ZGlmZiAtLWdpdCBhL0FuZHJvaWQuYnAgYi9BbmRyb2lkLmJwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ2MTA1MzAKLS0tIC9kZXYvbnVsbAorKysgYi9BbmRyb2lkLmJwCkBAIC0wLDAgKzEsODIgQEAKKy8vIENvcHlyaWdodCAyMDIyIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKy8vCisvLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKy8vIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKy8vIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorLy8KKy8vICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisvLworLy8gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorLy8gZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKy8vIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorLy8gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisKK3BhY2thZ2UgeworICAgIGRlZmF1bHRfYXBwbGljYWJsZV9saWNlbnNlczogWyJtb2JpbGVfZGF0YV9kb3dubG9hZGVyX2xpY2Vuc2UiXSwKK30KKworLy8gQWRkZWQgYXV0b21hdGljYWxseSBieSBhIGxhcmdlLXNjYWxlLWNoYW5nZQorLy8gU2VlOiBodHRwOi8vZ28vYW5kcm9pZC1saWNlbnNlLWZhcQorbGljZW5zZSB7CisgICAgbmFtZTogIm1vYmlsZV9kYXRhX2Rvd25sb2FkZXJfbGljZW5zZSIsCisgICAgdmlzaWJpbGl0eTogWyI6X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZV9raW5kczogWworICAgICAgICAiU1BEWC1saWNlbnNlLWlkZW50aWZpZXItQXBhY2hlLTIuMCIsCisgICAgXSwKKyAgICBsaWNlbnNlX3RleHQ6IFsKKyAgICAgICAgIkxJQ0VOU0UiLAorICAgIF0sCit9CisKK2phdmFfbGlicmFyeSB7CisgICAgbmFtZTogImFuZHJvaWRfY2hlY2tlcl9hbm5vdGF0aW9uX3N0dWJzIiwKKyAgICBzcmNzOiBbImFuZHJvaWQtYW5ub3RhdGlvbi1zdHVicy9zcmMvKiovKi5qYXZhIl0sCisgICAgaG9zdF9zdXBwb3J0ZWQ6IHRydWUsCisgICAgc2RrX3ZlcnNpb246ICJjb3JlX2N1cnJlbnQiLAorfQorCithbmRyb2lkX2xpYnJhcnkgeworICAgIG5hbWU6ICJtb2JpbGVfZGF0YV9kb3dubG9hZGVyX2xpYiIsCisgICAgc3JjczogWworICAgICAgICAiamF2YS8qKi8qLmphdmEiLAorICAgIF0sCisgICAgZXhjbHVkZV9zcmNzOiBbCisgICAgICAgICAgICAiamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvZGFnZ2VyLyoqLyouamF2YSIsCisgICAgICAgICAgICAiamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nLyoqLyouamF2YSIsCisgICAgICAgICAgICAiamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvT2Zmcm9hZDJGaWxlRG93bmxvYWRlci5qYXZhIiwKKyAgICBdLAorICAgIHN0YXRpY19saWJzOiBbCisgICAgICAgICJhbmRyb2lkeC5jb3JlX2NvcmUiLAorICAgICAgICAiYW5kcm9pZHguYW5ub3RhdGlvbl9hbm5vdGF0aW9uIiwKKyAgICAgICAgImVycm9yX3Byb25lX2Fubm90YXRpb25zIiwKKyAgICAgICAgImd1YXZhIiwKKyAgICAgICAgIm1vYmlsZS1kYXRhLWRvd25sb2FkLWphdmEtcHJvdG8tbGl0ZSIsCisgICAgICAgICJtb2JpbGUtZGF0YS1kb3dubG9hZC1wb3B1bGF0b3ItamF2YS1wcm90by1saXRlIiwKKyAgICAgICAgImRhZ2dlcjIiLAorICAgICAgICAianNyMzMwIiwKKyAgICAgICAgImNoZWNrZXItcXVhbCIsCisgICAgICAgICJhbmRyb2lkX2Rvd25sb2FkZXJfbGliIiwKKyAgICBdLAorICAgIGxpYnM6IFsKKyAgICAgICAgImF1dG9fdmFsdWVfYW5ub3RhdGlvbnMiLAorICAgICAgICAiZnJhbWV3b3JrLWFubm90YXRpb25zLWxpYiIsCisgICAgICAgICJ1bnN1cHBvcnRlZGFwcHVzYWdlIiwKKyAgICAgICAgImZyYW1ld29yay1hZHNlcnZpY2VzIiwKKyAgICAgICAgImFuZHJvaWRfY2hlY2tlcl9hbm5vdGF0aW9uX3N0dWJzIiwKKyAgICBdLAorICAgIHBsdWdpbnM6IFsKKyAgICAgICAgImF1dG9fdmFsdWVfcGx1Z2luIiwKKyAgICAgICAgImRhZ2dlcjItY29tcGlsZXIiLAorICAgICAgICAiYXV0b19hbm5vdGF0aW9uX3BsdWdpbiIsCisgICAgXSwKKyAgICBzZGtfdmVyc2lvbjogImN1cnJlbnQiLAorICAgIG1pbl9zZGtfdmVyc2lvbjogIjMwIiwKKyAgICBhcGV4X2F2YWlsYWJsZTogWworICAgICAgICAiLy9hcGV4X2F2YWlsYWJsZTpwbGF0Zm9ybSIsCisgICAgICAgICAiY29tLmFuZHJvaWQuYWRzZXJ2aWNlcyIsCisgICAgXSwKKyAgICB2aXNpYmlsaXR5OiBbCisgICAgICAgICIvL3BhY2thZ2VzL21vZHVsZXMvQWRTZXJ2aWNlczpfX3N1YnBhY2thZ2VzX18iLAorICAgIF0sCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvQW5kcm9pZE1hbmlmZXN0LnhtbCBiL0FuZHJvaWRNYW5pZmVzdC54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDBmMTNiOAotLS0gL2Rldi9udWxsCisrKyBiL0FuZHJvaWRNYW5pZmVzdC54bWwKQEAgLTAsMCArMSwyMiBAQAorPCEtLQorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy0tPgorPG1hbmlmZXN0CisgICAgeG1sbnM6YW5kcm9pZD0iaHR0cDovL3NjaGVtYXMuYW5kcm9pZC5jb20vYXBrL3Jlcy9hbmRyb2lkIgorICAgIHBhY2thZ2U9ImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkIj4KKyAgICA8dXNlcy1zZGsgYW5kcm9pZDptaW5TZGtWZXJzaW9uPSIxNiIgLz4KKzwvbWFuaWZlc3Q+CmRpZmYgLS1naXQgYS9DT05UUklCVVRJTkcubWQgYi9DT05UUklCVVRJTkcubWQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjI3MjQ4OQotLS0gL2Rldi9udWxsCisrKyBiL0NPTlRSSUJVVElORy5tZApAQCAtMCwwICsxLDI4IEBACisjIEhvdyB0byBDb250cmlidXRlCisKK1dlJ2QgbG92ZSB0byBhY2NlcHQgeW91ciBwYXRjaGVzIGFuZCBjb250cmlidXRpb25zIHRvIHRoaXMgcHJvamVjdC4gVGhlcmUgYXJlCitqdXN0IGEgZmV3IHNtYWxsIGd1aWRlbGluZXMgeW91IG5lZWQgdG8gZm9sbG93LgorCisjIyBDb250cmlidXRvciBMaWNlbnNlIEFncmVlbWVudAorCitDb250cmlidXRpb25zIHRvIHRoaXMgcHJvamVjdCBtdXN0IGJlIGFjY29tcGFuaWVkIGJ5IGEgQ29udHJpYnV0b3IgTGljZW5zZQorQWdyZWVtZW50LiBZb3UgKG9yIHlvdXIgZW1wbG95ZXIpIHJldGFpbiB0aGUgY29weXJpZ2h0IHRvIHlvdXIgY29udHJpYnV0aW9uOwordGhpcyBzaW1wbHkgZ2l2ZXMgdXMgcGVybWlzc2lvbiB0byB1c2UgYW5kIHJlZGlzdHJpYnV0ZSB5b3VyIGNvbnRyaWJ1dGlvbnMgYXMKK3BhcnQgb2YgdGhlIHByb2plY3QuIEhlYWQgb3ZlciB0byA8aHR0cHM6Ly9jbGEuZGV2ZWxvcGVycy5nb29nbGUuY29tLz4gdG8gc2VlCit5b3VyIGN1cnJlbnQgYWdyZWVtZW50cyBvbiBmaWxlIG9yIHRvIHNpZ24gYSBuZXcgb25lLgorCitZb3UgZ2VuZXJhbGx5IG9ubHkgbmVlZCB0byBzdWJtaXQgYSBDTEEgb25jZSwgc28gaWYgeW91J3ZlIGFscmVhZHkgc3VibWl0dGVkIG9uZQorKGV2ZW4gaWYgaXQgd2FzIGZvciBhIGRpZmZlcmVudCBwcm9qZWN0KSwgeW91IHByb2JhYmx5IGRvbid0IG5lZWQgdG8gZG8gaXQKK2FnYWluLgorCisjIyBDb2RlIFJldmlld3MKKworQWxsIHN1Ym1pc3Npb25zLCBpbmNsdWRpbmcgc3VibWlzc2lvbnMgYnkgcHJvamVjdCBtZW1iZXJzLCByZXF1aXJlIHJldmlldy4gV2UKK3VzZSBHaXRIdWIgcHVsbCByZXF1ZXN0cyBmb3IgdGhpcyBwdXJwb3NlLiBDb25zdWx0CitbR2l0SHViIEhlbHBdKGh0dHBzOi8vaGVscC5naXRodWIuY29tL2FydGljbGVzL2Fib3V0LXB1bGwtcmVxdWVzdHMvKSBmb3IgbW9yZQoraW5mb3JtYXRpb24gb24gdXNpbmcgcHVsbCByZXF1ZXN0cy4KKworIyMgQ29tbXVuaXR5IEd1aWRlbGluZXMKKworVGhpcyBwcm9qZWN0IGZvbGxvd3MgW0dvb2dsZSdzIE9wZW4gU291cmNlIENvbW11bml0eQorR3VpZGVsaW5lc10oaHR0cHM6Ly9vcGVuc291cmNlLmdvb2dsZS9jb25kdWN0LykuCmRpZmYgLS1naXQgYS9MSUNFTlNFIGIvTElDRU5TRQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTRhM2VhCi0tLSAvZGV2L251bGwKKysrIGIvTElDRU5TRQpAQCAtMCwwICsxLDIwMiBAQAorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcGFjaGUgTGljZW5zZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiAyLjAsIEphbnVhcnkgMjAwNAorICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLworCisgICBURVJNUyBBTkQgQ09ORElUSU9OUyBGT1IgVVNFLCBSRVBST0RVQ1RJT04sIEFORCBESVNUUklCVVRJT04KKworICAgMS4gRGVmaW5pdGlvbnMuCisKKyAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCisgICAgICBhbmQgZGlzdHJpYnV0aW9uIGFzIGRlZmluZWQgYnkgU2VjdGlvbnMgMSB0aHJvdWdoIDkgb2YgdGhpcyBkb2N1bWVudC4KKworICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIgdGhhdCBpcyBncmFudGluZyB0aGUgTGljZW5zZS4KKworICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAorICAgICAgb3RoZXIgZW50aXRpZXMgdGhhdCBjb250cm9sLCBhcmUgY29udHJvbGxlZCBieSwgb3IgYXJlIHVuZGVyIGNvbW1vbgorICAgICAgY29udHJvbCB3aXRoIHRoYXQgZW50aXR5LiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwKKyAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQorICAgICAgZGlyZWN0aW9uIG9yIG1hbmFnZW1lbnQgb2Ygc3VjaCBlbnRpdHksIHdoZXRoZXIgYnkgY29udHJhY3Qgb3IKKyAgICAgIG90aGVyd2lzZSwgb3IgKGlpKSBvd25lcnNoaXAgb2YgZmlmdHkgcGVyY2VudCAoNTAlKSBvciBtb3JlIG9mIHRoZQorICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KKworICAgICAgIllvdSIgKG9yICJZb3VyIikgc2hhbGwgbWVhbiBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQorICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KKworICAgICAgIlNvdXJjZSIgZm9ybSBzaGFsbCBtZWFuIHRoZSBwcmVmZXJyZWQgZm9ybSBmb3IgbWFraW5nIG1vZGlmaWNhdGlvbnMsCisgICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCisgICAgICBzb3VyY2UsIGFuZCBjb25maWd1cmF0aW9uIGZpbGVzLgorCisgICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAorICAgICAgdHJhbnNmb3JtYXRpb24gb3IgdHJhbnNsYXRpb24gb2YgYSBTb3VyY2UgZm9ybSwgaW5jbHVkaW5nIGJ1dAorICAgICAgbm90IGxpbWl0ZWQgdG8gY29tcGlsZWQgb2JqZWN0IGNvZGUsIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uLAorICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgorCisgICAgICAiV29yayIgc2hhbGwgbWVhbiB0aGUgd29yayBvZiBhdXRob3JzaGlwLCB3aGV0aGVyIGluIFNvdXJjZSBvcgorICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQorICAgICAgY29weXJpZ2h0IG5vdGljZSB0aGF0IGlzIGluY2x1ZGVkIGluIG9yIGF0dGFjaGVkIHRvIHRoZSB3b3JrCisgICAgICAoYW4gZXhhbXBsZSBpcyBwcm92aWRlZCBpbiB0aGUgQXBwZW5kaXggYmVsb3cpLgorCisgICAgICAiRGVyaXZhdGl2ZSBXb3JrcyIgc2hhbGwgbWVhbiBhbnkgd29yaywgd2hldGhlciBpbiBTb3VyY2Ugb3IgT2JqZWN0CisgICAgICBmb3JtLCB0aGF0IGlzIGJhc2VkIG9uIChvciBkZXJpdmVkIGZyb20pIHRoZSBXb3JrIGFuZCBmb3Igd2hpY2ggdGhlCisgICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCisgICAgICByZXByZXNlbnQsIGFzIGEgd2hvbGUsIGFuIG9yaWdpbmFsIHdvcmsgb2YgYXV0aG9yc2hpcC4gRm9yIHRoZSBwdXJwb3NlcworICAgICAgb2YgdGhpcyBMaWNlbnNlLCBEZXJpdmF0aXZlIFdvcmtzIHNoYWxsIG5vdCBpbmNsdWRlIHdvcmtzIHRoYXQgcmVtYWluCisgICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCisgICAgICB0aGUgV29yayBhbmQgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLgorCisgICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZworICAgICAgdGhlIG9yaWdpbmFsIHZlcnNpb24gb2YgdGhlIFdvcmsgYW5kIGFueSBtb2RpZmljYXRpb25zIG9yIGFkZGl0aW9ucworICAgICAgdG8gdGhhdCBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiwgdGhhdCBpcyBpbnRlbnRpb25hbGx5CisgICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCisgICAgICBvciBieSBhbiBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eSBhdXRob3JpemVkIHRvIHN1Ym1pdCBvbiBiZWhhbGYgb2YKKyAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIuIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBkZWZpbml0aW9uLCAic3VibWl0dGVkIgorICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAorICAgICAgdG8gdGhlIExpY2Vuc29yIG9yIGl0cyByZXByZXNlbnRhdGl2ZXMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8KKyAgICAgIGNvbW11bmljYXRpb24gb24gZWxlY3Ryb25pYyBtYWlsaW5nIGxpc3RzLCBzb3VyY2UgY29kZSBjb250cm9sIHN5c3RlbXMsCisgICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQorICAgICAgTGljZW5zb3IgZm9yIHRoZSBwdXJwb3NlIG9mIGRpc2N1c3NpbmcgYW5kIGltcHJvdmluZyB0aGUgV29yaywgYnV0CisgICAgICBleGNsdWRpbmcgY29tbXVuaWNhdGlvbiB0aGF0IGlzIGNvbnNwaWN1b3VzbHkgbWFya2VkIG9yIG90aGVyd2lzZQorICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCisKKyAgICAgICJDb250cmlidXRvciIgc2hhbGwgbWVhbiBMaWNlbnNvciBhbmQgYW55IGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5CisgICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKKyAgICAgIHN1YnNlcXVlbnRseSBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrLgorCisgICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBhIHBlcnBldHVhbCwKKyAgICAgIHdvcmxkd2lkZSwgbm9uLWV4Y2x1c2l2ZSwgbm8tY2hhcmdlLCByb3lhbHR5LWZyZWUsIGlycmV2b2NhYmxlCisgICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKKyAgICAgIHB1YmxpY2x5IGRpc3BsYXksIHB1YmxpY2x5IHBlcmZvcm0sIHN1YmxpY2Vuc2UsIGFuZCBkaXN0cmlidXRlIHRoZQorICAgICAgV29yayBhbmQgc3VjaCBEZXJpdmF0aXZlIFdvcmtzIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybS4KKworICAgMy4gR3JhbnQgb2YgUGF0ZW50IExpY2Vuc2UuIFN1YmplY3QgdG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCisgICAgICB0aGlzIExpY2Vuc2UsIGVhY2ggQ29udHJpYnV0b3IgaGVyZWJ5IGdyYW50cyB0byBZb3UgYSBwZXJwZXR1YWwsCisgICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQorICAgICAgKGV4Y2VwdCBhcyBzdGF0ZWQgaW4gdGhpcyBzZWN0aW9uKSBwYXRlbnQgbGljZW5zZSB0byBtYWtlLCBoYXZlIG1hZGUsCisgICAgICB1c2UsIG9mZmVyIHRvIHNlbGwsIHNlbGwsIGltcG9ydCwgYW5kIG90aGVyd2lzZSB0cmFuc2ZlciB0aGUgV29yaywKKyAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCisgICAgICBieSBzdWNoIENvbnRyaWJ1dG9yIHRoYXQgYXJlIG5lY2Vzc2FyaWx5IGluZnJpbmdlZCBieSB0aGVpcgorICAgICAgQ29udHJpYnV0aW9uKHMpIGFsb25lIG9yIGJ5IGNvbWJpbmF0aW9uIG9mIHRoZWlyIENvbnRyaWJ1dGlvbihzKQorICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKKyAgICAgIGluc3RpdHV0ZSBwYXRlbnQgbGl0aWdhdGlvbiBhZ2FpbnN0IGFueSBlbnRpdHkgKGluY2x1ZGluZyBhCisgICAgICBjcm9zcy1jbGFpbSBvciBjb3VudGVyY2xhaW0gaW4gYSBsYXdzdWl0KSBhbGxlZ2luZyB0aGF0IHRoZSBXb3JrCisgICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAorICAgICAgb3IgY29udHJpYnV0b3J5IHBhdGVudCBpbmZyaW5nZW1lbnQsIHRoZW4gYW55IHBhdGVudCBsaWNlbnNlcworICAgICAgZ3JhbnRlZCB0byBZb3UgdW5kZXIgdGhpcyBMaWNlbnNlIGZvciB0aGF0IFdvcmsgc2hhbGwgdGVybWluYXRlCisgICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCisKKyAgIDQuIFJlZGlzdHJpYnV0aW9uLiBZb3UgbWF5IHJlcHJvZHVjZSBhbmQgZGlzdHJpYnV0ZSBjb3BpZXMgb2YgdGhlCisgICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKKyAgICAgIG1vZGlmaWNhdGlvbnMsIGFuZCBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0sIHByb3ZpZGVkIHRoYXQgWW91CisgICAgICBtZWV0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKworICAgICAgKGEpIFlvdSBtdXN0IGdpdmUgYW55IG90aGVyIHJlY2lwaWVudHMgb2YgdGhlIFdvcmsgb3IKKyAgICAgICAgICBEZXJpdmF0aXZlIFdvcmtzIGEgY29weSBvZiB0aGlzIExpY2Vuc2U7IGFuZAorCisgICAgICAoYikgWW91IG11c3QgY2F1c2UgYW55IG1vZGlmaWVkIGZpbGVzIHRvIGNhcnJ5IHByb21pbmVudCBub3RpY2VzCisgICAgICAgICAgc3RhdGluZyB0aGF0IFlvdSBjaGFuZ2VkIHRoZSBmaWxlczsgYW5kCisKKyAgICAgIChjKSBZb3UgbXVzdCByZXRhaW4sIGluIHRoZSBTb3VyY2UgZm9ybSBvZiBhbnkgRGVyaXZhdGl2ZSBXb3JrcworICAgICAgICAgIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsbCBjb3B5cmlnaHQsIHBhdGVudCwgdHJhZGVtYXJrLCBhbmQKKyAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAorICAgICAgICAgIGV4Y2x1ZGluZyB0aG9zZSBub3RpY2VzIHRoYXQgZG8gbm90IHBlcnRhaW4gdG8gYW55IHBhcnQgb2YKKyAgICAgICAgICB0aGUgRGVyaXZhdGl2ZSBXb3JrczsgYW5kCisKKyAgICAgIChkKSBJZiB0aGUgV29yayBpbmNsdWRlcyBhICJOT1RJQ0UiIHRleHQgZmlsZSBhcyBwYXJ0IG9mIGl0cworICAgICAgICAgIGRpc3RyaWJ1dGlvbiwgdGhlbiBhbnkgRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlIG11c3QKKyAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKKyAgICAgICAgICB3aXRoaW4gc3VjaCBOT1RJQ0UgZmlsZSwgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QKKyAgICAgICAgICBwZXJ0YWluIHRvIGFueSBwYXJ0IG9mIHRoZSBEZXJpdmF0aXZlIFdvcmtzLCBpbiBhdCBsZWFzdCBvbmUKKyAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAorICAgICAgICAgIGFzIHBhcnQgb2YgdGhlIERlcml2YXRpdmUgV29ya3M7IHdpdGhpbiB0aGUgU291cmNlIGZvcm0gb3IKKyAgICAgICAgICBkb2N1bWVudGF0aW9uLCBpZiBwcm92aWRlZCBhbG9uZyB3aXRoIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyBvciwKKyAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCisgICAgICAgICAgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBub3RpY2VzIG5vcm1hbGx5IGFwcGVhci4gVGhlIGNvbnRlbnRzCisgICAgICAgICAgb2YgdGhlIE5PVElDRSBmaWxlIGFyZSBmb3IgaW5mb3JtYXRpb25hbCBwdXJwb3NlcyBvbmx5IGFuZAorICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCisgICAgICAgICAgbm90aWNlcyB3aXRoaW4gRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbG9uZ3NpZGUKKyAgICAgICAgICBvciBhcyBhbiBhZGRlbmR1bSB0byB0aGUgTk9USUNFIHRleHQgZnJvbSB0aGUgV29yaywgcHJvdmlkZWQKKyAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKKyAgICAgICAgICBhcyBtb2RpZnlpbmcgdGhlIExpY2Vuc2UuCisKKyAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAorICAgICAgbWF5IHByb3ZpZGUgYWRkaXRpb25hbCBvciBkaWZmZXJlbnQgbGljZW5zZSB0ZXJtcyBhbmQgY29uZGl0aW9ucworICAgICAgZm9yIHVzZSwgcmVwcm9kdWN0aW9uLCBvciBkaXN0cmlidXRpb24gb2YgWW91ciBtb2RpZmljYXRpb25zLCBvcgorICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCisgICAgICByZXByb2R1Y3Rpb24sIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlIFdvcmsgb3RoZXJ3aXNlIGNvbXBsaWVzIHdpdGgKKyAgICAgIHRoZSBjb25kaXRpb25zIHN0YXRlZCBpbiB0aGlzIExpY2Vuc2UuCisKKyAgIDUuIFN1Ym1pc3Npb24gb2YgQ29udHJpYnV0aW9ucy4gVW5sZXNzIFlvdSBleHBsaWNpdGx5IHN0YXRlIG90aGVyd2lzZSwKKyAgICAgIGFueSBDb250cmlidXRpb24gaW50ZW50aW9uYWxseSBzdWJtaXR0ZWQgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yaworICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKKyAgICAgIHRoaXMgTGljZW5zZSwgd2l0aG91dCBhbnkgYWRkaXRpb25hbCB0ZXJtcyBvciBjb25kaXRpb25zLgorICAgICAgTm90d2l0aHN0YW5kaW5nIHRoZSBhYm92ZSwgbm90aGluZyBoZXJlaW4gc2hhbGwgc3VwZXJzZWRlIG9yIG1vZGlmeQorICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKKyAgICAgIHdpdGggTGljZW5zb3IgcmVnYXJkaW5nIHN1Y2ggQ29udHJpYnV0aW9ucy4KKworICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQorICAgICAgbmFtZXMsIHRyYWRlbWFya3MsIHNlcnZpY2UgbWFya3MsIG9yIHByb2R1Y3QgbmFtZXMgb2YgdGhlIExpY2Vuc29yLAorICAgICAgZXhjZXB0IGFzIHJlcXVpcmVkIGZvciByZWFzb25hYmxlIGFuZCBjdXN0b21hcnkgdXNlIGluIGRlc2NyaWJpbmcgdGhlCisgICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KKworICAgNy4gRGlzY2xhaW1lciBvZiBXYXJyYW50eS4gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yCisgICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCisgICAgICBDb250cmlidXRvciBwcm92aWRlcyBpdHMgQ29udHJpYnV0aW9ucykgb24gYW4gIkFTIElTIiBCQVNJUywKKyAgICAgIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvcgorICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKKyAgICAgIG9mIFRJVExFLCBOT04tSU5GUklOR0VNRU5ULCBNRVJDSEFOVEFCSUxJVFksIG9yIEZJVE5FU1MgRk9SIEEKKyAgICAgIFBBUlRJQ1VMQVIgUFVSUE9TRS4gWW91IGFyZSBzb2xlbHkgcmVzcG9uc2libGUgZm9yIGRldGVybWluaW5nIHRoZQorICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CisgICAgICByaXNrcyBhc3NvY2lhdGVkIHdpdGggWW91ciBleGVyY2lzZSBvZiBwZXJtaXNzaW9ucyB1bmRlciB0aGlzIExpY2Vuc2UuCisKKyAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAorICAgICAgd2hldGhlciBpbiB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGNvbnRyYWN0LCBvciBvdGhlcndpc2UsCisgICAgICB1bmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgKHN1Y2ggYXMgZGVsaWJlcmF0ZSBhbmQgZ3Jvc3NseQorICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKKyAgICAgIGxpYWJsZSB0byBZb3UgZm9yIGRhbWFnZXMsIGluY2x1ZGluZyBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgc3BlY2lhbCwKKyAgICAgIGluY2lkZW50YWwsIG9yIGNvbnNlcXVlbnRpYWwgZGFtYWdlcyBvZiBhbnkgY2hhcmFjdGVyIGFyaXNpbmcgYXMgYQorICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQorICAgICAgV29yayAoaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBkYW1hZ2VzIGZvciBsb3NzIG9mIGdvb2R3aWxsLAorICAgICAgd29yayBzdG9wcGFnZSwgY29tcHV0ZXIgZmFpbHVyZSBvciBtYWxmdW5jdGlvbiwgb3IgYW55IGFuZCBhbGwKKyAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKKyAgICAgIGhhcyBiZWVuIGFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlcy4KKworICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZworICAgICAgdGhlIFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9mLCBZb3UgbWF5IGNob29zZSB0byBvZmZlciwKKyAgICAgIGFuZCBjaGFyZ2UgYSBmZWUgZm9yLCBhY2NlcHRhbmNlIG9mIHN1cHBvcnQsIHdhcnJhbnR5LCBpbmRlbW5pdHksCisgICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcworICAgICAgTGljZW5zZS4gSG93ZXZlciwgaW4gYWNjZXB0aW5nIHN1Y2ggb2JsaWdhdGlvbnMsIFlvdSBtYXkgYWN0IG9ubHkKKyAgICAgIG9uIFlvdXIgb3duIGJlaGFsZiBhbmQgb24gWW91ciBzb2xlIHJlc3BvbnNpYmlsaXR5LCBub3Qgb24gYmVoYWxmCisgICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCisgICAgICBkZWZlbmQsIGFuZCBob2xkIGVhY2ggQ29udHJpYnV0b3IgaGFybWxlc3MgZm9yIGFueSBsaWFiaWxpdHkKKyAgICAgIGluY3VycmVkIGJ5LCBvciBjbGFpbXMgYXNzZXJ0ZWQgYWdhaW5zdCwgc3VjaCBDb250cmlidXRvciBieSByZWFzb24KKyAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgorCisgICBFTkQgT0YgVEVSTVMgQU5EIENPTkRJVElPTlMKKworICAgQVBQRU5ESVg6IEhvdyB0byBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLgorCisgICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZworICAgICAgYm9pbGVycGxhdGUgbm90aWNlLCB3aXRoIHRoZSBmaWVsZHMgZW5jbG9zZWQgYnkgYnJhY2tldHMgIltdIgorICAgICAgcmVwbGFjZWQgd2l0aCB5b3VyIG93biBpZGVudGlmeWluZyBpbmZvcm1hdGlvbi4gKERvbid0IGluY2x1ZGUKKyAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCisgICAgICBjb21tZW50IHN5bnRheCBmb3IgdGhlIGZpbGUgZm9ybWF0LiBXZSBhbHNvIHJlY29tbWVuZCB0aGF0IGEKKyAgICAgIGZpbGUgb3IgY2xhc3MgbmFtZSBhbmQgZGVzY3JpcHRpb24gb2YgcHVycG9zZSBiZSBpbmNsdWRlZCBvbiB0aGUKKyAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgorICAgICAgaWRlbnRpZmljYXRpb24gd2l0aGluIHRoaXJkLXBhcnR5IGFyY2hpdmVzLgorCisgICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KKworICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKworICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorCisgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9NRVRBREFUQSBiL01FVEFEQVRBCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1ODgwMTgKLS0tIC9kZXYvbnVsbAorKysgYi9NRVRBREFUQQpAQCAtMCwwICsxLDEzIEBACituYW1lOiAiTW9iaWxlIERhdGEgRG93bmxvYWQiCitkZXNjcmlwdGlvbjoKKyAgICAiQW5kcm9pZCBsaWJyYXJ5IGZvciBkb3dubG9hZGluZyBhbmQgbWFuYWdpbmcgZmlsZXMgb24gZGV2aWNlLiIKKwordGhpcmRfcGFydHkgeworICB1cmwgeworICAgIHR5cGU6IEdJVAorICAgIHZhbHVlOiAiaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9tb2JpbGUtZGF0YS1kb3dubG9hZCIKKyAgfQorICB2ZXJzaW9uOiAiMTQwMjFhYjQ4Yzc5NWQ0ZGFkOWI4M2E3ODEwMmZhYzVkYjJiZjg1ZSIKKyAgbGFzdF91cGdyYWRlX2RhdGUgeyB5ZWFyOiAyMDIyIG1vbnRoOiA2IGRheTogMTUgfQorICBsaWNlbnNlX3R5cGU6IE5PVElDRQorfQpkaWZmIC0tZ2l0IGEvTU9EVUxFX0xJQ0VOU0VfQVBBQ0hFMiBiL01PRFVMRV9MSUNFTlNFX0FQQUNIRTIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY5ZGUyOQotLS0gL2Rldi9udWxsCisrKyBiL01PRFVMRV9MSUNFTlNFX0FQQUNIRTIKZGlmZiAtLWdpdCBhL09XTkVSUyBiL09XTkVSUwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNzBmZjMyCi0tLSAvZGV2L251bGwKKysrIGIvT1dORVJTCkBAIC0wLDAgKzEsMyBAQAorbnBhdHRhbkBnb29nbGUuY29tCitiaW5obmd1eWVuQGdvb2dsZS5jb20KK2hhb2xpdXVAZ29vZ2xlLmNvbQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC1hbm5vdGF0aW9uLXN0dWJzL2dlbl9hbm5vdGF0aW9ucy5zaCBiL2FuZHJvaWQtYW5ub3RhdGlvbi1zdHVicy9nZW5fYW5ub3RhdGlvbnMuc2gKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjM0ZGE5NwotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQtYW5ub3RhdGlvbi1zdHVicy9nZW5fYW5ub3RhdGlvbnMuc2gKQEAgLTAsMCArMSwxNiBAQAorIyEvYmluL2Jhc2gKKworQU5OT1RBVElPTlM9KAorICAgIG9yZy5jaGVja2VyZnJhbWV3b3JrLmNoZWNrZXIubnVsbG5lc3MuY29tcGF0cXVhbC5OdWxsYWJsZURlY2wKKyAgICBvcmcuY2hlY2tlcmZyYW1ld29yay5jaGVja2VyLm51bGxuZXNzLmNvbXBhdHF1YWwuTnVsbGFibGVUeXBlCispCisKK2ZvciBhIGluICR7QU5OT1RBVElPTlNbQF19OyBkbworICAgIHBhY2thZ2U9JHthJS4qfQorICAgIGNsYXNzPSR7YSMjKi59CisgICAgZGlyPSQoZGlybmFtZSAkMCkvc3JjLyR7cGFja2FnZS8vLi8vfQorICAgIGZpbGU9JHtjbGFzc30uamF2YQorCisgICAgbWtkaXIgLXAgJHtkaXJ9CisgICAgc2VkIC1lInMvX19QQUNLQUdFX18vJHtwYWNrYWdlfS8iIC1lInMvX19DTEFTU19fLyR7Y2xhc3N9LyIgdG1wbC5qYXZhID4gJHtkaXJ9LyR7ZmlsZX0KK2RvbmUKZGlmZiAtLWdpdCBhL2FuZHJvaWQtYW5ub3RhdGlvbi1zdHVicy9zcmMvb3JnL2NoZWNrZXJmcmFtZXdvcmsvY2hlY2tlci9udWxsbmVzcy9jb21wYXRxdWFsL051bGxhYmxlRGVjbC5qYXZhIGIvYW5kcm9pZC1hbm5vdGF0aW9uLXN0dWJzL3NyYy9vcmcvY2hlY2tlcmZyYW1ld29yay9jaGVja2VyL251bGxuZXNzL2NvbXBhdHF1YWwvTnVsbGFibGVEZWNsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWU3YzM0NAotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQtYW5ub3RhdGlvbi1zdHVicy9zcmMvb3JnL2NoZWNrZXJmcmFtZXdvcmsvY2hlY2tlci9udWxsbmVzcy9jb21wYXRxdWFsL051bGxhYmxlRGVjbC5qYXZhCkBAIC0wLDAgKzEsMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMjIgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKworcGFja2FnZSBvcmcuY2hlY2tlcmZyYW1ld29yay5jaGVja2VyLm51bGxuZXNzLmNvbXBhdHF1YWw7CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlRhcmdldDsKKworQFRhcmdldCh7CisgICAgICAgIEVsZW1lbnRUeXBlLkFOTk9UQVRJT05fVFlQRSwKKyAgICAgICAgRWxlbWVudFR5cGUuQ09OU1RSVUNUT1IsCisgICAgICAgIEVsZW1lbnRUeXBlLkZJRUxELAorICAgICAgICBFbGVtZW50VHlwZS5MT0NBTF9WQVJJQUJMRSwKKyAgICAgICAgRWxlbWVudFR5cGUuTUVUSE9ELAorICAgICAgICBFbGVtZW50VHlwZS5QQUNLQUdFLAorICAgICAgICBFbGVtZW50VHlwZS5QQVJBTUVURVIsCisgICAgICAgIEVsZW1lbnRUeXBlLlRZUEUsCisgICAgICAgIEVsZW1lbnRUeXBlLlRZUEVfUEFSQU1FVEVSLAorICAgICAgICBFbGVtZW50VHlwZS5UWVBFX1VTRX0pCitAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5TT1VSQ0UpCitwdWJsaWMgQGludGVyZmFjZSBOdWxsYWJsZURlY2wge30KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9hbmRyb2lkLWFubm90YXRpb24tc3R1YnMvc3JjL29yZy9jaGVja2VyZnJhbWV3b3JrL2NoZWNrZXIvbnVsbG5lc3MvY29tcGF0cXVhbC9OdWxsYWJsZVR5cGUuamF2YSBiL2FuZHJvaWQtYW5ub3RhdGlvbi1zdHVicy9zcmMvb3JnL2NoZWNrZXJmcmFtZXdvcmsvY2hlY2tlci9udWxsbmVzcy9jb21wYXRxdWFsL051bGxhYmxlVHlwZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyMGE0NGYKLS0tIC9kZXYvbnVsbAorKysgYi9hbmRyb2lkLWFubm90YXRpb24tc3R1YnMvc3JjL29yZy9jaGVja2VyZnJhbWV3b3JrL2NoZWNrZXIvbnVsbG5lc3MvY29tcGF0cXVhbC9OdWxsYWJsZVR5cGUuamF2YQpAQCAtMCwwICsxLDM5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDIyIFRoZSBBbmRyb2lkIE9wZW4gU291cmNlIFByb2plY3QKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCisKK3BhY2thZ2Ugb3JnLmNoZWNrZXJmcmFtZXdvcmsuY2hlY2tlci5udWxsbmVzcy5jb21wYXRxdWFsOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKKy8qIFRoaXMgaXMgYW4gYW5ub3RhdGlvbiBzdHViIHRvIGF2b2lkIGRlcGVuZGVuY2llcyBvbiBhbm5vdGF0aW9ucyB0aGF0IGFyZW4ndAorICogaW4gdGhlIEFuZHJvaWQgcGxhdGZvcm0gc291cmNlIHRyZWUuICovCisKK0BUYXJnZXQoeworICAgICAgICBFbGVtZW50VHlwZS5BTk5PVEFUSU9OX1RZUEUsCisgICAgICAgIEVsZW1lbnRUeXBlLkNPTlNUUlVDVE9SLAorICAgICAgICBFbGVtZW50VHlwZS5GSUVMRCwKKyAgICAgICAgRWxlbWVudFR5cGUuTE9DQUxfVkFSSUFCTEUsCisgICAgICAgIEVsZW1lbnRUeXBlLk1FVEhPRCwKKyAgICAgICAgRWxlbWVudFR5cGUuUEFDS0FHRSwKKyAgICAgICAgRWxlbWVudFR5cGUuUEFSQU1FVEVSLAorICAgICAgICBFbGVtZW50VHlwZS5UWVBFLAorICAgICAgICBFbGVtZW50VHlwZS5UWVBFX1BBUkFNRVRFUiwKKyAgICAgICAgRWxlbWVudFR5cGUuVFlQRV9VU0V9KQorQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuU09VUkNFKQorcHVibGljIEBpbnRlcmZhY2UgTnVsbGFibGVUeXBlIHt9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvYW5kcm9pZC1hbm5vdGF0aW9uLXN0dWJzL3RtcGwuamF2YSBiL2FuZHJvaWQtYW5ub3RhdGlvbi1zdHVicy90bXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzVmYjJlYQotLS0gL2Rldi9udWxsCisrKyBiL2FuZHJvaWQtYW5ub3RhdGlvbi1zdHVicy90bXBsLmphdmEKQEAgLTAsMCArMSwzOSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAyMiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworCitwYWNrYWdlIF9fUEFDS0FHRV9fOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uOworaW1wb3J0IGphdmEubGFuZy5hbm5vdGF0aW9uLlJldGVudGlvblBvbGljeTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CisKKy8qIFRoaXMgaXMgYW4gYW5ub3RhdGlvbiBzdHViIHRvIGF2b2lkIGRlcGVuZGVuY2llcyBvbiBhbm5vdGF0aW9ucyB0aGF0IGFyZW4ndAorICogaW4gdGhlIEFuZHJvaWQgcGxhdGZvcm0gc291cmNlIHRyZWUuICovCisKK0BUYXJnZXQoeworICAgICAgICBFbGVtZW50VHlwZS5BTk5PVEFUSU9OX1RZUEUsCisgICAgICAgIEVsZW1lbnRUeXBlLkNPTlNUUlVDVE9SLAorICAgICAgICBFbGVtZW50VHlwZS5GSUVMRCwKKyAgICAgICAgRWxlbWVudFR5cGUuTE9DQUxfVkFSSUFCTEUsCisgICAgICAgIEVsZW1lbnRUeXBlLk1FVEhPRCwKKyAgICAgICAgRWxlbWVudFR5cGUuUEFDS0FHRSwKKyAgICAgICAgRWxlbWVudFR5cGUuUEFSQU1FVEVSLAorICAgICAgICBFbGVtZW50VHlwZS5UWVBFLAorICAgICAgICBFbGVtZW50VHlwZS5UWVBFX1BBUkFNRVRFUiwKKyAgICAgICAgRWxlbWVudFR5cGUuVFlQRV9VU0V9KQorQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuU09VUkNFKQorcHVibGljIEBpbnRlcmZhY2UgX19DTEFTU19fIHt9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9BY2NvdW50U291cmNlLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0FjY291bnRTb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZGE2MDY1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9BY2NvdW50U291cmNlLmphdmEKQEAgLTAsMCArMSwyNyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBhbmRyb2lkLmFjY291bnRzLkFjY291bnQ7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworCisvKioKKyAqIEltcGxlbWVudGF0aW9ucyBhcmUgcmVzcG9uc2libGUgZm9yIGxpc3RpbmcgYWxsIGFjY291bnRzIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLiBSZXF1aXJlZCBmb3IKKyAqIHdpcGVvdXQgY29tcGxpYW5jZS4KKyAqLworcHVibGljIGludGVyZmFjZSBBY2NvdW50U291cmNlIHsKKyAgSW1tdXRhYmxlTGlzdDxBY2NvdW50PiBnZXRBbGxBY2NvdW50cygpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9BZGRGaWxlR3JvdXBSZXF1ZXN0LmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0FkZEZpbGVHcm91cFJlcXVlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NGNkMWYwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9BZGRGaWxlR3JvdXBSZXF1ZXN0LmphdmEKQEAgLTAsMCArMSw2NiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBhbmRyb2lkLmFjY291bnRzLkFjY291bnQ7CitpbXBvcnQgY29tLmdvb2dsZS5hdXRvLnZhbHVlLkF1dG9WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLmNvbmN1cnJlbnQuSW1tdXRhYmxlOworCisvKiogUmVxdWVzdCB0byBhZGQgZmlsZSBncm91cCBpbiBNREQuICovCitAQXV0b1ZhbHVlCitASW1tdXRhYmxlCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQWRkRmlsZUdyb3VwUmVxdWVzdCB7CisgIEFkZEZpbGVHcm91cFJlcXVlc3QoKSB7fQorCisgIHB1YmxpYyBhYnN0cmFjdCBEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXAoKTsKKworICBwdWJsaWMgYWJzdHJhY3QgT3B0aW9uYWw8QWNjb3VudD4gYWNjb3VudE9wdGlvbmFsKCk7CisKKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPFN0cmluZz4gdmFyaWFudElkT3B0aW9uYWwoKTsKKworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEF1dG9WYWx1ZV9BZGRGaWxlR3JvdXBSZXF1ZXN0LkJ1aWxkZXIoKTsKKyAgfQorCisgIC8qKiBCdWlsZGVyIGZvciB7QGxpbmsgQWRkRmlsZUdyb3VwUmVxdWVzdH0uICovCisgIEBBdXRvVmFsdWUuQnVpbGRlcgorICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEJ1aWxkZXIgeworICAgIEJ1aWxkZXIoKSB7fQorCisgICAgLyoqIFNldHMgdGhlIGRhdGEgZmlsZSBncm91cCwgd2hpY2ggaXMgcmVxdWlyZWQuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0RGF0YUZpbGVHcm91cChEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXApOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYWNjb3VudCBhc3NvY2lhdGVkIHdpdGggdGhlIGdyb3VwLCB3aGljaCBpcyBvcHRpb25hbC4KKyAgICAgKgorICAgICAqIDxwPk5PVEU6IFdoZW4gdGhpcyBvcHRpb24gaXMgc2V0LCBpdCB3aWxsIGFsc28gYmUgcmVxdWlyZWQgd2hlbiByZXRyaWV2aW5nIGZpbGUgZ3JvdXBzIGluCisgICAgICoge0BsaW5rIEdldEZpbGVHcm91cFJlcXVlc3R9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldEFjY291bnRPcHRpb25hbChPcHRpb25hbDxBY2NvdW50PiBhY2NvdW50T3B0aW9uYWwpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFyaWFudCBpZCBhc3NvY2lhdGVkIHdpdGggdGhlIGdyb3VwLCB3aGljaCBpcyBvcHRpb25hbC4KKyAgICAgKgorICAgICAqIDxwPk5PVEU6IFdoZW4gdGhpcyBvcHRpb24gaXMgc2V0LCBpdCB3aWxsIGFsc28gYmUgcmVxdWlyZWQgd2hlbiByZXRyaWV2aW5nIGZpbGUgZ3JvdXBzIGluCisgICAgICoge0BsaW5rIEdldEZpbGVHcm91cFJlcXVlc3R9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldFZhcmlhbnRJZE9wdGlvbmFsKE9wdGlvbmFsPFN0cmluZz4gdmFyaWFudElkT3B0aW9uYWwpOworCisgICAgcHVibGljIGFic3RyYWN0IEFkZEZpbGVHcm91cFJlcXVlc3QgYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9BZ2dyZWdhdGVFeGNlcHRpb24uamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvQWdncmVnYXRlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTQwODBkOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvQWdncmVnYXRlRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwxOTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgYW5kcm9pZHguYW5ub3RhdGlvbi5WaXNpYmxlRm9yVGVzdGluZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlQ2FsbGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlN0cmluZ1dyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNhbmNlbGxhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5OdWxsYWJsZTsKKworLyoqCisgKiBSZXByZXNlbnRzIGFuIGV4Y2VwdGlvbiB0aGF0J3MgYW4gYWdncmVnYXRlIG9mIG11bHRpcGxlIG90aGVyIGV4Y2VwdGlvbnMuCisgKgorICogPHA+VGhlIGZpcnN0IGFnZ3JlZ2F0ZWQgZXhjZXB0aW9uIGluIHNldCBhcyB0aGUgY2F1c2UgKHNlZSB7QGxpbmsgRXhjZXB0aW9uI2dldENhdXNlfSkgb2YgdGhlCisgKiB7QGxpbmsgQWdncmVnYXRlRXhjZXB0aW9ufS4gVGhlIGZ1bGwgbGlzdCBjYW4gYmUgYWNjZXNzZWQgd2l0aCB7QGxpbmsgI2dldEZhaWx1cmVzfS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVBBUkFUT1JfSEVBREVSID0gIi0tLSBGYWlsdXJlICVkIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTRVBBUkFUT1IgPSAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSI7CisKKyAgLyoqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBjYXVzZXMgdG8gcmVjdXJzaXZlbHkgcHJpbnQgaW4gYW4gZXhjZXB0aW9uJ3MgbWVzc2FnZS4gKi8KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9DQVVTRV9ERVBUSCA9IDU7CisKKyAgcHJpdmF0ZSBmaW5hbCBJbW11dGFibGVMaXN0PFRocm93YWJsZT4gZmFpbHVyZXM7CisKKyAgcHJpdmF0ZSBBZ2dyZWdhdGVFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSwgSW1tdXRhYmxlTGlzdDxUaHJvd2FibGU+IGZhaWx1cmVzKSB7CisgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICAgIHRoaXMuZmFpbHVyZXMgPSBmYWlsdXJlczsKKyAgfQorCisgIC8qKiBSZXR1cm5zIHRoZSBsaXN0IG9mIHRoZSBhZ2dyZWdhdGVkIGZhaWx1cmVzLiAqLworICBwdWJsaWMgSW1tdXRhYmxlTGlzdDxUaHJvd2FibGU+IGdldEZhaWx1cmVzKCkgeworICAgIHJldHVybiBmYWlsdXJlczsKKyAgfQorCisgIC8qKgorICAgKiBUaHJvd3Mge0BsaW5rIEFnZ3JlZ2F0ZUV4Y2VwdGlvbn0gaWYgYW55IG9mIHRoZSBmdXR1cmUgaW4ge0Bjb2RlIGZ1dHVyZXN9IGZhaWxzIHdpdGggZWl0aGVyCisgICAqIHtAbGluayBDYW5jZWxsYXRpb25FeGNlcHRpb259IG9yIHtAbGluayBFeGVjdXRpb25FeGNlcHRpb259LgorICAgKgorICAgKiA8cD5UaGUge0Bjb2RlIGNhbGxiYWNrT3B0aW9uYWx9LCBpZiBwcmVzZW50LCB3aWxsIGJlIGV4ZWN1dGVkIGVhY2ggdGltZSB3aGVuIGEgZnV0dXJlIGluc2lkZQorICAgKiB7QGNvZGUgZnV0dXJlc30gY29tcGxldGVzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyA8VD4gdm9pZCB0aHJvd0lmRmFpbGVkKAorICAgICAgQ29sbGVjdGlvbjxMaXN0ZW5hYmxlRnV0dXJlPFQ+PiBmdXR1cmVzLAorICAgICAgT3B0aW9uYWw8RnV0dXJlQ2FsbGJhY2s8VD4+IGNhbGxiYWNrT3B0aW9uYWwsCisgICAgICBTdHJpbmcgbWVzc2FnZSwKKyAgICAgIE9iamVjdC4uLiBhcmdzKQorICAgICAgdGhyb3dzIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiB7CisgICAgSW1tdXRhYmxlTGlzdC5CdWlsZGVyPFRocm93YWJsZT4gYnVpbGRlciA9IG51bGw7CisgICAgZm9yIChMaXN0ZW5hYmxlRnV0dXJlPFQ+IGZ1dHVyZSA6IGZ1dHVyZXMpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIFQgcmVzdWx0ID0gRnV0dXJlcy5nZXREb25lKGZ1dHVyZSk7CisgICAgICAgIGlmIChjYWxsYmFja09wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgY2FsbGJhY2tPcHRpb25hbC5nZXQoKS5vblN1Y2Nlc3MocmVzdWx0KTsKKyAgICAgICAgfQorICAgICAgfSBjYXRjaCAoQ2FuY2VsbGF0aW9uRXhjZXB0aW9uIHwgRXhlY3V0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgLy8gVW53cmFwIHRoZSBjYXVzZSBvZiB0aGUgZXhlY3V0aW9uIGV4Y2VwdGlvbiwgd2Ugd2lsbCBpbnN0ZWFkIHdyYXAgaXQgd2l0aCB0aGUgYWdncmVnYXRlLgorICAgICAgICBpZiAoYnVpbGRlciA9PSBudWxsKSB7CisgICAgICAgICAgYnVpbGRlciA9IEltbXV0YWJsZUxpc3QuYnVpbGRlcigpOworICAgICAgICB9CisgICAgICAgIFRocm93YWJsZSB1bndyYXBwZWQgPSB1bndyYXBFeGNlcHRpb24oZSk7CisgICAgICAgIGJ1aWxkZXIuYWRkKHVud3JhcHBlZCk7CisgICAgICAgIGlmIChjYWxsYmFja09wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgY2FsbGJhY2tPcHRpb25hbC5nZXQoKS5vbkZhaWx1cmUodW53cmFwcGVkKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICBpZiAoYnVpbGRlciA9PSBudWxsKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIGZpbmFsIEltbXV0YWJsZUxpc3Q8VGhyb3dhYmxlPiBmYWlsdXJlcyA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICB0aHJvdyBuZXdJbnN0YW5jZShmYWlsdXJlcywgbWVzc2FnZSwgYXJncyk7CisgIH0KKworICAvKioKKyAgICogVGhyb3dzIHtAbGluayBBZ2dyZWdhdGVFeGNlcHRpb259IGlmIGFueSBvZiB0aGUgZnV0dXJlIGluIHtAY29kZSBmdXR1cmVzfSBmYWlscyB3aXRoIGVpdGhlcgorICAgKiB7QGxpbmsgQ2FuY2VsbGF0aW9uRXhjZXB0aW9ufSBvciB7QGxpbmsgRXhlY3V0aW9uRXhjZXB0aW9ufS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgPFQ+IHZvaWQgdGhyb3dJZkZhaWxlZCgKKyAgICAgIENvbGxlY3Rpb248TGlzdGVuYWJsZUZ1dHVyZTxUPj4gZnV0dXJlcywgU3RyaW5nIG1lc3NhZ2UsIE9iamVjdC4uLiBhcmdzKQorICAgICAgdGhyb3dzIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiB7CisgICAgdGhyb3dJZkZhaWxlZChmdXR1cmVzLCAvKiBjYWxsYmFja09wdGlvbmFsPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwgbWVzc2FnZSwgYXJncyk7CisgIH0KKworICAvKioKKyAgICogQ29uc29saWRhdGVzIGNvbXBsZXRlZCBmdXR1cmVzIGludG8gYSBzaW5nbGUgZmFpbGVkIGZ1dHVyZXMgaWYgYW55IGZhaWx1cmVzIGV4aXN0LgorICAgKgorICAgKiA8cD5JZiB0aGVyZSBhcmUgbm8gZmFpbHVyZXMsIGEgdm9pZCBmdXR1cmUgd2lsbCBiZSByZXR1cm5lZC4KKyAgICoKKyAgICogPHA+SWYgdGhlcmUgaXMgYSBzaW5nbGUgZmFpbHVyZSwgdGhhdCBmYWlsdXJlIHdpbGwgYmUgcmV0dXJuZWQuCisgICAqCisgICAqIDxwPklmIHRoZXJlIGFyZSBtdWx0aXBsZSBmYWlsdXJlcywgYW4gQWdncmVnYXRlRXhjZXB0aW9uIGNvbnRhaW5pbmcgYWxsIGZhaWx1cmVzIHdpbGwgYmUKKyAgICogcmV0dXJuZWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIDxUPiBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNvbnNvbGlkYXRlRG9uZUZ1dHVyZXMoCisgICAgICBDb2xsZWN0aW9uPExpc3RlbmFibGVGdXR1cmU8VD4+IGZ1dHVyZXMsIFN0cmluZyBtZXNzYWdlLCBPYmplY3QuLi4gYXJncykgeworICAgIHRyeSB7CisgICAgICAvLyBDaGVjayBpZiBhbnkgZnV0dXJlcyBhcmUgZmFpbGVkLgorICAgICAgdGhyb3dJZkZhaWxlZChmdXR1cmVzLCBtZXNzYWdlLCBhcmdzKTsKKyAgICB9IGNhdGNoIChBZ2dyZWdhdGVFeGNlcHRpb24gZSkgeworICAgICAgaWYgKGUuZ2V0RmFpbHVyZXMoKS5zaXplKCkgPT0gMSkgeworICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoZS5nZXRGYWlsdXJlcygpLmdldCgwKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoZSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgfQorCisgIC8qKiBDb25zdHJ1Y3RzIGEgbmV3IHtAbGluayBBZ2dyZWdhdGVFeGNlcHRpb259IHdpdGggdGhlIGdpdmVuIHRocm93YWJsZXMuICovCisgIHB1YmxpYyBzdGF0aWMgQWdncmVnYXRlRXhjZXB0aW9uIG5ld0luc3RhbmNlKAorICAgICAgSW1tdXRhYmxlTGlzdDxUaHJvd2FibGU+IGZhaWx1cmVzLCBTdHJpbmcgbWVzc2FnZSwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICBTdHJpbmcgcHJvbG9ndWUgPSBTdHJpbmcuZm9ybWF0KExvY2FsZS5VUywgbWVzc2FnZSwgYXJncyk7CisgICAgcmV0dXJuIG5ldyBBZ2dyZWdhdGVFeGNlcHRpb24oCisgICAgICAgIGZhaWx1cmVzLnNpemUoKSA+IDEKKyAgICAgICAgICAgID8gdGhyb3dhYmxlc1RvU3RyaW5nKAorICAgICAgICAgICAgICAgIHByb2xvZ3VlICsgIlxuIiArIGZhaWx1cmVzLnNpemUoKSArICIgZmFpbHVyZShzKSBpbiB0b3RhbDpcbiIsIGZhaWx1cmVzKQorICAgICAgICAgICAgOiBwcm9sb2d1ZSwKKyAgICAgICAgZmFpbHVyZXMuZ2V0KDApLAorICAgICAgICBmYWlsdXJlcyk7CisgIH0KKworICBAVmlzaWJsZUZvclRlc3RpbmcKKyAgc3RhdGljIFRocm93YWJsZSB1bndyYXBFeGNlcHRpb24oVGhyb3dhYmxlIHQpIHsKKyAgICBUaHJvd2FibGUgY2F1c2UgPSB0LmdldENhdXNlKCk7CisgICAgaWYgKGNhdXNlID09IG51bGwpIHsKKyAgICAgIHJldHVybiB0OworICAgIH0KKyAgICBDbGFzczw/PiBjbGF6eiA9IHQuZ2V0Q2xhc3MoKTsKKyAgICBpZiAoY2xhenouZXF1YWxzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcykpIHsKKyAgICAgIHJldHVybiB1bndyYXBFeGNlcHRpb24oY2F1c2UpOworICAgIH0KKyAgICByZXR1cm4gdDsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0aHJvd2FibGVzVG9TdHJpbmcoCisgICAgICBATnVsbGFibGUgU3RyaW5nIHByb2xvZ3VlLCBJbW11dGFibGVMaXN0PFRocm93YWJsZT4gdGhyb3dhYmxlcykgeworICAgIHRyeSAoU3RyaW5nV3JpdGVyIG91dCA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKKyAgICAgICAgUHJpbnRXcml0ZXIgd3JpdGVyID0gbmV3IFByaW50V3JpdGVyKG91dCkpIHsKKyAgICAgIGlmIChwcm9sb2d1ZSAhPSBudWxsKSB7CisgICAgICAgIHdyaXRlci5wcmludGxuKHByb2xvZ3VlKTsKKyAgICAgIH0KKyAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhyb3dhYmxlcy5zaXplKCk7IGkrKykgeworICAgICAgICBUaHJvd2FibGUgZmFpbHVyZSA9IHRocm93YWJsZXMuZ2V0KGkpOworICAgICAgICB3cml0ZXIucHJpbnRmKFNFUEFSQVRPUl9IRUFERVIsIChpICsgMSkpOworICAgICAgICB3cml0ZXIucHJpbnRsbih0aHJvd2FibGVUb1N0cmluZyhmYWlsdXJlKSk7CisgICAgICB9CisgICAgICB3cml0ZXIucHJpbnRsbihTRVBBUkFUT1IpOworICAgICAgcmV0dXJuIG91dC50b1N0cmluZygpOworICAgIH0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CisgICAgICByZXR1cm4gIkZhaWxlZCB0byBidWlsZCBzdHJpbmcgZnJvbSB0aHJvd2FibGVzOiAiICsgdDsKKyAgICB9CisgIH0KKworICBAVmlzaWJsZUZvclRlc3RpbmcKKyAgc3RhdGljIFN0cmluZyB0aHJvd2FibGVUb1N0cmluZyhUaHJvd2FibGUgZmFpbHVyZSkgeworICAgIHJldHVybiB0aHJvd2FibGVUb1N0cmluZyhmYWlsdXJlLCAvKmRlcHRoPSovIDEpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIHRocm93YWJsZVRvU3RyaW5nKFRocm93YWJsZSBmYWlsdXJlLCBpbnQgZGVwdGgpIHsKKyAgICBTdHJpbmcgbWVzc2FnZSA9IGZhaWx1cmUuZ2V0Q2xhc3MoKS5nZXROYW1lKCkgKyAiOiAiICsgZmFpbHVyZS5nZXRNZXNzYWdlKCk7CisgICAgVGhyb3dhYmxlIGNhdXNlID0gZmFpbHVyZS5nZXRDYXVzZSgpOworICAgIGlmIChjYXVzZSAhPSBudWxsKSB7CisgICAgICBpZiAoZGVwdGggPj0gTUFYX0NBVVNFX0RFUFRIKSB7CisgICAgICAgIHJldHVybiBtZXNzYWdlICsgIlxuKC4uLikiOworICAgICAgfQorICAgICAgcmV0dXJuIG1lc3NhZ2UgKyAiXG5DYXVzZWQgYnk6ICIgKyB0aHJvd2FibGVUb1N0cmluZyhjYXVzZSwgZGVwdGggKyAxKTsKKyAgICB9CisgICAgcmV0dXJuIG1lc3NhZ2U7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvQW5kcm9pZE1hbmlmZXN0LnhtbCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvQW5kcm9pZE1hbmlmZXN0LnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNDhlMTg4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9BbmRyb2lkTWFuaWZlc3QueG1sCkBAIC0wLDAgKzEsMjYgQEAKKzwhLS0KKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCistLT4KKzxtYW5pZmVzdAorICAgIHhtbG5zOmFuZHJvaWQ9Imh0dHA6Ly9zY2hlbWFzLmFuZHJvaWQuY29tL2Fway9yZXMvYW5kcm9pZCIKKyAgICBwYWNrYWdlPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZCI+CisKKyAgPHVzZXMtc2RrIGFuZHJvaWQ6bWluU2RrVmVyc2lvbj0iMTYiLz4KKworICA8IS0tIEFuIGVtcHR5IGFwcGxpY2F0aW9uIHRhZyBpcyByZXF1aXJlZCBmb3IgZnJhbWV3b3JrIEFBUiBjb25mb3JtYW5jZS4gLS0+CisgIDxhcHBsaWNhdGlvbj48L2FwcGxpY2F0aW9uPgorPC9tYW5pZmVzdD4KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczM2Q4MTQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0JVSUxECkBAIC0wLDAgKzEsMjU1IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9saWJyYXJ5IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbCisgICAgICAgICIvL3Zpc2liaWxpdHk6cHVibGljIiwKKyAgICBdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAibW9iaWxlZGF0YWRvd25sb2FkIiwKKyAgICBzcmNzID0gZ2xvYigKKyAgICAgICAgWyIqLmphdmEiXSwKKyAgICAgICAgZXhjbHVkZSA9IFsKKyAgICAgICAgICAgICJBY2NvdW50U291cmNlLmphdmEiLAorICAgICAgICAgICAgIkFnZ3JlZ2F0ZUV4Y2VwdGlvbi5qYXZhIiwKKyAgICAgICAgICAgICJDb25maWd1cmF0b3IuamF2YSIsCisgICAgICAgICAgICAiVGltZVNvdXJjZS5qYXZhIiwKKyAgICAgICAgICAgICJGbGFncy5qYXZhIiwKKyAgICAgICAgICAgICJDb25zdGFudHMuamF2YSIsCisgICAgICAgICAgICAiRG93bmxvYWRFeGNlcHRpb24uamF2YSIsCisgICAgICAgICAgICAiRG93bmxvYWRMaXN0ZW5lci5qYXZhIiwKKyAgICAgICAgICAgICJMb2dnZXIuamF2YSIsCisgICAgICAgICAgICAiTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlci5qYXZhIiwKKyAgICAgICAgICAgICJTaWxlbnRGZWVkYmFjay5qYXZhIiwKKyAgICAgICAgICAgICJVc2FnZUV2ZW50LmphdmEiLAorICAgICAgICAgICAgIlNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QuamF2YSIsCisgICAgICAgICAgICAiU2luZ2xlRmlsZURvd25sb2FkTGlzdGVuZXIuamF2YSIsCisgICAgICAgICAgICAiRmlsZVNvdXJjZS5qYXZhIiwKKyAgICAgICAgICAgICJFeHBlcmltZW50YXRpb25Db25maWcuamF2YSIsCisgICAgICAgIF0sCisgICAgKSwKKyAgICBleHBvcnRzID0gWworICAgICAgICAiOnNpbmdsZV9maWxlX2ludGVyZmFjZXMiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpEb3dubG9hZEV4Y2VwdGlvbiIsCisgICAgICAgICI6RG93bmxvYWRMaXN0ZW5lciIsCisgICAgICAgICI6RmlsZVNvdXJjZSIsCisgICAgICAgICI6RmxhZ3MiLAorICAgICAgICAiOlVzYWdlRXZlbnQiLAorICAgICAgICAiOnNpbmdsZV9maWxlX2ludGVyZmFjZXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2FjY291bnQ6QWNjb3VudFV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZvcmVncm91bmQ6Tm90aWZpY2F0aW9uVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpFdmVudExvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6TWRkTGl0ZUNvbnZlcnNpb25VdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOlByb3RvQ29udmVyc2lvblV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3I6RG93bmxvYWRQcm9ncmVzc01vbml0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3RyYWNpbmciLAorICAgICAgICAiLy9wcm90bzpjbGllbnRfY29uZmlnX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL3Byb3RvOmRvd25sb2FkX2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGFuZHJvaWR4X2Fubm90YXRpb25fYW5ub3RhdGlvbiIsCisgICAgICAgICJAYW5kcm9pZHhfY29yZV9jb3JlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2F1dG9fdmFsdWUiLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzphbnlfcHJvdG8iLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzpwcm90b2J1Zl9saXRlIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIiwKKyAgICBzcmNzID0gWworICAgICAgICAiTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlci5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6QWNjb3VudFNvdXJjZSIsCisgICAgICAgICI6Q29uZmlndXJhdG9yIiwKKyAgICAgICAgIjpDb25zdGFudHMiLAorICAgICAgICAiOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIjpEb3dubG9hZExpc3RlbmVyIiwKKyAgICAgICAgIjpFeHBlcmltZW50YXRpb25Db25maWciLAorICAgICAgICAiOkZsYWdzIiwKKyAgICAgICAgIjpMb2dnZXIiLAorICAgICAgICAiOlNpbGVudEZlZWRiYWNrIiwKKyAgICAgICAgIjptb2JpbGVkYXRhZG93bmxvYWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2FjY291bnQ6QWNjb3VudE1hbmFnZXJBY2NvdW50U291cmNlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hY2NvdW50OkFjY291bnRVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kZWx0YTpEZWx0YURlY29kZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXI6RmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZvcmVncm91bmQ6Tm90aWZpY2F0aW9uVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZGFnZ2VyOkFwcGxpY2F0aW9uQ29udGV4dE1vZHVsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZGFnZ2VyOkRvd25sb2FkZXJNb2R1bGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2RhZ2dlcjpFeGVjdXRvcnNNb2R1bGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2RhZ2dlcjpNYWluTWRkTGliTW9kdWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kYWdnZXI6U3RhbmRhbG9uZUNvbXBvbmVudCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpFdmVudExvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dTYW1wbGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ1V0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TWRkRXZlbnRMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6Tm9PcEV2ZW50TG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6UHJvdG9Db252ZXJzaW9uVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpOZXR3b3JrVXNhZ2VNb25pdG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nIiwKKyAgICAgICAgIi8vcHJvdG86Y2xpZW50X2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkeF9jb3JlX2NvcmUiLAorICAgICAgICAiQGNvbV9nb29nbGVfYXV0b192YWx1ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICJAY29tX2dvb2dsZV9kYWdnZXIiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzpwcm90b2J1Zl9saXRlIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJBY2NvdW50U291cmNlIiwKKyAgICBzcmNzID0gWyJBY2NvdW50U291cmNlLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIlRpbWVTb3VyY2UiLAorICAgIHNyY3MgPSBbIlRpbWVTb3VyY2UuamF2YSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJDb25maWd1cmF0b3IiLAorICAgIHNyY3MgPSBbIkNvbmZpZ3VyYXRvci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJGbGFncyIsCisgICAgc3JjcyA9IFsiRmxhZ3MuamF2YSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJMb2dnZXIiLAorICAgIHNyY3MgPSBbIkxvZ2dlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86cHJvdG9idWZfbGl0ZSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiU2lsZW50RmVlZGJhY2siLAorICAgIHNyY3MgPSBbIlNpbGVudEZlZWRiYWNrLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiQGNvbV9nb29nbGVfZXJyb3Jwcm9uZV9lcnJvcl9wcm9uZV9hbm5vdGF0aW9ucyIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiVGFza1NjaGVkdWxlciIsCisgICAgc3JjcyA9IFsiVGFza1NjaGVkdWxlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX2F1dG9fdmFsdWUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkRvd25sb2FkTGlzdGVuZXIiLAorICAgIHNyY3MgPSBbIkRvd25sb2FkTGlzdGVuZXIuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIi8vcHJvdG86Y2xpZW50X2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkNvbnN0YW50cyIsCisgICAgc3JjcyA9IFsiQ29uc3RhbnRzLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJEb3dubG9hZEV4Y2VwdGlvbiIsCisgICAgc3JjcyA9IFsiRG93bmxvYWRFeGNlcHRpb24uamF2YSJdLAorICAgIGRlcHMgPSBbIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkZpbGVTb3VyY2UiLAorICAgIHNyY3MgPSBbIkZpbGVTb3VyY2UuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICJAY29tX2dvb2dsZV9wcm90b2J1Zi8vOnByb3RvYnVmX2xpdGUiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkFnZ3JlZ2F0ZUV4Y2VwdGlvbiIsCisgICAgc3JjcyA9IFsiQWdncmVnYXRlRXhjZXB0aW9uLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiQGFuZHJvaWR4X2Fubm90YXRpb25fYW5ub3RhdGlvbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAic2luZ2xlX2ZpbGVfaW50ZXJmYWNlcyIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlNpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyLmphdmEiLAorICAgICAgICAiU2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlcjpGaWxlRG93bmxvYWRlciIsCisgICAgICAgICJAY29tX2dvb2dsZV9hdXRvX3ZhbHVlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJVc2FnZUV2ZW50IiwKKyAgICBzcmNzID0gWworICAgICAgICAiVXNhZ2VFdmVudC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL3Byb3RvOmNsaWVudF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2F1dG9fdmFsdWUiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkV4cGVyaW1lbnRhdGlvbkNvbmZpZyIsCisgICAgc3JjcyA9IFsiRXhwZXJpbWVudGF0aW9uQ29uZmlnLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiQGNvbV9nb29nbGVfYXV0b192YWx1ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvQ29uZmlndXJhdG9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0NvbmZpZ3VyYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4MmU2YzUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0NvbmZpZ3VyYXRvci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CisKKy8qKiBJbnRlcmZhY2UgZm9yIHVwZGF0ZSBjb25maWd1cmF0aW9ucyAqLworcHVibGljIGludGVyZmFjZSBDb25maWd1cmF0b3IgeworCisgIC8qKiBDb21taXRzIHRvIHRoZSBtb3N0IHJlY2VudCBjb25maWd1cmF0aW9uLiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNvbW1pdFRvRmxhZ1NuYXBzaG90KCk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0NvbnN0YW50cy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Db25zdGFudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YzcxY2QxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Db25zdGFudHMuamF2YQpAQCAtMCwwICsxLDQ0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZDsKKworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5Eb3dubG9hZENvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5Eb3dubG9hZENvbmRpdGlvbnMuRGV2aWNlTmV0d29ya1BvbGljeTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VTdG9yYWdlUG9saWN5OworCisvKiogRXh0ZXJuYWwgTUREIENvbnN0YW50cyAqLworcHVibGljIGZpbmFsIGNsYXNzIENvbnN0YW50cyB7CisgIC8vIFRPRE86IEZpZ3VyZSBvdXQgaWYgd2UgY2FuIGFkZCBhIHRlc3QgdG8ga2VlcCBpbiBzeW5jIHdpdGggRG93bmxvYWRDb25kaXRpb24KKyAgLyoqIFRvIGRvd25sb2FkIHVuZGVyIGFueSBjb25kaXRpb25zLCBjbGllbnRzIHNob3VsZCB1c2UgY29uc3RhbnQuICovCisgIC8vIExJTlQuSWZDaGFuZ2UKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBPcHRpb25hbDxEb3dubG9hZENvbmRpdGlvbnM+IE5PX1JFU1RSSUNUSU9OU19ET1dOTE9BRF9DT05ESVRJT05TID0KKyAgICAgIE9wdGlvbmFsLm9mKAorICAgICAgICAgIERvd25sb2FkQ29uZGl0aW9ucy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgLnNldERldmljZU5ldHdvcmtQb2xpY3koRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSykKKyAgICAgICAgICAgICAgLnNldERldmljZVN0b3JhZ2VQb2xpY3koRGV2aWNlU3RvcmFnZVBvbGljeS5CTE9DS19ET1dOTE9BRF9MT1dFUl9USFJFU0hPTEQpCisgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgLy8gTElOVC5UaGVuQ2hhbmdlKDxpbnRlcm5hbD4pCisKKyAgLyoqIFRoZSB2ZXJzaW9uIG9mIE1ERCBsaWJyYXJ5LiBTYW1lIGFzIG1kaV9kb3dubG9hZCBtb2R1bGUgdmVyc2lvbi4gKi8KKyAgLy8gVE9ETyhiLzEyMjI3MTc2Nik6IEZpZ3VyZSBvdXQgaG93IHRvIHVwZGF0ZSB0aGlzIGF1dG9tYXRpY2FsbHkuCisgIC8vIExJTlQuSWZDaGFuZ2UKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUREX0xJQl9WRVJTSU9OID0gNDIyODgzODM4OworICAvLyBMSU5ULlRoZW5DaGFuZ2UoPGludGVybmFsPikKKworICAvLyA8aW50ZXJuYWw+CisgIHByaXZhdGUgQ29uc3RhbnRzKCkge30KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvQ3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0N1c3RvbUZpbGVHcm91cFZhbGlkYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE5YmVhZmUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0N1c3RvbUZpbGVHcm91cFZhbGlkYXRvci5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5lcnJvcnByb25lLmFubm90YXRpb25zLkNoZWNrUmV0dXJuVmFsdWU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuQ2xpZW50Q29uZmlnUHJvdG8uQ2xpZW50RmlsZUdyb3VwOworCisvKioKKyAqIFJ1bnMgY3VzdG9tIHZhbGlkYXRpb24gcm91dGluZSBvbiB0aGUgZmlsZSBncm91cC4gVGhlIGZpbGUgZ3JvdXAgaXMgbm90IGFsbG93ZWQgdG8gYmVjb21lIGFjdGl2ZQorICogdW5sZXNzIHRoaXMgcmV0dXJucyB0cnVlLgorICoKKyAqIDxwPlRoaXMgY2FsbGJhY2sgaXMgaW52b2tlZCBmb3IgYWxsIGZpbGUgZ3JvdXBzIGluIHRoZSBNREQgaW5zdGFuY2UuIEl0IGlzIHVwIHRvIHRoZSBpbXBsZW1lbnRvcgorICogdG8gaGFuZGxlIGZpbGUgZ3JvdXBzIHRoYXQgZG9uJ3QgbmVlZCB2YWxpZGF0aW9uIGJ5LCBlZywgcmV0dXJuaW5nIHRydWUgaW1tZWRpYXRlbHkuCisgKgorICogPHA+VGhlIENsaWVudEZpbGVHcm91cCBhY2NvdW50IGZpZWxkIGlzIG5ldmVyIHBvcHVsYXRlZCBkdXJpbmcgdmFsaWRhdGlvbi4gVGhlIHN0YXR1cyBmaWVsZCB3aWxsCisgKiBiZSBzZXQgdG8gUEVORElOR19DVVNUT01fVkFMSURBVElPTi4KKyAqLworQENoZWNrUmV0dXJuVmFsdWUKK3B1YmxpYyBpbnRlcmZhY2UgQ3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yIHsKKyAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiB2YWxpZGF0ZUZpbGVHcm91cChDbGllbnRGaWxlR3JvdXAgZmlsZUdyb3VwKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvRG93bmxvYWRFeGNlcHRpb24uamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvRG93bmxvYWRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYzlhMTQ4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Eb3dubG9hZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjM3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmU7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlByZWNvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CisKKy8qKiBUaHJvd24gd2hlbiB0aGVyZSBpcyBhIGRvd25sb2FkIGZhaWx1cmUuICovCitwdWJsaWMgZmluYWwgY2xhc3MgRG93bmxvYWRFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24geworICAvKiogVGhpcyBlcnJvciBjb2RlIGlzIGEgcmVwcmVzZW50YXRpb24gb2Yge0Bjb2RlIE1kZERvd25sb2FkUmVzdWx0LkNvZGV9LiAqLworICBwcml2YXRlIGZpbmFsIERvd25sb2FkUmVzdWx0Q29kZSBkb3dubG9hZFJlc3VsdENvZGU7CisKKyAgLyoqCisgICAqIFRoaXMgaXMgdGhlIHJlc3VsdCBvZiBjYWxsaW5nIGRvd25sb2FkLCB3aGljaCBzaG91bGQgYmUgaWRlbnRpY2FsIHRvIHtAY29kZQorICAgKiBNZGREb3dubG9hZFJlc3VsdC5Db2RlfS4KKyAgICovCisgIC8vIExJTlQuSWZDaGFuZ2UKKyAgcHVibGljIGVudW0gRG93bmxvYWRSZXN1bHRDb2RlIHsKKyAgICBVTlNQRUNJRklFRCgwKSwgLy8gdW5zZXQgdmFsdWUKKworICAgIC8vIEZpbGUgZG93bmxvYWRlZCBzdWNjZXNzZnVsbHkuCisgICAgLy8gVGhpcyBpcyBqdXN0IGEgcGxhY2Vob2xkZXIsIHdlIGN1cnJlbnRseSBkb24ndCBsb2cgZm9yIHN1Y2Nlc3MgY2FzZS4KKyAgICBTVUNDRVNTKDEpLAorCisgICAgLy8gVGhlIGVycm9yIHdlIGRvbid0IGtub3cuCisgICAgVU5LTk9XTl9FUlJPUigyKSwKKworICAgIC8vIFRoZSBlcnJvcnMgZnJvbSB0aGUgYW5kcm9pZCBkb3dubG9hZGVyIG91dHNpZGUgTURELCB3aGljaCBjb21lcyBmcm9tOgorICAgIC8vIDxpbnRlcm5hbD4KKyAgICBBTkRST0lEX0RPV05MT0FERVJfVU5LTk9XTigxMDApLAorICAgIEFORFJPSURfRE9XTkxPQURFUl9DQU5DRUxFRCgxMDEpLAorICAgIEFORFJPSURfRE9XTkxPQURFUl9JTlZBTElEX1JFUVVFU1QoMTAyKSwKKyAgICBBTkRST0lEX0RPV05MT0FERVJfSFRUUF9FUlJPUigxMDMpLAorICAgIEFORFJPSURfRE9XTkxPQURFUl9SRVFVRVNUX0VSUk9SKDEwNCksCisgICAgQU5EUk9JRF9ET1dOTE9BREVSX1JFU1BPTlNFX09QRU5fRVJST1IoMTA1KSwKKyAgICBBTkRST0lEX0RPV05MT0FERVJfUkVTUE9OU0VfQ0xPU0VfRVJST1IoMTA2KSwKKyAgICBBTkRST0lEX0RPV05MT0FERVJfTkVUV09SS19JT19FUlJPUigxMDcpLAorICAgIEFORFJPSURfRE9XTkxPQURFUl9ESVNLX0lPX0VSUk9SKDEwOCksCisgICAgQU5EUk9JRF9ET1dOTE9BREVSX0ZJTEVfU1lTVEVNX0VSUk9SKDEwOSksCisgICAgQU5EUk9JRF9ET1dOTE9BREVSX1VOS05PV05fSU9fRVJST1IoMTEwKSwKKyAgICBBTkRST0lEX0RPV05MT0FERVJfT0FVVEhfRVJST1IoMTExKSwKKworICAgIC8vIFRoZSBlcnJvcnMgZnJvbSB0aGUgYW5kcm9pZCBkb3dubG9hZGVyIHYyIG91dHNpZGUgTURELCB3aGljaCBjb21lcyBmcm9tOgorICAgIC8vIDxpbnRlcm5hbD4KKyAgICBBTkRST0lEX0RPV05MT0FERVIyX0VSUk9SKDIwMCksCisKKyAgICAvLyBUaGUgZGF0YSBmaWxlIGdyb3VwIGhhcyBub3QgYmVlbiBhZGRlZCB0byBNREQgYnkgdGhlIHRpbWUgdGhlIGNhbGxlcgorICAgIC8vIG1ha2VzIGRvd25sb2FkIEFQSSBjYWxsLgorICAgIEdST1VQX05PVF9GT1VORF9FUlJPUigzMDApLAorCisgICAgLy8gVGhlIERvd25sb2FkTGlzdGVuZXIgaXMgcHJlc2VudCBidXQgdGhlIERvd25sb2FkTW9uaXRvciBpcyBub3QgcHJvdmlkZWQuCisgICAgRE9XTkxPQURfTU9OSVRPUl9OT1RfUFJPVklERURfRVJST1IoMzAxKSwKKworICAgIC8vIEVycm9ycyBmcm9tIHVuc2F0aXNmaWVkIGRvd25sb2FkIHByZWNvbmRpdGlvbnMuCisgICAgSU5TRUNVUkVfVVJMX0VSUk9SKDMwMiksCisgICAgTE9XX0RJU0tfRVJST1IoMzAzKSwKKworICAgIC8vIEVycm9ycyBmcm9tIGRvd25sb2FkIHByZXBhcmF0aW9uLgorICAgIFVOQUJMRV9UT19DUkVBVEVfRklMRV9VUklfRVJST1IoMzA0KSwKKyAgICBTSEFSRURfRklMRV9OT1RfRk9VTkRfRVJST1IoMzA1KSwKKyAgICBNQUxGT1JNRURfRklMRV9VUklfRVJST1IoMzA2KSwKKyAgICBVTkFCTEVfVE9fQ1JFQVRFX01PQlNUT1JFX1JFU1BPTlNFX1dSSVRFUl9FUlJPUigzMDcpLAorCisgICAgLy8gRXJyb3JzIGZyb20gZmlsZSB2YWxpZGF0aW9uLgorICAgIFVOQUJMRV9UT19WQUxJREFURV9ET1dOTE9BRF9GSUxFX0VSUk9SKDMwOCksCisgICAgRE9XTkxPQURFRF9GSUxFX05PVF9GT1VORF9FUlJPUigzMDkpLAorICAgIERPV05MT0FERURfRklMRV9DSEVDS1NVTV9NSVNNQVRDSF9FUlJPUigzMTApLAorICAgIENVU1RPTV9GSUxFR1JPVVBfVkFMSURBVElPTl9GQUlMRUQoMzMwKSwKKworICAgIC8vIEVycm9ycyBmcm9tIGRvd25sb2FkIHRyYW5zZm9ybXMuCisgICAgVU5BQkxFX1RPX1NFUklBTElaRV9ET1dOTE9BRF9UUkFOU0ZPUk1fRVJST1IoMzExKSwKKyAgICBET1dOTE9BRF9UUkFOU0ZPUk1fSU9fRVJST1IoMzEyKSwKKyAgICBGSU5BTF9GSUxFX0NIRUNLU1VNX01JU01BVENIX0VSUk9SKDMxMyksCisKKyAgICAvLyBFcnJvcnMgZnJvbSBkZWx0YSBkb3dubG9hZC4KKyAgICBERUxUQV9ET1dOTE9BRF9CQVNFX0ZJTEVfTk9UX0ZPVU5EX0VSUk9SKDMxNCksCisgICAgREVMVEFfRE9XTkxPQURfREVDT0RFX0lPX0VSUk9SKDMxNSksCisKKyAgICAvLyBUaGUgZXJyb3Igb2NjdXJzIGFmdGVyIHRoZSBmaWxlIGlzIHJlYWR5LgorICAgIFVOQUJMRV9UT19VUERBVEVfRklMRV9TVEFURV9FUlJPUigzMTYpLAorCisgICAgLy8gRmFpbCB0byB1cGRhdGUgdGhlIGZpbGUgZ3JvdXAgbWV0YWRhdGEuCisgICAgVU5BQkxFX1RPX1VQREFURV9HUk9VUF9NRVRBREFUQV9FUlJPUigzMTcpLAorCisgICAgLy8gRXJyb3JzIGZyb20gc2hhcmluZyBmaWxlcyB3aXRoIHRoZSBibG9iIHN0b3JhZ2UuCisgICAgLy8gRmFpbGVkIHRvIHVwZGF0ZSB0aGUgbWV0YWRhdGEgbWF4X2V4cGlyYXRpb25fZGF0ZS4KKyAgICBVTkFCTEVfVE9fVVBEQVRFX0ZJTEVfTUFYX0VYUElSQVRJT05fREFURSgzMTgpLAorICAgIC8vIEZhaWxlZCB0byBzaGFyZSB0aGUgZmlsZSBiZWZvcmUgU2hhcmVkRmlsZU1hbmFnZXIuc3RhcnREb3dubG9hZCBpcyBjYWxsZWQuCisgICAgVU5BQkxFX1NIQVJFX0ZJTEVfQkVGT1JFX0RPV05MT0FEX0VSUk9SKDMxOSksCisgICAgLy8gRmFpbGVkIHRvIHNoYXJlIHRoZSBmaWxlIGFmdGVyIFNoYXJlZEZpbGVNYW5hZ2VyLnN0YXJ0RG93bmxvYWQgaXMgY2FsbGVkLgorICAgIFVOQUJMRV9TSEFSRV9GSUxFX0FGVEVSX0RPV05MT0FEX0VSUk9SKDMyMCksCisKKyAgICAvLyBEb3dubG9hZCBlcnJvcnMgcmVsYXRlZCB0byBpc29sYXRlZCBmaWxlIHN0cnVjdHVyZQorICAgIFVOQUJMRV9UT19SRU1PVkVfU1lNTElOS19TVFJVQ1RVUkUoMzIxKSwKKyAgICBVTkFCTEVfVE9fQ1JFQVRFX1NZTUxJTktfU1RSVUNUVVJFKDMyMiksCisKKyAgICAvLyBEb3dubG9hZCBlcnJvcnMgcmVsYXRlZCB0byBpbXBvcnRpbmcgaW5saW5lIGZpbGVzCisgICAgLy8gRmFpbGVkIHRvIHJlc2VydmUgZmlsZSBlbnRyaWVzCisgICAgVU5BQkxFX1RPX1JFU0VSVkVfRklMRV9FTlRSWSgzMjMpLAorICAgIC8vIEludmFsaWQgdXNlIG9mIGlubGluZWZpbGUgdXJsIHNjaGVtZQorICAgIElOVkFMSURfSU5MSU5FX0ZJTEVfVVJMX1NDSEVNRSgzMjQpLAorICAgIC8vIEVycm9yIHBlcmZvcm1pbmcgaW5saW5lIGZpbGUgZG93bmxvYWQKKyAgICBJTkxJTkVfRklMRV9JT19FUlJPUigzMjcpLAorICAgIC8vIE1pc3NpbmcgcmVxdWlyZWQgaW5saW5lIGRvd25sb2FkIHBhcm1zIGluIEZpbGVEb3dubG9hZGVyJ3MgRG93bmxvYWRSZXF1ZXN0CisgICAgTUlTU0lOR19JTkxJTkVfRE9XTkxPQURfUEFSQU1TKDMyOCksCisgICAgLy8gTWlzc2luZyByZXF1aXJlZCBpbmxpbmUgZmlsZSBzb3VyY2UgaW4gSW1wb3J0RmlsZXNSZXF1ZXN0CisgICAgTUlTU0lOR19JTkxJTkVfRklMRV9TT1VSQ0UoMzI5KSwKKworICAgIC8vIERvd25sb2FkIGVycm9ycyByZWxhdGVkIHRvIFVSTCBwYXJzaW5nCisgICAgTUFMRk9STUVEX0RPV05MT0FEX1VSTCgzMjUpLAorICAgIFVOU1VQUE9SVEVEX0RPV05MT0FEX1VSTF9TQ0hFTUUoMzI2KSwKKworICAgIC8vIERvd25sb2FkIGVycm9ycyBmb3IgbWFuaWZlc3QgZmlsZSBncm91cCBwb3B1bGF0b3IuCisgICAgTUFOSUZFU1RfRklMRV9HUk9VUF9QT1BVTEFUT1JfSU5WQUxJRF9GTEFHX0VSUk9SKDQwMCksCisgICAgTUFOSUZFU1RfRklMRV9HUk9VUF9QT1BVTEFUT1JfQ09OVEVOVF9DSEFOR0VEX0RVUklOR19ET1dOTE9BRF9FUlJPUig0MDEpLAorICAgIE1BTklGRVNUX0ZJTEVfR1JPVVBfUE9QVUxBVE9SX1BBUlNFX01BTklGRVNUX0ZJTEVfRVJST1IoNDAyKSwKKyAgICBNQU5JRkVTVF9GSUxFX0dST1VQX1BPUFVMQVRPUl9ERUxFVEVfTUFOSUZFU1RfRklMRV9FUlJPUig0MDMpLAorICAgIE1BTklGRVNUX0ZJTEVfR1JPVVBfUE9QVUxBVE9SX01FVEFEQVRBX0lPX0VSUk9SKDQwNCksCisKKyAgICAvLyBHREQgc3BlY2lmaWMgZG93bmxvYWQgZXJyb3JzLCByZXNlcnZlZCBmcm9tIDIwMDAtMjk5OS4KKyAgICBHRERfSU5WQUxJRF9BQ0NPVU5UKDIwMDApLAorICAgIEdERF9JTlZBTElEX0FVVEhfVE9LRU4oMjAwMSksCisgICAgR0REX0ZBSUxfSU5fU1lOQ19SVU5ORVIoMjAwMiksCisgICAgR0REX0lOVkFMSURfRUxFTUVOVF9DT01CSU5BVElPTl9SRUNFSVZFRCgyMDAzKSwKKyAgICBHRERfSU5WQUxJRF9JTkxJTkVfUEFZTE9BRF9FTEVNRU5UX0RBVEEoMjAwNCksCisgICAgR0REX0lOVkFMSURfQ1VSUkVOVF9BQ1RJVkVfRUxFTUVOVF9EQVRBKDIwMDUpLAorICAgIEdERF9JTlZBTElEX05FWFRfUEVORElOR19FTEVNRU5UX0RBVEEoMjAwNiksCisgICAgR0REX0NVUlJFTlRfQUNUSVZFX0dST1VQX0hBU19OT19JTkxJTkVfRklMRSgyMDA3KSwKKyAgICBHRERfRkFJTF9UT19BRERfTkVYVF9QRU5ESU5HX0dST1VQKDIwMDgpLAorICAgIEdERF9NSVNTSU5HX0FDQ09VTlRfRk9SX1BSSVZBVEVfU1lOQygyMDA5KSwKKyAgICBHRERfRkFJTF9JTl9TWU5DX1JVTk5FUl9QVUJMSUMoMjAxMCksCisgICAgR0REX0ZBSUxfSU5fU1lOQ19SVU5ORVJfUFJJVkFURSgyMDExKSwKKyAgICBHRERfUFVCTElDX1NZTkNfU1VDQ0VTUygyMDEyKSwKKyAgICBHRERfUFJJVkFURV9TWU5DX1NVQ0NFU1MoMjAxMyksCisgICAgR0REX0ZBSUxfVE9fUkVUUklFVkVfWldJRUJBQ0tfVE9LRU4oMjAxNCk7CisKKyAgICBwcml2YXRlIGZpbmFsIGludCBjb2RlOworCisgICAgRG93bmxvYWRSZXN1bHRDb2RlKGludCBjb2RlKSB7CisgICAgICB0aGlzLmNvZGUgPSBjb2RlOworICAgIH0KKworICAgIC8qKiBSZXR1cm5zIHRoZSBpbnQgY29kZSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgZW51bSB2YWx1ZS4gKi8KKyAgICBwdWJsaWMgaW50IGdldENvZGUoKSB7CisgICAgICByZXR1cm4gY29kZTsKKyAgICB9CisgIH0KKyAgLy8gTElOVC5UaGVuQ2hhbmdlKDxpbnRlcm5hbD4pCisKKyAgLyoqIEJ1aWxkZXIgZm9yIHtAbGluayBEb3dubG9hZEV4Y2VwdGlvbn0uICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciB7CisgICAgcHJpdmF0ZSBEb3dubG9hZFJlc3VsdENvZGUgZG93bmxvYWRSZXN1bHRDb2RlOworICAgIHByaXZhdGUgU3RyaW5nIG1lc3NhZ2U7CisgICAgcHJpdmF0ZSBUaHJvd2FibGUgY2F1c2U7CisKKyAgICAvKiogU2V0cyB0aGUge0BsaW5rIERvd25sb2FkUmVzdWx0Q29kZX0uICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZSBkb3dubG9hZFJlc3VsdENvZGUpIHsKKyAgICAgIHRoaXMuZG93bmxvYWRSZXN1bHRDb2RlID0gZG93bmxvYWRSZXN1bHRDb2RlOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqIFNldHMgdGhlIGVycm9yIG1lc3NhZ2UuICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0TWVzc2FnZShTdHJpbmcgbWVzc2FnZSkgeworICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKiBTZXRzIHRoZSBjYXVzZSBvZiB0aGUgZXhjZXB0aW9uLiAqLworICAgIHB1YmxpYyBCdWlsZGVyIHNldENhdXNlKFRocm93YWJsZSBjYXVzZSkgeworICAgICAgdGhpcy5jYXVzZSA9IGNhdXNlOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqIFJldHVybnMgYSB7QGxpbmsgRG93bmxvYWRFeGNlcHRpb259IGluc3RhbmNlLiAqLworICAgIHB1YmxpYyBEb3dubG9hZEV4Y2VwdGlvbiBidWlsZCgpIHsKKyAgICAgIFByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKGRvd25sb2FkUmVzdWx0Q29kZSk7CisgICAgICBpZiAobWVzc2FnZSA9PSBudWxsKSB7CisgICAgICAgIG1lc3NhZ2UgPSAiRG93bmxvYWQgcmVzdWx0IGNvZGU6ICIgKyBkb3dubG9hZFJlc3VsdENvZGUubmFtZSgpOworICAgICAgfQorICAgICAgcmV0dXJuIG5ldyBEb3dubG9hZEV4Y2VwdGlvbih0aGlzKTsKKyAgICB9CisgIH0KKworICAvKiogUmV0dXJucyBhIEJ1aWxkZXIgZm9yIHtAbGluayBEb3dubG9hZEV4Y2VwdGlvbn0uICovCisgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBidWlsZGVyKCkgeworICAgIHJldHVybiBuZXcgQnVpbGRlcigpOworICB9CisKKyAgcHVibGljIERvd25sb2FkUmVzdWx0Q29kZSBnZXREb3dubG9hZFJlc3VsdENvZGUoKSB7CisgICAgcmV0dXJuIGRvd25sb2FkUmVzdWx0Q29kZTsKKyAgfQorCisgIC8qKgorICAgKiBXcmFwcyB0aGUgdGhyb3dhYmxlIHdpdGgge0BsaW5rIERvd25sb2FkRXhjZXB0aW9ufSBhbmQgcmV0dXJucyBhIGZhaWxlZCBmdXR1cmUgb25seSBpZiB0aGUKKyAgICogaW5wdXQgZnV0dXJlIGZhaWxzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyA8VD4gTGlzdGVuYWJsZUZ1dHVyZTxUPiB3cmFwSWZGYWlsZWQoCisgICAgICBMaXN0ZW5hYmxlRnV0dXJlPFQ+IGZ1dHVyZSwgRG93bmxvYWRSZXN1bHRDb2RlIGNvZGUsIFN0cmluZyBtZXNzYWdlKSB7CisgICAgcmV0dXJuIEZ1dHVyZXMuY2F0Y2hpbmdBc3luYygKKyAgICAgICAgZnV0dXJlLAorICAgICAgICBUaHJvd2FibGUuY2xhc3MsCisgICAgICAgIChUaHJvd2FibGUgdCkgLT4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKHdyYXAodCwgY29kZSwgbWVzc2FnZSkpLAorICAgICAgICBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCkpOworICB9CisKKyAgLyoqIFdyYXBzIHRoZSB0aHJvd2FibGUgd2l0aCB7QGxpbmsgRG93bmxvYWRFeGNlcHRpb259LiAqLworICBwcml2YXRlIHN0YXRpYyBEb3dubG9hZEV4Y2VwdGlvbiB3cmFwKAorICAgICAgVGhyb3dhYmxlIHRocm93YWJsZSwgRG93bmxvYWRSZXN1bHRDb2RlIGNvZGUsIFN0cmluZyBtZXNzYWdlKSB7CisgICAgcmV0dXJuIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKGNvZGUpCisgICAgICAgIC5zZXRNZXNzYWdlKG1lc3NhZ2UpCisgICAgICAgIC5zZXRDYXVzZSh0aHJvd2FibGUpCisgICAgICAgIC5idWlsZCgpOworICB9CisKKyAgcHJpdmF0ZSBEb3dubG9hZEV4Y2VwdGlvbihCdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICBzdXBlcihidWlsZGVyLm1lc3NhZ2UsIGJ1aWxkZXIuY2F1c2UpOworICAgIHRoaXMuZG93bmxvYWRSZXN1bHRDb2RlID0gYnVpbGRlci5kb3dubG9hZFJlc3VsdENvZGU7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0LmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiOTg1MjcKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5qYXZhCkBAIC0wLDAgKzEsMTU5IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZDsKKworaW1wb3J0IGFuZHJvaWQuYWNjb3VudHMuQWNjb3VudDsKK2ltcG9ydCBjb20uZ29vZ2xlLmF1dG8udmFsdWUuQXV0b1ZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5Eb3dubG9hZENvbmRpdGlvbnM7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5jb25jdXJyZW50LkltbXV0YWJsZTsKKworLyoqIFJlcXVlc3QgdG8gZG93bmxvYWQgZmlsZSBncm91cCBpbiBNREQuICovCitAQXV0b1ZhbHVlCitASW1tdXRhYmxlCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0IHsKKworICAvKiogRGVmaW5lcyBub3RpZmljdGlvbiBiZWhhdmlvciBmb3IgZm9yZWdyb3VuZCBkb3dubG9hZCByZXF1ZXN0cy4gKi8KKyAgLy8gTElOVC5JZkNoYW5nZShzaG93X25vdGlmaWNhdGlvbnMpCisgIHB1YmxpYyBlbnVtIFNob3dOb3RpZmljYXRpb25zIHsKKyAgICBOT05FLAorICAgIEFMTCwKKyAgfQorICAvLyBMSU5ULlRoZW5DaGFuZ2UoPGludGVybmFsPikKKworICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QoKSB7fQorCisgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgZ3JvdXBOYW1lKCk7CisKKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPEFjY291bnQ+IGFjY291bnRPcHRpb25hbCgpOworCisgIHB1YmxpYyBhYnN0cmFjdCBPcHRpb25hbDxTdHJpbmc+IHZhcmlhbnRJZE9wdGlvbmFsKCk7CisKKyAgLyoqCisgICAqIElmIHByZXNlbnQsIHRpdGxlIHRleHQgdG8gZGlzcGxheSBpbiBub3RpZmljYXRpb24gd2hlbiB1c2luZyBmb3JlZ3JvdW5kIGRvd25sb2Fkcy4gT3RoZXJ3aXNlLAorICAgKiB0aGUgZmlsZSBncm91cCBuYW1lIHdpbGwgYmUgdXNlZC4KKyAgICoKKyAgICogPHA+U2VlIDxpbnRlcm5hbD4gZm9yIGFuIGV4YW1wbGUgb2YgdGhlIG5vdGlmaWNhdGlvbi4KKyAgICovCisgIHB1YmxpYyBhYnN0cmFjdCBPcHRpb25hbDxTdHJpbmc+IGNvbnRlbnRUaXRsZU9wdGlvbmFsKCk7CisKKyAgLyoqCisgICAqIElmIHByZXNlbnQsIGNvbnRlbnQgdGV4dCB0byBkaXNwbGF5IGluIG5vdGlmaWNhdGlvbiB3aGVuIHVzaW5nIGZvcmVncm91bmQgZG93bmxvYWRzLiBPdGhlcndpc2UsCisgICAqIHRoZSBmaWxlIGdyb3VwIG5hbWUgd2lsbCBiZSB1c2VkLgorICAgKgorICAgKiA8cD5TZWUgPGludGVybmFsPiBmb3IgYW4gZXhhbXBsZSBvZiB0aGUgbm90aWZpY2F0aW9uLgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPFN0cmluZz4gY29udGVudFRleHRPcHRpb25hbCgpOworCisgIC8qKgorICAgKiBUaGUgY29uZGl0aW9ucyBmb3IgdGhlIGRvd25sb2FkLiBJZiBhYnNlbnQsIE1ERCB3aWxsIHVzZSB0aGUgZG93bmxvYWQgY29uZGl0aW9ucyBmcm9tIHRoZQorICAgKiBzZXJ2ZXIgY29uZmlnLgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPERvd25sb2FkQ29uZGl0aW9ucz4gZG93bmxvYWRDb25kaXRpb25zT3B0aW9uYWwoKTsKKworICAvKiogSWYgcHJlc2VudCwgd2lsbCByZWNlaXZlIGRvd25sb2FkIHByb2dyZXNzIHVwZGF0ZS4gKi8KKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPERvd25sb2FkTGlzdGVuZXI+IGxpc3RlbmVyT3B0aW9uYWwoKTsKKworICAvLyBUaGUgc2l6ZSBvZiB0aGUgYmVpbmcgZG93bmxvYWRlZCBmaWxlIGluIGJ5dGVzLgorICAvLyBUaGlzIGlzIHVzZWQgdG8gZGlzcGxheSB0aGUgcHJvZ3Jlc3NiYXIuCisgIC8vIElmIG5vdCBzcGVjaWZpZWQsIGFuIGluZGV0ZXJtaW5hdGUgcHJvZ3Jlc3NiYXIgd2lsbCBiZSBkaXNwbGF5ZWQuCisgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3JlZmVyZW5jZS9hbmRyb2lkL2FwcC9Ob3RpZmljYXRpb24uQnVpbGRlci5odG1sI3NldFByb2dyZXNzKGludCwlMjBpbnQsJTIwYm9vbGVhbikKKyAgcHVibGljIGFic3RyYWN0IGludCBncm91cFNpemVCeXRlcygpOworCisgIC8qKgorICAgKiBJZiB7QGxpbmsgU2hvd05vdGlmaWNhdGlvbnMuTk9ORX0sIHdpbGwgbm90IGNyZWF0ZSBub3RpZmljYXRpb25zIGZvciB0aGlzIGZvcmVncm91bmQgZG93bmxvYWQKKyAgICogcmVxdWVzdC4KKyAgICovCisgIHB1YmxpYyBhYnN0cmFjdCBTaG93Tm90aWZpY2F0aW9ucyBzaG93Tm90aWZpY2F0aW9ucygpOworCisgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHByZXNlcnZlWmlwRGlyZWN0b3JpZXMoKTsKKworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEF1dG9WYWx1ZV9Eb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuQnVpbGRlcigpCisgICAgICAgIC5zZXRHcm91cFNpemVCeXRlcygwKQorICAgICAgICAuc2V0U2hvd05vdGlmaWNhdGlvbnMoU2hvd05vdGlmaWNhdGlvbnMuQUxMKQorICAgICAgICAuc2V0UHJlc2VydmVaaXBEaXJlY3RvcmllcyhmYWxzZSk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdH0uICovCisgIEBBdXRvVmFsdWUuQnVpbGRlcgorICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEJ1aWxkZXIgeworICAgIEJ1aWxkZXIoKSB7fQorCisgICAgLyoqIFNldHMgdGhlIG5hbWUgb2YgdGhlIGZpbGUgZ3JvdXAuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0R3JvdXBOYW1lKFN0cmluZyBncm91cE5hbWUpOworCisgICAgLyoqIFNldHMgdGhlIG9wdGlvbmFsIGFjY291bnQgdGhhdCBpcyBhc3NvY2lhdGVkIHRvIHRoZSBmaWxlIGdyb3VwLiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldEFjY291bnRPcHRpb25hbChPcHRpb25hbDxBY2NvdW50PiBhY2NvdW50T3B0aW9uYWwpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgdmFyaWFudCBpZCB0aGF0IGlzIGFzc29jaWF0ZWQgdG8gdGhlIGZpbGUgZ3JvdXAuCisgICAgICoKKyAgICAgKiA8cD5UaGlzIHBhcmFtZXRlciBpcyBvbmx5IHJlcXVpcmVkIHRvIGRvd25sb2FkIGEgZ3JvdXAgdGhhdCB3YXMgYWRkZWQgdG8gTUREIHdpdGggYSB2YXJpYW50SWQKKyAgICAgKiBzcGVjaWZpZWQgKHNlZSB7QGxpbmsgQWRkRmlsZUdyb3VwUmVxdWVzdC5CdWlsZGVyI3NldFZhcmlhbnRJZE9wdGlvbmFsfSkuCisgICAgICoKKyAgICAgKiA8cD5JZiBhIHZhcmlhbnRJZCB3YXMgc3BlY2lmaWVkIHdoZW4gYWRkaW5nIHRoZSBncm91cCB0byBNREQgYW5kIGlzIG5vdCBpbmNsdWRlZCBoZXJlLCB0aGUKKyAgICAgKiByZXF1ZXN0IHdpbGwgZmFpbCB3aXRoIGEge0BsaW5rIERvd25sb2FkRXhjZXB0aW9ufSBhbmQgYSBHUk9VUF9OT1RfRk9VTkQgcmVzdWx0IGNvZGUuCisgICAgICoKKyAgICAgKiA8cD5TaW1pbGFybHksIGlmIGEgdmFyaWFudElkIHdhcyA8ZW0+bm90PC9lbT4gc3BlY2lmaWVkIHdoZW4gYWRkaW5nIHRoZSBncm91cCB0byBNREQgYW5kCisgICAgICogPGVtPmlzPC9lbT4gaW5jbHVkZWQgaGVyZSwgdGhlIHJlcXVlc3Qgd2lsbCBhbHNvIGZhaWwgd2l0aCB0aGUgc2FtZSBleGNlcHRpb24uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0VmFyaWFudElkT3B0aW9uYWwoT3B0aW9uYWw8U3RyaW5nPiB2YXJpYW50SWRPcHRpb25hbCk7CisKKyAgICAvKiogU2V0cyB0aGUgb3B0aW9uYWwgdGl0bGUgdGV4dCBmb3IgYSBub3RpZmljYXRpb24gd2hlbiB1c2luZyBmb3JlZ3JvdW5kIGRvd25sb2Fkcy4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRDb250ZW50VGl0bGVPcHRpb25hbChPcHRpb25hbDxTdHJpbmc+IGNvbnRlbnRUaXRsZU9wdGlvbmFsKTsKKworICAgIC8qKiBTZXRzIHRoZSBvcHRpb25hbCBjb250ZW50IHRleHQgZm9yIGEgbm90aWZpY2F0aW9uIHdoZW4gdXNpbmcgZm9yZWdyb3VuZCBkb3dubG9hZHMuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0Q29udGVudFRleHRPcHRpb25hbChPcHRpb25hbDxTdHJpbmc+IGNvbnRlbnRUZXh0T3B0aW9uYWwpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgb3B0aW9uYWwgZG93bmxvYWQgY29uZGl0aW9ucy4gSWYgYWJzZW50LCBNREQgd2lsbCB1c2UgdGhlIGRvd25sb2FkIGNvbmRpdGlvbnMgZnJvbQorICAgICAqIHRoZSBzZXJ2ZXIgY29uZmlnLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldERvd25sb2FkQ29uZGl0aW9uc09wdGlvbmFsKAorICAgICAgICBPcHRpb25hbDxEb3dubG9hZENvbmRpdGlvbnM+IGRvd25sb2FkQ29uZGl0aW9uc09wdGlvbmFsKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG9wdGlvbmFsIGRvd25sb2FkIGxpc3RlbmVyIHdoZW4gdXNpbmcgZm9yZWdyb3VuZCBkb3dubG9hZHMuIElmIHByZXNlbnQsIHdpbGwgcmVjZWl2ZQorICAgICAqIGRvd25sb2FkIHByb2dyZXNzIHVwZGF0ZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRMaXN0ZW5lck9wdGlvbmFsKE9wdGlvbmFsPERvd25sb2FkTGlzdGVuZXI+IGxpc3RlbmVyT3B0aW9uYWwpOworCisgICAgLyoqCisgICAgICogU2V0cyBzaXplIG9mIHRoZSBiZWluZyBkb3dubG9hZGVkIGdyb3VwIGluIGJ5dGVzIHdoZW4gdXNpbmcgZm9yZWdyb3VuZCBkb3dubG9hZHMuIFRoaXMgaXMKKyAgICAgKiB1c2VkIHRvIGRpc3BsYXkgdGhlIHByb2dyZXNzYmFyLiBJZiBub3Qgc3BlY2lmaWVkLCBhIGluZGV0ZXJtaW5hdGUgcHJvZ3Jlc3NiYXIgd2lsbCBiZQorICAgICAqIGRpc3BsYXllZC4KKyAgICAgKiBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC9hcHAvTm90aWZpY2F0aW9uLkJ1aWxkZXIuaHRtbCNzZXRQcm9ncmVzcyhpbnQsJTIwaW50LCUyMGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0R3JvdXBTaXplQnl0ZXMoaW50IGdyb3VwU2l6ZUJ5dGVzKTsKKworICAgIC8qKgorICAgICAqIENvbnRyb2xzIGlmIG5vdGlmaWNhdGlvbnMgc2hvdWxkIGJlIGNyZWF0ZWQgZm9yIHRoaXMgZG93bmxvYWQgcmVxdWVzdCB3aGVuIHVzaW5nIGZvcmVncm91bmQKKyAgICAgKiBkb3dubG9hZHMuIERlZmF1bHRzIHRvIHRydWUuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0U2hvd05vdGlmaWNhdGlvbnMoU2hvd05vdGlmaWNhdGlvbnMgbm90aWZpY2F0aW9ucyk7CisKKyAgICAvKioKKyAgICAgKiBCeSBkZWZhdWx0LCBNREQgd2lsbCBzY2FuIHRoZSBkaXJlY3RvcmllcyBnZW5lcmF0ZWQgYnkgdW5wYWNraW5nIHppcCBmaWxlcyBpbiBhIGRvd25sb2FkCisgICAgICogdHJhbnNmb3JtIGFuZCBnZW5lcmF0ZSBhIENsaWVudERhdGFGaWxlIGZvciBlYWNoIGNvbnRhaW5lZCBmaWxlLiBCeSBkZWZhdWx0LCBNREQgYWxzbyBoaWRlcworICAgICAqIHRoZSByb290IGRpcmVjdG9yeS4gU2V0dGluZyB0aGlzIHRvIHRydWUgZGlzYWJsZXMgdGhhdCBiZWhhdmlvciwgYW5kIHdpbGwgc2ltcGx5IHJldHVybiB0aGUKKyAgICAgKiBkaXJlY3RvcmllcyBhcyBDbGllbnREYXRhRmlsZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0UHJlc2VydmVaaXBEaXJlY3Rvcmllcyhib29sZWFuIHByZXNlcnZlKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QgYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Eb3dubG9hZExpc3RlbmVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkTGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNDA0MDZkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Eb3dubG9hZExpc3RlbmVyLmphdmEKQEAgLTAsMCArMSw2MCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuQ2xpZW50Q29uZmlnUHJvdG8uQ2xpZW50RmlsZUdyb3VwOworCisvKioKKyAqIFN1cHBvcnRzIHJlZ2lzdGVyaW5nIGZvciBkb3dubG9hZCBwcm9ncmVzcyB1cGRhdGUuCisgKgorICogPHA+SW4gZ2VuZXJhbCwgZG9uJ3QgZG8gYW55dGhpbmcgaGVhdnkgb24gb25Qcm9ncmVzcyBhbmQgb25Db21wbGV0ZSBzaW5jZSBpdCBpcyBydW5uaW5nIG8KKyAqLworcHVibGljIGludGVyZmFjZSBEb3dubG9hZExpc3RlbmVyIHsKKyAgU3RyaW5nIFRBRyA9ICJEb3dubG9hZExpc3RlbmVyIjsKKworICAvKioKKyAgICogV2lsbCBiZSB0cmlnZ2VyZWQgcGVyaW9kaWNhbGx5IHdpdGggdGhlIGN1cnJlbnQgZG93bmxvYWRlZCBzaXplIG9mIHRoZSBmaWxlIGdyb3VwLiBUaGlzIGNvdWxkCisgICAqIGJlIHVzZWQgdG8gc2hvdyBwcm9ncmVzc2JhciB0byB1c2Vycy4KKyAgICoKKyAgICogPHA+VGhlIG9uUHJvZ3Jlc3MgaXMgcnVuIG9uIE1ERCBEb3dubG9hZCBFeGVjdXRvci4gSWYgeW91IG5lZWQgdG8gZG8gaGVhdnkgd29yaywgcGxlYXNlIG9mZmxvYWQKKyAgICogdG8gYSBiYWNrZ3JvdW5kIHRhc2suCisgICAqLworICAvLyBUT0RPKGIvMTI5NDY0ODk3KTogbWFrZSBvblByb2dyZXNzIHJ1biBvbiBjb250cm9sIGV4ZWN1dG9yLgorICB2b2lkIG9uUHJvZ3Jlc3MobG9uZyBjdXJyZW50U2l6ZSk7CisKKyAgLyoqCisgICAqIFRoaXMgd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgZG93bmxvYWQgaXMgY29tcGxldGVkLiBUaGUgY2xpZW50RmlsZUdyb3VwIGhhcyBkYXRhIGFib3V0IHRoZQorICAgKiBkb3dubG9hZGVkIGZpbGUgZ3JvdXAuCisgICAqCisgICAqIDxwPlRoZSBvbkNvbXBsZXRlIGlzIHJ1biBvbiBNREQgQ29udHJvbCBFeGVjdXRvci4gSWYgeW91IG5lZWQgdG8gZG8gaGVhdnkgd29yaywgcGxlYXNlIG9mZmxvYWQKKyAgICogdG8gYSBiYWNrZ3JvdW5kIHRhc2suCisgICAqLworICB2b2lkIG9uQ29tcGxldGUoQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCk7CisKKyAgLyoqIFRoaXMgd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgZG93bmxvYWQgZmFpbGVkLiAqLworICBkZWZhdWx0IHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KSB7CisgICAgTG9nVXRpbC5lKHQsICIlczogb25GYWlsdXJlIiwgVEFHKTsKKyAgfQorCisgIC8qKgorICAgKiBDYWxsYmFjayB0cmlnZ2VyZWQgd2hlbiBhbGwgZG93bmxvYWRzIGFyZSBpbiBhIHN0YXRlIHdhaXRpbmcgZm9yIGNvbm5lY3Rpdml0eSwgYW5kIG5vIGRvd25sb2FkCisgICAqIHByb2dyZXNzIGlzIGhhcHBlbmluZyB1bnRpbCBjb25uZWN0aXZpdHkgcmVzdW1lcy4KKyAgICovCisgIGRlZmF1bHQgdm9pZCBwYXVzZWRGb3JDb25uZWN0aXZpdHkoKSB7CisgICAgTG9nVXRpbC5kKCIlczogcGF1c2VkRm9yQ29ubmVjdGl2aXR5IiwgVEFHKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9FeHBlcmltZW50YXRpb25Db25maWcuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvRXhwZXJpbWVudGF0aW9uQ29uZmlnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWI2MTQ4YgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvRXhwZXJpbWVudGF0aW9uQ29uZmlnLmphdmEKQEAgLTAsMCArMSw3MiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmF1dG8udmFsdWUuQXV0b1ZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5lcnJvcnByb25lLmFubm90YXRpb25zLkNoZWNrUmV0dXJuVmFsdWU7CisKKy8qKiBDb25maWd1cmF0aW9uIHZhbHVlcyBmb3IgZXhwZXJpbWVudGF0aW9uIGluIE1ERC4gKi8KK0BDaGVja1JldHVyblZhbHVlCitAQXV0b1ZhbHVlCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRXhwZXJpbWVudGF0aW9uQ29uZmlnIHsKKworICAvKioKKyAgICogUmV0dXJucyB0aGUgbG9nIHNvdXJjZSB0byB3aGljaCBkb3dubG9hZCBzdGFnZSBleHBlcmltZW50IElEUyB3aWxsIGJlIGFkZGVkIGFzIGV4dGVybmFsCisgICAqIGV4cGVyaW1lbnQgSURzLgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPFN0cmluZz4gZ2V0SG9zdEFwcExvZ1NvdXJjZSgpOworCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSBwcmltZXMgbG9nIHNvdXJjZSB0byB3aGljaCBkb3dubG9hZCBzdGFnZSBleHBlcmltZW50IElEcyB3aWxsIGJlIGFkZGVkIGFzIGV4dGVybmFsCisgICAqIGV4cGVyaW1lbnQgSURzLiBUaGlzIHdpbGwgYWxsb3cgc2xpY2luZyBwcmltZXMgbWV0cmljcyB0byBNREQgcm9sbG91dHMuCisgICAqLworICBwdWJsaWMgYWJzdHJhY3QgT3B0aW9uYWw8U3RyaW5nPiBnZXRQcmltZXNMb2dTb3VyY2UoKTsKKworICAvLyBUT0RPKGIvMjAxNDYzODAzKTogYWRkIHBlci1maWxlLWdyb3VwIG92ZXJyaWRlcy4KKworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgYnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEF1dG9WYWx1ZV9FeHBlcmltZW50YXRpb25Db25maWcuQnVpbGRlcigpOworICB9CisKKyAgLyoqIEJ1aWxkZXIgZm9yIEV4cGVyaW1lbnRhdGlvbkNvbmZpZy4gKi8KKyAgQEF1dG9WYWx1ZS5CdWlsZGVyCisgIHB1YmxpYyBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgQnVpbGRlciB7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBob3N0IGFwcCBsb2cgc291cmNlLiBEb3dubG9hZCBzdGFnZSBleHBlcmltZW50IGlkcyB3aWxsIGJlIGFkZGVkIGFzIGV4dGVybmFsCisgICAgICogZXhwZXJpbWVudCBpZHMgdG8gdGhpcyBsb2cgc291cmNlLgorICAgICAqCisgICAgICogPHA+T3B0aW9uYWwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gaG9zdEFwcExvZ1NvdXJjZSB0aGUgbmFtZSBvZiB0aGUgaG9zdCBhcHAgbG9nIHNvdXJjZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRIb3N0QXBwTG9nU291cmNlKFN0cmluZyBob3N0QXBwTG9nU291cmNlKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGhvc3QgYXBwIHByaW1lcyBsb2cgc291cmNlLiBEb3dubG9hZCBzdGFnZSBleHBlcmltZW50IGlkcyB3aWxsIGJlIGFkZGVkIGFzIGV4dGVybmFsCisgICAgICogZXhwZXJpbWVudCBpZHMgdG8gdGhpcyBsb2cgc291cmNlLiBUaGlzIHdpbGwgYWxsb3cgc2xpY2luZyBwcmltZXMgbWV0cmljcyB0byBNREQgcm9sbCBvdXRzLgorICAgICAqIFNlZSA8aW50ZXJuYWw+IGZvciBtb3JlIGRldGFpbHMuCisgICAgICoKKyAgICAgKiA8cD5PcHRpb25hbC4KKyAgICAgKgorICAgICAqIEBwYXJhbSBwcmltZXNMb2dTb3VyY2UgdGhlIG5hbWUgb2YgdGhlIHByaW1lcyBsb2cgc291cmNlCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0UHJpbWVzTG9nU291cmNlKFN0cmluZyBwcmltZXNMb2dTb3VyY2UpOworCisgICAgcHVibGljIGFic3RyYWN0IEV4cGVyaW1lbnRhdGlvbkNvbmZpZyBidWlsZCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0ZpbGVHcm91cFBvcHVsYXRvci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9GaWxlR3JvdXBQb3B1bGF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZGNjZDg3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9GaWxlR3JvdXBQb3B1bGF0b3IuamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZDsKKworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworCisvKioKKyAqIFBvcHVsYXRlcyBNREQgd2l0aCBmaWxlIGdyb3VwcyBmcm9tIG11bHRpcGxlIHNvdXJjZXMgbGlrZSBwaGVub3R5cGUgb3IgYnVpbHQgb24gdGhlIGRldmljZS4KKyAqCisgKiA8cD5DbGllbnRzIG11c3Qgb3ZlcnJpZGVzIHRoZSByZWZyZXNoRmlsZUdyb3VwcyBtZXRob2QgYW5kIGFkZCBncm91cHMgdG8ge0BsaW5rCisgKiBNb2JpbGVEYXRhRG93bmxvYWQjYWRkRmlsZUdyb3VwKEFkZEZpbGVHcm91cFJlcXVlc3QpfSBpbiB0aGUgaW1wbC4KKyAqLworcHVibGljIGludGVyZmFjZSBGaWxlR3JvdXBQb3B1bGF0b3IgeworCisgIC8qKgorICAgKiBDYWxsZWQgcGVyaW9kaWNhbGx5IGJ5IE1ERCB0byByZWZyZXNoIGZpbGUgZ3JvdXBzLgorICAgKgorICAgKiA8cD5UaGlzIGdyb3VwIHNob3VsZCBpZGVhbGx5IGJlIHJlYWRpbmcgZnJvbSBhIHNvdXJjZSBsaWtlIHBoZW5vdHlwZSwgc28gdGhhdCBtZGQgZ2V0cyB0aGUKKyAgICogdXBkYXRlcyBmcm9tIHRoZXJlIG9uIGEgcmVndWxhciBiYXNpcy4KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVmcmVzaEZpbGVHcm91cHMoTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0ZpbGVTb3VyY2UuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvRmlsZVNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5NWJjY2EKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0ZpbGVTb3VyY2UuamF2YQpAQCAtMCwwICsxLDEzNiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5jb25jdXJyZW50LkltbXV0YWJsZTsKKworLyoqIEVpdGhlciBhIFVSSSBvciBhIEJ5dGVTdHJpbmcuICovCisvLyBUT0RPKGIvMjE5NzY1MDQ4KSB1c2UgQXV0b09uZU9mIG9uY2UgdGhhdCdzIGF2YWlsYWJsZSBpbiBBbmRyb2lkCitASW1tdXRhYmxlCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRmlsZVNvdXJjZSB7CisgIC8qKiBUaGUgcG9zc2libGUgdHlwZXMgb2Ygc291cmNlLiAqLworICBwdWJsaWMgZW51bSBLaW5kIHsKKyAgICBCWVRFU1RSSU5HLAorICAgIFVSSQorICB9CisKKyAgLyoqIFRoZSB0eXBlIG9mIHRoaXMgc291cmNlLiAqLworICBwdWJsaWMgYWJzdHJhY3QgS2luZCBnZXRLaW5kKCk7CisKKyAgcHVibGljIGFic3RyYWN0IEJ5dGVTdHJpbmcgYnl0ZVN0cmluZygpOworCisgIHB1YmxpYyBhYnN0cmFjdCBVcmkgdXJpKCk7CisKKyAgLyoqIENyZWF0ZSBhIEZpbGVTb3VyY2UgZnJvbSBhIEJ5dGVTdHJpbmcuICovCisgIHB1YmxpYyBzdGF0aWMgRmlsZVNvdXJjZSBvZkJ5dGVTdHJpbmcoQnl0ZVN0cmluZyBieXRlU3RyaW5nKSB7CisgICAgaWYgKGJ5dGVTdHJpbmcgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgfQorICAgIHJldHVybiBuZXcgSW1wbEJ5dGVTdHJpbmcoYnl0ZVN0cmluZyk7CisgIH0KKworICAvKiogQ3JlYXRlIGEgRmlsZVNvdXJjZSBmcm9tIGEgVVJJLiAqLworICBwdWJsaWMgc3RhdGljIEZpbGVTb3VyY2Ugb2ZVcmkoVXJpIHVyaSkgeworICAgIGlmICh1cmkgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CisgICAgfQorICAgIHJldHVybiBuZXcgSW1wbFVyaSh1cmkpOworICB9CisKKyAgLy8gUGFyZW50IGNsYXNzIHRoYXQgZWFjaCBpbXBsZW1lbnRhdGlvbiB3aWxsIGluaGVyaXQgZnJvbS4KKyAgcHJpdmF0ZSBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgUGFyZW50IGV4dGVuZHMgRmlsZVNvdXJjZSB7CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEJ5dGVTdHJpbmcgYnl0ZVN0cmluZygpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbihnZXRLaW5kKCkudG9TdHJpbmcoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFVyaSB1cmkoKSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oZ2V0S2luZCgpLnRvU3RyaW5nKCkpOworICAgIH0KKyAgfQorCisgIC8vIEltcGxlbWVudGF0aW9uIHdoZW4gdGhlIGNvbnRhaW5lZCBwcm9wZXJ0eSBpcyAiYnl0ZVN0cmluZyIuCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEltcGxCeXRlU3RyaW5nIGV4dGVuZHMgUGFyZW50IHsKKyAgICBwcml2YXRlIGZpbmFsIEJ5dGVTdHJpbmcgYnl0ZVN0cmluZzsKKworICAgIEltcGxCeXRlU3RyaW5nKEJ5dGVTdHJpbmcgYnl0ZVN0cmluZykgeworICAgICAgdGhpcy5ieXRlU3RyaW5nID0gYnl0ZVN0cmluZzsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgQnl0ZVN0cmluZyBieXRlU3RyaW5nKCkgeworICAgICAgcmV0dXJuIGJ5dGVTdHJpbmc7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZpbGVTb3VyY2UuS2luZCBnZXRLaW5kKCkgeworICAgICAgcmV0dXJuIEZpbGVTb3VyY2UuS2luZC5CWVRFU1RSSU5HOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhATnVsbGFibGUgT2JqZWN0IHgpIHsKKyAgICAgIGlmICh4IGluc3RhbmNlb2YgRmlsZVNvdXJjZSkgeworICAgICAgICBGaWxlU291cmNlIHRoYXQgPSAoRmlsZVNvdXJjZSkgeDsKKyAgICAgICAgcmV0dXJuIHRoaXMuZ2V0S2luZCgpID09IHRoYXQuZ2V0S2luZCgpICYmIHRoaXMuYnl0ZVN0cmluZy5lcXVhbHModGhhdC5ieXRlU3RyaW5nKCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gYnl0ZVN0cmluZy5oYXNoQ29kZSgpOworICAgIH0KKyAgfQorCisgIC8vIEltcGxlbWVudGF0aW9uIHdoZW4gdGhlIGNvbnRhaW5lZCBwcm9wZXJ0eSBpcyAidXJpIi4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW1wbFVyaSBleHRlbmRzIFBhcmVudCB7CisgICAgcHJpdmF0ZSBmaW5hbCBVcmkgdXJpOworCisgICAgSW1wbFVyaShVcmkgdXJpKSB7CisgICAgICB0aGlzLnVyaSA9IHVyaTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgVXJpIHVyaSgpIHsKKyAgICAgIHJldHVybiB1cmk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZpbGVTb3VyY2UuS2luZCBnZXRLaW5kKCkgeworICAgICAgcmV0dXJuIEZpbGVTb3VyY2UuS2luZC5VUkk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKEBOdWxsYWJsZSBPYmplY3QgeCkgeworICAgICAgaWYgKHggaW5zdGFuY2VvZiBGaWxlU291cmNlKSB7CisgICAgICAgIEZpbGVTb3VyY2UgdGhhdCA9IChGaWxlU291cmNlKSB4OworICAgICAgICByZXR1cm4gdGhpcy5nZXRLaW5kKCkgPT0gdGhhdC5nZXRLaW5kKCkgJiYgdGhpcy51cmkuZXF1YWxzKHRoYXQudXJpKCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgICByZXR1cm4gdXJpLmhhc2hDb2RlKCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0ZsYWdzLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0ZsYWdzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmE1YmVhZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvRmxhZ3MuamF2YQpAQCAtMCwwICsxLDI4NiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKKy8qKgorICogUmVzcG9uc2libGUgZm9yIGNvbmZpZ3VyaW5nIE1ERC4KKyAqCisgKiA8cD5BbGwgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbnMgbWF0Y2ggZGVmYXVsdF92YWx1ZSBmcm9tIEdDTCBpZ25vcmluZyBjb25kaXRpb25hbF92YWx1ZXMsIGV0YywKKyAqIHVubGVzcyBub3RlZCBvdGhlcndpc2UuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRmxhZ3MgeworICAvLyBMSU5ULklmQ2hhbmdlCisKKyAgLy8gRmVhdHVyZUZsYWdzCisgIGRlZmF1bHQgYm9vbGVhbiBjbGVhclN0YXRlT25NZGREaXNhYmxlZCgpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBkZWZhdWx0IGJvb2xlYW4gbWRkRGVsZXRlR3JvdXBzUmVtb3ZlZEFjY291bnRzKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBicm9hZGNhc3ROZXdseURvd25sb2FkZWRHcm91cHMoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBkZWZhdWx0IGJvb2xlYW4gbG9nRmlsZUdyb3Vwc1dpdGhGaWxlc01pc3NpbmcoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBkZWZhdWx0IGJvb2xlYW4gZGVsZXRlRmlsZUdyb3Vwc1dpdGhGaWxlc01pc3NpbmcoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBkZWZhdWx0IGJvb2xlYW4gZHVtcE1kZEluZm8oKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIGVuYWJsZURlYnVnVWkoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIGVuYWJsZUNsaWVudEVycm9yTG9nZ2luZygpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBkZWZhdWx0IGludCBmaWxlS2V5VmVyc2lvbigpIHsKKyAgICByZXR1cm4gMjsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiB0ZXN0T25seUZpbGVLZXlWZXJzaW9uKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBlbmFibGVDb21wcmVzc2VkRmlsZSgpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBlbmFibGVaaXBGb2xkZXIoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBkZWZhdWx0IGJvb2xlYW4gZW5hYmxlRGVsdGFEb3dubG9hZCgpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBlbmFibGVNZGRHY21TZXJ2aWNlKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIGVuYWJsZVNpbGVudEZlZWRiYWNrKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIG1pZ3JhdGVUb05ld0ZpbGVLZXkoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBkZWZhdWx0IGJvb2xlYW4gbWlncmF0ZUZpbGVFeHBpcmF0aW9uUG9saWN5KCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIGRvd25sb2FkRmlyc3RPbldpZmlUaGVuT25BbnlOZXR3b3JrKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIGxvZ1N0b3JhZ2VTdGF0cygpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBsb2dOZXR3b3JrU3RhdHMoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBkZWZhdWx0IGJvb2xlYW4gcmVtb3ZlR3JvdXBrZXlzV2l0aERvd25sb2FkZWRGaWVsZE5vdFNldCgpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBjYWNoZUxhc3RMb2NhdGlvbigpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGRlZmF1bHQgaW50IGxvY2F0aW9uQ3VzdG9tUGFyYW1TMkxldmVsKCkgeworICAgIHJldHVybiAxMDsKKyAgfQorCisgIGRlZmF1bHQgaW50IGxvY2F0aW9uVGFza1RpbWVvdXRTZWMoKSB7CisgICAgcmV0dXJuIDU7CisgIH0KKworICBkZWZhdWx0IGJvb2xlYW4gYWRkQ29uZmlnc0Zyb21QaGVub3R5cGUoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBkZWZhdWx0IGJvb2xlYW4gZW5hYmxlTW9iaWxlRGF0YURvd25sb2FkKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBpbnQgbWRkUmVzZXRUcmlnZ2VyKCkgeworICAgIHJldHVybiAwOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIG1kZEVuYWJsZURvd25sb2FkUGVuZGluZ0dyb3VwcygpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBtZGRFbmFibGVWZXJpZnlQZW5kaW5nR3JvdXBzKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIG1kZEVuYWJsZUdhcmJhZ2VDb2xsZWN0aW9uKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIG1kZERlbGV0ZVVuaW5zdGFsbGVkQXBwcygpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBlbmFibGVNb2JzdG9yZUZpbGVTZXJ2aWNlKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIGVuYWJsZURlbGF5ZWREb3dubG9hZCgpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBnY21SZXNjaGVkdWxlT25seU9uY2VQZXJQcm9jZXNzU3RhcnQoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBkZWZhdWx0IGJvb2xlYW4gZ21zTWRkU3dpdGNoVG9Dcm9uZXQoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIGVuYWJsZURheXNTaW5jZUxhc3RNYWludGVuYW5jZVRyYWNraW5nKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIGVuYWJsZVNpZGVsb2FkaW5nKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBlbmFibGVEb3dubG9hZFN0YWdlRXhwZXJpbWVudElkUHJvcGFnYXRpb24oKSB7CisgICAgcmV0dXJuIGZhbHNlOyAvLyBUT0RPKGIvMjAxNDYzODAzKTogZmxpcCB0byB0cnVlIG9uY2Ugcm9sbGVkIG91dC4KKyAgfQorCisgIC8vIENvbnRyb2xzIHZlcmlmaWNhdGlvbiBvZiBpc29sYXRlZCBzeW1saW5rIHN0cnVjdHVyZXMuCisgIC8vIEJ5IGRlZmF1bHQsIHZlcmlmaWNhdGlvbiBpcyBPTi4gaWYgdGhpcyBmbGFnIGlzIHNldCB0byBmYWxzZSwgdmVyaWZpY2F0aW9uIHdpbGwgYmUgdHVybmVkIE9GRi4KKyAgZGVmYXVsdCBib29sZWFuIGVuYWJsZUlzb2xhdGVkU3RydWN0dXJlVmVyaWZpY2F0aW9uKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBib29sZWFuIGVuYWJsZVJuZ0Jhc2VkRGV2aWNlU3RhYmxlU2FtcGxpbmcoKSB7CisgICAgcmV0dXJuIGZhbHNlOyAvLyBUT0RPKGIvMTQ0Njg0NzYzKTogU3dpdGNoIHRvIHRydWUgYWZ0ZXIgZnVsbHkgcm9sbGVkIG91dC4KKyAgfQorCisgIC8vIFBlcmlvZFRhc2tGbGFncworICBkZWZhdWx0IGxvbmcgbWFpbnRlbmFuY2VHY21UYXNrUGVyaW9kKCkgeworICAgIHJldHVybiA4NjQwMDsKKyAgfQorCisgIGRlZmF1bHQgbG9uZyBjaGFyZ2luZ0djbVRhc2tQZXJpb2QoKSB7CisgICAgcmV0dXJuIDIxNjAwOworICB9CisKKyAgZGVmYXVsdCBsb25nIGNlbGx1bGFyQ2hhcmdpbmdHY21UYXNrUGVyaW9kKCkgeworICAgIHJldHVybiAyMTYwMDsKKyAgfQorCisgIGRlZmF1bHQgbG9uZyB3aWZpQ2hhcmdpbmdHY21UYXNrUGVyaW9kKCkgeworICAgIHJldHVybiAyMTYwMDsKKyAgfQorCisgIC8vIE1kZFNhbXBsZUludGVydmFscworICBkZWZhdWx0IGludCBtZGREZWZhdWx0U2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIDEwMDsKKyAgfQorCisgIGRlZmF1bHQgaW50IG1kZERvd25sb2FkRXZlbnRzU2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBkZWZhdWx0IGludCBncm91cFN0YXRzTG9nZ2luZ1NhbXBsZUludGVydmFsKCkgeworICAgIHJldHVybiAxMDA7CisgIH0KKworICBkZWZhdWx0IGludCBhcGlMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIDEwMDsKKyAgfQorCisgIGRlZmF1bHQgaW50IGNsZWFudXBMb2dMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIDEwMDA7CisgIH0KKworICBkZWZhdWx0IGludCBzaWxlbnRGZWVkYmFja1NhbXBsZUludGVydmFsKCkgeworICAgIHJldHVybiAxMDA7CisgIH0KKworICBkZWZhdWx0IGludCBzdG9yYWdlU3RhdHNMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIDEwMDsKKyAgfQorCisgIGRlZmF1bHQgaW50IG5ldHdvcmtTdGF0c0xvZ2dpbmdTYW1wbGVJbnRlcnZhbCgpIHsKKyAgICByZXR1cm4gMTAwOworICB9CisKKyAgZGVmYXVsdCBpbnQgbW9ic3RvcmVGaWxlU2VydmljZVN0YXRzU2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIDEwMDsKKyAgfQorCisgIGRlZmF1bHQgaW50IG1kZEFuZHJvaWRTaGFyaW5nU2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIDEwMDsKKyAgfQorCisgIC8vIERvd25sb2FkZXJGbGFncworICBkZWZhdWx0IGJvb2xlYW4gZG93bmxvYWRlckVuZm9yY2VIdHRwcygpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIGRlZmF1bHQgYm9vbGVhbiBlbmZvcmNlTG93U3RvcmFnZUJlaGF2aW9yKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgZGVmYXVsdCBpbnQgYWJzRnJlZVNwYWNlQWZ0ZXJEb3dubG9hZCgpIHsKKyAgICByZXR1cm4gNTAwICogMTAyNCAqIDEwMjQ7IC8vIDUwMG1iCisgIH0KKworICBkZWZhdWx0IGludCBhYnNGcmVlU3BhY2VBZnRlckRvd25sb2FkTG93U3RvcmFnZUFsbG93ZWQoKSB7CisgICAgcmV0dXJuIDEwMCAqIDEwMjQgKiAxMDI0OyAvLyAxMDBtYgorICB9CisKKyAgZGVmYXVsdCBpbnQgYWJzRnJlZVNwYWNlQWZ0ZXJEb3dubG9hZEV4dHJlbWVseUxvd1N0b3JhZ2VBbGxvd2VkKCkgeworICAgIHJldHVybiAyICogMTAyNCAqIDEwMjQ7IC8vIDJtYgorICB9CisKKyAgZGVmYXVsdCBmbG9hdCBmcmFjdGlvbkZyZWVTcGFjZUFmdGVyRG93bmxvYWQoKSB7CisgICAgcmV0dXJuIDAuMUY7CisgIH0KKworICBkZWZhdWx0IGludCB0aW1lVG9XYWl0Rm9yRG93bmxvYWRlcigpIHsKKyAgICByZXR1cm4gMTIwMDAwOyAvLyAyIG1pbnV0ZXMKKyAgfQorCisgIGRlZmF1bHQgaW50IGRvd25sb2FkZXJNYXhUaHJlYWRzKCkgeworICAgIHJldHVybiAyOworICB9CisKKyAgZGVmYXVsdCBpbnQgZG93bmxvYWRlck1heFJldHJ5T25DaGVja3N1bU1pc21hdGNoQ291bnQoKSB7CisgICAgcmV0dXJuIDU7CisgIH0KKworICAvLyBMSU5ULlRoZW5DaGFuZ2UoPGludGVybmFsPikKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvR2V0RmlsZUdyb3VwUmVxdWVzdC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9HZXRGaWxlR3JvdXBSZXF1ZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmYxMTdkNQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvR2V0RmlsZUdyb3VwUmVxdWVzdC5qYXZhCkBAIC0wLDAgKzEsNjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgYW5kcm9pZC5hY2NvdW50cy5BY2NvdW50OworaW1wb3J0IGNvbS5nb29nbGUuYXV0by52YWx1ZS5BdXRvVmFsdWU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLmNvbmN1cnJlbnQuSW1tdXRhYmxlOworCisvKiogUmVxdWVzdCB0byBnZXQgYSBzaW5nbGUgZmlsZSBncm91cC4gKi8KK0BBdXRvVmFsdWUKK0BJbW11dGFibGUKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBHZXRGaWxlR3JvdXBSZXF1ZXN0IHsKKyAgR2V0RmlsZUdyb3VwUmVxdWVzdCgpIHt9CisKKyAgcHVibGljIGFic3RyYWN0IFN0cmluZyBncm91cE5hbWUoKTsKKworICBwdWJsaWMgYWJzdHJhY3QgT3B0aW9uYWw8QWNjb3VudD4gYWNjb3VudE9wdGlvbmFsKCk7CisKKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPFN0cmluZz4gdmFyaWFudElkT3B0aW9uYWwoKTsKKworICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBwcmVzZXJ2ZVppcERpcmVjdG9yaWVzKCk7CisKKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ldyBBdXRvVmFsdWVfR2V0RmlsZUdyb3VwUmVxdWVzdC5CdWlsZGVyKCkuc2V0UHJlc2VydmVaaXBEaXJlY3RvcmllcyhmYWxzZSk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIEdldEZpbGVHcm91cFJlcXVlc3R9LiAqLworICBAQXV0b1ZhbHVlLkJ1aWxkZXIKKyAgcHVibGljIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBCdWlsZGVyIHsKKyAgICBCdWlsZGVyKCkge30KKworICAgIC8qKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBmaWxlIGdyb3VwLCB3aGljaCBpcyByZXF1aXJlZC4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRHcm91cE5hbWUoU3RyaW5nIGdyb3VwTmFtZSk7CisKKyAgICAvKiogU2V0cyB0aGUgYWNjb3VudCB0aGF0IGlzIGFzc29jaWF0ZWQgdG8gdGhlIGZpbGUgZ3JvdXAsIHdoaWNoIGlzIG9wdGlvbmFsLiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldEFjY291bnRPcHRpb25hbChPcHRpb25hbDxBY2NvdW50PiBhY2NvdW50T3B0aW9uYWwpOworCisgICAgLyoqIFNldHMgdGhlIHZhcmlhbnQgaWQgYXNzb2NpYXRlZCB3aXRoIHRoZSBncm91cCwgd2hpY2ggaXMgb3B0aW9uYWwuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0VmFyaWFudElkT3B0aW9uYWwoT3B0aW9uYWw8U3RyaW5nPiB2YXJpYW50SWRPcHRpb25hbCk7CisKKyAgICAvKioKKyAgICAgKiBCeSBkZWZhdWx0LCBNREQgd2lsbCBzY2FuIHRoZSBkaXJlY3RvcmllcyBnZW5lcmF0ZWQgYnkgdW5wYWNraW5nIHppcCBmaWxlcyBpbiBhIGRvd25sb2FkCisgICAgICogdHJhbnNmb3JtIGFuZCBnZW5lcmF0ZSBhIENsaWVudERhdGFGaWxlIGZvciBlYWNoIGNvbnRhaW5lZCBmaWxlLiBCeSBkZWZhdWx0LCBNREQgYWxzbyBoaWRlcworICAgICAqIHRoZSByb290IGRpcmVjdG9yeS4gU2V0dGluZyB0aGlzIHRvIHRydWUgZGlzYWJsZXMgdGhhdCBiZWhhdmlvciwgYW5kIHdpbGwgc2ltcGx5IHJldHVybiB0aGUKKyAgICAgKiBkaXJlY3RvcmllcyBhcyBDbGllbnREYXRhRmlsZXMuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0UHJlc2VydmVaaXBEaXJlY3Rvcmllcyhib29sZWFuIHByZXNlcnZlKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBHZXRGaWxlR3JvdXBSZXF1ZXN0IGJ1aWxkKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9HZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTA0ZGRmNwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudDsKKworaW1wb3J0IGFuZHJvaWQuYWNjb3VudHMuQWNjb3VudDsKK2ltcG9ydCBjb20uZ29vZ2xlLmF1dG8udmFsdWUuQXV0b1ZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5jb25jdXJyZW50LkltbXV0YWJsZTsKKworLyoqIFJlcXVlc3QgdG8gZ2V0IG11bHRpcGxlIGZpbGUgZ3JvdXBzIGFmdGVyIGZpbHRlcmluZy4gKi8KK0BBdXRvVmFsdWUKK0BJbW11dGFibGUKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0IHsKKyAgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCgpIHt9CisKKyAgLy8gSWYgdGhpcyB2YWx1ZSBpcyBzZXQgdG8gdHJ1ZSwgZ3JvdXBOYW1lIHNob3VsZCBub3QgYmUgc2V0LgorICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpbmNsdWRlQWxsR3JvdXBzKCk7CisKKyAgLy8gSWYgdGhpcyB2YWx1ZSBpcyBzZXQgdG8gdHJ1ZSwgb25seSBncm91cHMgd2l0aG91dCBhY2NvdW50IHdpbGwgYmUgcmV0dXJuZWQsIGFuZCBhY2NvdW50T3B0aW9uYWwKKyAgLy8gc2hvdWxkIGJlIGFic2VudC4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgZmFsc2UuCisgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIGdyb3VwV2l0aE5vQWNjb3VudE9ubHkoKTsKKworICBwdWJsaWMgYWJzdHJhY3QgT3B0aW9uYWw8U3RyaW5nPiBncm91cE5hbWVPcHRpb25hbCgpOworCisgIHB1YmxpYyBhYnN0cmFjdCBPcHRpb25hbDxBY2NvdW50PiBhY2NvdW50T3B0aW9uYWwoKTsKKworICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBwcmVzZXJ2ZVppcERpcmVjdG9yaWVzKCk7CisKKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ldyBBdXRvVmFsdWVfR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5CdWlsZGVyKCkKKyAgICAgICAgLnNldEluY2x1ZGVBbGxHcm91cHMoZmFsc2UpCisgICAgICAgIC5zZXRHcm91cFdpdGhOb0FjY291bnRPbmx5KGZhbHNlKQorICAgICAgICAuc2V0UHJlc2VydmVaaXBEaXJlY3RvcmllcyhmYWxzZSk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3R9LiAqLworICBAQXV0b1ZhbHVlLkJ1aWxkZXIKKyAgcHVibGljIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBCdWlsZGVyIHsKKyAgICBCdWlsZGVyKCkge30KKworICAgIC8qKiBTZXRzIHRoZSBmbGFnIHdoZXRoZXIgYWxsIGdyb3VwcyBhcmUgaW5jbHVkZWQuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0SW5jbHVkZUFsbEdyb3Vwcyhib29sZWFuIGluY2x1ZGVBbGxHcm91cHMpOworCisgICAgLyoqIFNldHMgdGhlIGZsYWcgd2hldGhlciB0byBvbmx5IHJldHVybiBhY2NvdW50IGluZGVwZW5kZW50IGdyb3Vwcy4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRHcm91cFdpdGhOb0FjY291bnRPbmx5KGJvb2xlYW4gZ3JvdXBXaXRoTm9BY2NvdW50T25seSk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBmaWxlIGdyb3VwLCB3aGljaCBpcyBvcHRpb25hbC4gV2hlbiBncm91cE5hbWVPcHRpb25hbCBpcyBhYnNlbnQsIGNhbGxlcgorICAgICAqIG11c3Qgc2V0IHRoZSBpbmNsdWRlQWxsR3JvdXBzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldEdyb3VwTmFtZU9wdGlvbmFsKE9wdGlvbmFsPFN0cmluZz4gZ3JvdXBOYW1lT3B0aW9uYWwpOworCisgICAgLyoqIFNldHMgdGhlIGFjY291bnQgdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggdGhlIGZpbGUgZ3JvdXAsIHdoaWNoIGlzIG9wdGlvbmFsLiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldEFjY291bnRPcHRpb25hbChPcHRpb25hbDxBY2NvdW50PiBhY2NvdW50T3B0aW9uYWwpOworCisgICAgLyoqCisgICAgICogQnkgZGVmYXVsdCwgTUREIHdpbGwgc2NhbiB0aGUgZGlyZWN0b3JpZXMgZ2VuZXJhdGVkIGJ5IHVucGFja2luZyB6aXAgZmlsZXMgaW4gYSBkb3dubG9hZAorICAgICAqIHRyYW5zZm9ybSBhbmQgZ2VuZXJhdGUgYSBDbGllbnREYXRhRmlsZSBmb3IgZWFjaCBjb250YWluZWQgZmlsZS4gQnkgZGVmYXVsdCwgTUREIGFsc28gaGlkZXMKKyAgICAgKiB0aGUgcm9vdCBkaXJlY3RvcnkuIFNldHRpbmcgdGhpcyB0byB0cnVlIGRpc2FibGVzIHRoYXQgYmVoYXZpb3IsIGFuZCB3aWxsIHNpbXBseSByZXR1cm4gdGhlCisgICAgICogZGlyZWN0b3JpZXMgYXMgQ2xpZW50RGF0YUZpbGVzLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldFByZXNlcnZlWmlwRGlyZWN0b3JpZXMoYm9vbGVhbiBwcmVzZXJ2ZSk7CisKKyAgICBhYnN0cmFjdCBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0IGF1dG9CdWlsZCgpOworCisgICAgcHVibGljIGZpbmFsIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QgYnVpbGQoKSB7CisgICAgICBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0IGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QgPSBhdXRvQnVpbGQoKTsKKworICAgICAgaWYgKGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QuaW5jbHVkZUFsbEdyb3VwcygpKSB7CisgICAgICAgIGNoZWNrQXJndW1lbnQoIWdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QuZ3JvdXBOYW1lT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSk7CisgICAgICAgIGNoZWNrQXJndW1lbnQoIWdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QuYWNjb3VudE9wdGlvbmFsKCkuaXNQcmVzZW50KCkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgY2hlY2tBcmd1bWVudCgKKyAgICAgICAgICAgIGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QuZ3JvdXBOYW1lT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSwKKyAgICAgICAgICAgICJSZXF1ZXN0IG11c3QgcHJvdmlkZSBhIGdyb3VwIG5hbWUgb3Igc291cmNlIHRvIGZpbHRlciBieSIpOworICAgICAgfQorCisgICAgICBpZiAoZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5ncm91cFdpdGhOb0FjY291bnRPbmx5KCkpIHsKKyAgICAgICAgY2hlY2tBcmd1bWVudCghZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5hY2NvdW50T3B0aW9uYWwoKS5pc1ByZXNlbnQoKSk7CisgICAgICB9CisKKyAgICAgIHJldHVybiBnZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0OworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9JbXBvcnRGaWxlc1JlcXVlc3QuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvSW1wb3J0RmlsZXNSZXF1ZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzZjOWMzNgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvSW1wb3J0RmlsZXNSZXF1ZXN0LmphdmEKQEAgLTAsMCArMSwxNDggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgYW5kcm9pZC5hY2NvdW50cy5BY2NvdW50OworaW1wb3J0IGNvbS5nb29nbGUuYXV0by52YWx1ZS5BdXRvVmFsdWU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVNYXA7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5jb25jdXJyZW50LkltbXV0YWJsZTsKKworLyoqIFJlcXVlc3QgdG8gaW1wb3J0IGZpbGVzIGludG8gYW4gZXhpc3RpbmcgRGF0YUZpbGVHcm91cC4gKi8KK0BBdXRvVmFsdWUKK0BJbW11dGFibGUKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBJbXBvcnRGaWxlc1JlcXVlc3QgeworCisgIEltcG9ydEZpbGVzUmVxdWVzdCgpIHt9CisKKyAgLyoqIE5hbWUgdGhhdCBpZGVudGlmaWVzIHRoZSBmaWxlIGdyb3VwIHRvIGltcG9ydCBmaWxlcyBpbnRvLiAqLworICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIGdyb3VwTmFtZSgpOworCisgIC8qKiBCdWlsZCBpZCB0aGF0IGlkZW50aWZpZXMgdGhlIGZpbGUgZ3JvdXAgdG8gaW1wb3J0IGZpbGVzIGludG8uICovCisgIHB1YmxpYyBhYnN0cmFjdCBsb25nIGJ1aWxkSWQoKTsKKworICAvKiogVmFyaWFudCBpZCB0aGF0IGlkZW50aWZpZXMgdGhlIGZpbGUgZ3JvdXAgdG8gaW1wb3J0IGZpbGVzIGludG8uICovCisgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgdmFyaWFudElkKCk7CisKKyAgLyoqCisgICAqIEN1c3RvbSBwcm9wZXJ0eSB0aGF0IGlkZW50aWZpZXMgdGhlIGZpbGUgZ3JvdXAgdG8gaW1wb3J0IGZpbGVzIGludG8uCisgICAqCisgICAqIDxwPklmIGEgZmlsZSBncm91cCBzdXBwb3J0cyB0aGlzIGZpZWxkLCBpdCBpcyByZXF1aXJlZCB0byBpZGVudGlmeSB0aGUgZmlsZSBncm91cC4gSW4gbW9zdAorICAgKiBjYXNlcywgdGhpcyBmaWVsZCBkb2VzIG5vdCBuZWVkIHRvIGJlIGluY2x1ZGVkIHRvIGlkZW50aWZ5IHRoZSBmaWxlIGdyb3VwLgorICAgKgorICAgKiA8cD5Db250YWN0IDxpbnRlcm5hbD5AIGlmIHlvdSB0aGluayB0aGlzIGZpZWxkIGlzIHJlcXVpcmVkIGZvciB5b3VyIHVzZS1jYXNlLgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPEFueT4gY3VzdG9tUHJvcGVydHlPcHRpb25hbCgpOworCisgIC8qKiBMaXN0IG9mIHtAbGluayBEYXRhRmlsZX1zIHRvIGltcG9ydCBpbnRvIHRoZSBleGlzdGluZyBmaWxlIGdyb3VwLiAqLworICBwdWJsaWMgYWJzdHJhY3QgSW1tdXRhYmxlTGlzdDxEYXRhRmlsZT4gdXBkYXRlZERhdGFGaWxlTGlzdCgpOworCisgIC8qKgorICAgKiBNYXAgb2YgaW5saW5lIGZpbGUgY29udGVudCB0aGF0IHNob3VsZCBiZSBpbXBvcnRlZC4KKyAgICoKKyAgICogPHA+VGhlIE1hcCBpcyBrZXllZCBieSB0aGUge0BsaW5rIERhdGFGaWxlI2ZpbGVJZH0gdGhhdCByZXByZXNlbnRzIHRoZSBmaWxlIGNvbnRlbnQgYW5kIHRoZQorICAgKiB2YWx1ZXMgYXJlIHRoZSBmaWxlIGNvbnRlbnQgY29udGFpbmVkIGluIGEge0BsaW5rIEJ5dGVTdHJpbmd9LgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IEltbXV0YWJsZU1hcDxTdHJpbmcsIEZpbGVTb3VyY2U+IGlubGluZUZpbGVNYXAoKTsKKworICAvKiogQWNjb3VudCBhc3NvY2lhdGVkIHdpdGggdGhlIGZpbGUgZ3JvdXAuICovCisgIHB1YmxpYyBhYnN0cmFjdCBPcHRpb25hbDxBY2NvdW50PiBhY2NvdW50T3B0aW9uYWwoKTsKKworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKKyAgICAvLyBTZXQgdXBkYXRlZERhdGFGaWxlTGlzdCBhcyBlbXB0eSBieSBkZWZhdWx0CisgICAgcmV0dXJuIG5ldyBBdXRvVmFsdWVfSW1wb3J0RmlsZXNSZXF1ZXN0LkJ1aWxkZXIoKS5zZXRVcGRhdGVkRGF0YUZpbGVMaXN0KEltbXV0YWJsZUxpc3Qub2YoKSk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIEltcG9ydEZpbGVzUmVxdWVzdH0uICovCisgIEBBdXRvVmFsdWUuQnVpbGRlcgorICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEJ1aWxkZXIgeworICAgIEJ1aWxkZXIoKSB7fQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgbmFtZSBvZiB0aGUgZmlsZSBncm91cCB0byBpbXBvcnQgZmlsZXMgaW50by4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgcmVxdWlyZWQgdG8gaWRlbnRpZnkgdGhlIGZpbGUgZ3JvdXAuCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0R3JvdXBOYW1lKFN0cmluZyBncm91cE5hbWUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgYnVpbGQgaWQgb2YgdGhlIGZpbGUgZ3JvdXAgdG8gaW1wb3J0IGZpbGVzIGludG8uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGlzIHJlcXVpcmVkIHRvIGlkZW50aWZ5IHRoZSBmaWxlIGdyb3VwLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldEJ1aWxkSWQobG9uZyBidWlsZElkKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhcmlhbnQgaWQgb2YgdGhlIGZpbGUgZ3JvdXAgdG8gaW1wb3J0IGZpbGVzIGludG8uCisgICAgICoKKyAgICAgKiA8cD5UaGlzIGlzIHJlcXVpcmVkIHRvIGlkZW50aWZ5IHRoZSBmaWxlIGdyb3VwLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldFZhcmlhbnRJZChTdHJpbmcgdmFyaWFudElkKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGN1c3RvbSBwcm9wZXJ0eSBvZiB0aGUgZmlsZSBncm91cCB0byBpbXBvcnQgZmlsZXMgaW50by4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgc2hvdWxkIG9ubHkgYmUgcHJvdmlkZWQgaWYgdGhlIGZpbGUgZ3JvdXAgc3VwcG9ydHMgdGhpcyBmaWVsZC4gTW9zdCBjYXNlcyBkbyBub3QKKyAgICAgKiByZXF1aXJlIHRoaXMuCisgICAgICoKKyAgICAgKiA8cD5Db250YWN0IDxpbnRlcm5hbD5AIGlmIHlvdSB0aGluayB0aGlzIGZpZWxkIGlzIHJlcXVpcmVkIGZvciB5b3VyIHVzZS1jYXNlLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldEN1c3RvbVByb3BlcnR5T3B0aW9uYWwoT3B0aW9uYWw8QW55PiBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIExpc3Qgb2YgaW5saW5lIERhdGFGaWxlcyB0aGF0IHNob3VsZCBiZSB1cGRhdGVkIGluIHRoZSBmaWxlIGdyb3VwLgorICAgICAqCisgICAgICogPHA+VGhpcyBsaXN0IGNhbiBiZSBpbmNsdWRlZCB0byB1cGRhdGUgRGF0YUZpbGVzIGluIHRoZSBleGlzdGluZyBmaWxlIGdyb3VwIGlkZW50aWZpZWQgYnkgdGhlCisgICAgICogb3RoZXIgcGFyYW1ldGVycyBpbiB0aGUgcmVxdWVzdCAoe0BsaW5rICNncm91cE5hbWV9LCB7QGxpbmsgI2J1aWxkSWR9LCBhbmQge0BsaW5rCisgICAgICogI3ZhcmlhbnRJZH0pLgorICAgICAqCisgICAgICogPHA+RmlsZXMgaW4gdGhpcyBsaXN0IGFyZSBtZXJnZWQgaW50byB0aGUgZXhpc3RpbmcgZmlsZSBncm91cCBiYXNlZCBvbiB7QGxpbmsKKyAgICAgKiBEYXRhRmlsZSNmaWxlSWR9LiBUaGF0IGlzOgorICAgICAqCisgICAgICogPHVsPgorICAgICAqICAgPGxpPklmIGEgRmlsZSBleGlzdHMgd2l0aCB0aGUgc2FtZSBmaWxlSWQsIGl0IGlzIHJlcGxhY2VkIGJ5IHRoZSBGaWxlIGluIHRoaXMgTGlzdAorICAgICAqICAgPGxpPklmIGEgRmlsZSBkb2VzIG5vdCBleGlzdCB3aXRoIHRoZSBzYW1lIGZpbGVJZCwgaXQgaXMgYWRkZWQgdG8gdGhlIGZpbGUgZ3JvdXAKKyAgICAgKiA8L3VsPgorICAgICAqCisgICAgICogPHA+VGhpcyBsaXN0IGlzIG9ubHkgcmVxdWlyZWQgaWYgaW5saW5lIGZpbGVzIG5lZWQgdG8gYmUgYWRkZWQvdXBkYXRlZCBpbiB0aGUgZXhpc3RpbmcgZmlsZQorICAgICAqIGdyb3VwLiBJZiB0aGUgZXhpc3RpbmcgZmlsZSBncm91cCBoYXMgaW5saW5lIGZpbGVzIGFkZGVkIHdpdGgge0BsaW5rCisgICAgICogTW9iaWxlRGF0YURvd25sb2FkI2FkZEZpbGVHcm91cH0sIHRoaXMgbGlzdCBtYXkgYmUgZW1wdHkgYW5kIHRoZSBleGlzdGluZyBpbmxpbmUgZmlsZXMgdGhhdAorICAgICAqIG5lZWQgdG8gYmUgaW1wb3J0ZWQgY2FuIGJlIGluY2x1ZGVkIGluIHtAbGluayBJbXBvcnRGaWxlc1JlcXVlc3QjaW5saW5lRmlsZU1hcH0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0VXBkYXRlZERhdGFGaWxlTGlzdChJbW11dGFibGVMaXN0PERhdGFGaWxlPiB1cGRhdGVkRGF0YUZpbGVMaXN0KTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIG1hcCBvZiBpbmxpbmUgZmlsZSBjb250ZW50IHRvIGltcG9ydC4KKyAgICAgKgorICAgICAqIDxwPlRoZSBrZXlzIG9mIHRoaXMgbWFwIHNob3VsZCBiZSBmaWxlSWRzIG9mIERhdGFGaWxlcyB0aGF0IG5lZWQgdG8gYmUgaW1wb3J0ZWQuIFRoZSB2YWx1ZXMKKyAgICAgKiBvZiB0aGUgbWFwIHNob3VsZCBiZSBGaWxlU291cmNlLgorICAgICAqCisgICAgICogPHA+Tk9URTogS2V5L1ZhbHVlIHBhaXJzIGluY2x1ZGVkIGluIHRoaXMgbWFwIGNhbiByZWZlcmVuY2VzIGlubGluZSBmaWxlcyBhbHJlYWR5IGluIHRoZQorICAgICAqIGV4aXN0aW5nIGZpbGUgZ3JvdXAgKGFkZGVkIHZpYSB7QGxpbmsgTW9iaWxlRGF0YURvd25sb2FkI2FkZEZpbGVHcm91cH0pIG9yIGlubGluZSBmaWxlcworICAgICAqIGluY2x1ZGVkIGluIHRoZSB7QGxpbmsgSW1wb3J0RmlsZXNSZXF1ZXN0I3VwZGF0ZWREYXRhRmlsZUxpc3R9LgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldElubGluZUZpbGVNYXAoSW1tdXRhYmxlTWFwPFN0cmluZywgRmlsZVNvdXJjZT4gaW5saW5lRmlsZU1hcCk7CisKKyAgICAvKiogU2V0cyB0aGUgb3B0aW9uYWwgYWNjb3VudCB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZmlsZSBncm91cC4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRBY2NvdW50T3B0aW9uYWwoT3B0aW9uYWw8QWNjb3VudD4gYWNjb3VudE9wdGlvbmFsKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBJbXBvcnRGaWxlc1JlcXVlc3QgYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Mb2dnZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvTG9nZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGY2Zjg1MwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvTG9nZ2VyLmphdmEKQEAgLTAsMCArMSwyNCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlOworCisvKiogUmVzcG9uc2libGUgdG8gbG9nIE1ERCBldmVudHMuICovCitwdWJsaWMgaW50ZXJmYWNlIExvZ2dlciB7CisKKyAgdm9pZCBsb2coTWVzc2FnZUxpdGUgZXZlbnQsIGludCBldmVudENvZGUpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Nb2JpbGVEYXRhRG93bmxvYWQuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvTW9iaWxlRGF0YURvd25sb2FkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjg4NjkxZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvTW9iaWxlRGF0YURvd25sb2FkLmphdmEKQEAgLTAsMCArMSw0MTAgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGFza1NjaGVkdWxlci5Db25zdHJhaW50T3ZlcnJpZGVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DYW5JZ25vcmVSZXR1cm5WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmVycm9ycHJvbmUuYW5ub3RhdGlvbnMuQ2hlY2tSZXR1cm5WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5DbGllbnRDb25maWdQcm90by5DbGllbnRGaWxlR3JvdXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqIFRoZSByb290IG9iamVjdCBhbmQgZW50cnkgcG9pbnQgZm9yIHRoZSBNb2JpbGVEYXRhRG93bmxvYWQgbGlicmFyeS4gKi8KK3B1YmxpYyBpbnRlcmZhY2UgTW9iaWxlRGF0YURvd25sb2FkIHsKKworICAvKioKKyAgICogQWRkcyBmb3IgZG93bmxvYWQgdGhlIGRhdGEgZmlsZSBncm91cCBpbiB7QGxpbmsgQWRkRmlsZUdyb3VwUmVxdWVzdH0sIGFmdGVyIHJ1bm5pbmcgdmFsaWRhdGlvbgorICAgKiBvbiB0aGUgZ3JvdXAuIFRoaXMgZ3JvdXAgd2lsbCByZXBsYWNlIGFueSBwcmV2aW91cyB2ZXJzaW9uIG9mIHRoaXMgZ3JvdXAgb25jZSBpdCBpcyBkb3dubG9hZGVkLgorICAgKgorICAgKiA8cD5UaGlzIGFwaSB0YWtlcyB7QGxpbmsgQWRkRmlsZUdyb3VwUmVxdWVzdH0gdGhhdCBjb250YWlucyBkYXRhIGZpbGUgZ3JvdXAsIGFuZCBpdCBjYW4gYmUgdXNlZAorICAgKiB0byBzZXQgZXh0cmEgcGFyYW1zIHN1Y2ggYXMgYWNjb3VudC4KKyAgICoKKyAgICogPHA+VGhpcyBkb2Vzbid0IHN0YXJ0IHRoZSBkb3dubG9hZCByaWdodCBhd2F5LiBUaGUgZG93bmxvYWQgc3RhcnRzIGxhdGVyIHdoZW4gdGhlIHRhc2tzCisgICAqIHNjaGVkdWxlZCB2aWEge0BsaW5rICNzY2hlZHVsZVBlcmlvZGljVGFza3N9IGFyZSBydW4uCisgICAqCisgICAqIDxwPkNhbGxpbmcgdGhpcyBhcGkgd2l0aCB0aGUgZXhhY3Qgc2FtZSBwYXJhbWV0ZXJzIG11bHRpcGxlIHRpbWVzIGlzIGEgbm8tb3AuCisgICAqCisgICAqIEBwYXJhbSBhZGRGaWxlR3JvdXBSZXF1ZXN0IFRoZSByZXF1ZXN0IHRvIGFkZCBmaWxlIGdyb3VwIGluIE1ERC4KKyAgICogQHJldHVybiBMaXN0ZW5hYmxlRnV0dXJlIG9mIHRydWUgaWYgdGhlIGdyb3VwIHdhcyBzdWNjZXNzZnVsbHkgYWRkZWQsIG9yIHRoZSBncm91cCB3YXMgYWxyZWFkeQorICAgKiAgICAgcHJlc2VudDsgTGlzdGVuYWJsZUZ1dHVyZSBvZiBmYWxzZSBpZiB0aGUgZ3JvdXAgaXMgaW52YWxpZCBvciBhbiBJL08gZXJyb3Igb2NjdXJzLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiBhZGRGaWxlR3JvdXAoQWRkRmlsZUdyb3VwUmVxdWVzdCBhZGRGaWxlR3JvdXBSZXF1ZXN0KTsKKworICAvKioKKyAgICogUmVtb3ZlcyBhbGwgdmVyc2lvbnMgb2YgdGhlIGRhdGEgZmlsZSBncm91cCB0aGF0IG1hdGNoZXMge0BsaW5rIFJlbW92ZUZpbGVHcm91cFJlcXVlc3R9IGZyb20KKyAgICogTURELiBJZiBubyBkYXRhIGZpbGUgZ3JvdXAgbWF0Y2hlcywgdGhpcyBjYWxsIGlzIGEgbm8tb3AuCisgICAqCisgICAqIDxwPlRoaXMgYXBpIHRha2VzIHtAbGluayBSZW1vdmVGaWxlR3JvdXBSZXF1ZXN0fSB0aGF0IGNvbnRhaW5zIGRhdGEgZmlsZSBncm91cCwgYW5kIGl0IGNhbiBiZQorICAgKiB1c2VkIHRvIHNldCBleHRyYSBwYXJhbXMgc3VjaCBhcyBhY2NvdW50LgorICAgKgorICAgKiBAcGFyYW0gcmVtb3ZlRmlsZUdyb3VwUmVxdWVzdCBUaGUgcmVxdWVzdCB0byByZW1vdmUgZmlsZSBncm91cCBmcm9tIE1ERC4KKyAgICogQHJldHVybiBMaXN0ZW5hYmxlIG9mIHRydWUgaWYgdGhlIGdyb3VwIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCwgb3Igbm8gZ3JvdXAgbWF0Y2hlczsKKyAgICogICAgIExpc3RlbmFibGUgb2YgZmFsc2UgaWYgdGhlIG1hdGNoaW5nIGdyb3VwIGZhaWxzIHRvIGJlIHJlbW92ZWQuCisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IHJlbW92ZUZpbGVHcm91cChSZW1vdmVGaWxlR3JvdXBSZXF1ZXN0IHJlbW92ZUZpbGVHcm91cFJlcXVlc3QpOworCisgIC8qKgorICAgKiBSZW1vdmVzIGFsbCB2ZXJzaW9ucyBvZiB0aGUgZGF0YSBmaWxlIGdyb3VwcyB0aGF0IG1hdGNoIHtAbGluayBSZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0fQorICAgKiBmcm9tIE1ERC4gSWYgbm8gZGF0YSBmaWxlIGdyb3VwIG1hdGNoZXMsIHRoaXMgY2FsbCBpcyBhIG5vLW9wLgorICAgKgorICAgKiA8cD5UaGlzIGFwaSB0YWtlcyBhIHtAbGluayBSZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0fSB0aGF0IGNvbnRhaW5zIG9wdGlvbmFsIGZpbHRlcnMgZm9yCisgICAqIHRoZSBncm91cCBuYW1lLCBncm91cCBzb3VyY2UsIGFzc29jaWF0ZWQgYWNjb3VudCwgZXRjLgorICAgKgorICAgKiA8cD5BIHJlc29sdmVkIGZ1dHVyZSB3aWxsIG9ubHkgYmUgcmV0dXJuZWQgaWYgdGhlIHJlbW92YWwgY29tcGxldGVzIHN1Y2Nlc3NmdWxseSBmb3IgYWxsCisgICAqIG1hdGNoaW5nIGZpbGUgZ3JvdXBzLiBJZiBhbnkgZmFpbHVyZXMgb2NjdXIgZHVyaW5nIHRoaXMgbWV0aG9kLCBpdCB3aWxsIHJldHVybiBhIGZhaWxlZCBmdXR1cmUKKyAgICogd2l0aCBhbiB7QGxpbmsgQWdncmVnYXRlRXhjZXB0aW9ufSBjb250YWluaW5nIHRoZSBmYWlsdXJlcyB0aGF0IG9jY3VycmVkLgorICAgKgorICAgKiA8cD5OT1RFOiBUaGlzIG9ubHkgcmVtb3ZlcyB0aGUgbWV0YWRhdGEgZnJvbSBNREQsIG5vdCBmaWxlIGNvbnRlbnQuIERvd25sb2FkZWQgZmlsZXMgdGhhdCBhcmUKKyAgICogbm8gbG9uZ2VyIG5lZWRlZCBhcmUgZGVsZXRlZCBkdXJpbmcgTUREJ3MgZGFpbHkgbWFpbnRlbmFuY2UgdGFzay4KKyAgICoKKyAgICogQHBhcmFtIHJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QgVGhlIHJlcXVlc3QgdG8gcmVtb3ZlIGZpbGUgZ3JvdXAgZnJvbSBNREQuCisgICAqIEByZXR1cm4gTGlzdGVuYWJsZUZ1dHVyZSB0aGF0IHJlc29sdmVzIHdpdGgge0BsaW5rIFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlc3BvbnNlfSwgb3IgZmFpbHMKKyAgICogICAgIHdpdGgge0BsaW5rIEFnZ3JlZ2F0ZUV4Y2VwdGlvbn0KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8UmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVzcG9uc2U+IHJlbW92ZUZpbGVHcm91cHNCeUZpbHRlcigKKyAgICAgIFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QgcmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCk7CisKKyAgLyoqCisgICAqIFJldHVybnMgdGhlIGxhdGVzdCBkb3dubG9hZGVkIGRhdGEgdGhhdCB3ZSBoYXZlIGZvciB0aGUgZ2l2ZW4gZ3JvdXAgbmFtZS4KKyAgICoKKyAgICogPHA+VGhpcyBhcGkgdGFrZXMgYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIEdldEZpbGVHcm91cFJlcXVlc3R9IHRoYXQgY29udGFpbnMgZ3JvdXAgbmFtZSwgYW5kIGl0CisgICAqIGNhbiBiZSB1c2VkIHRvIHNldCBleHRyYSBwYXJhbXMgc3VjaCBhcyBhY2NvdW50LgorICAgKgorICAgKiA8cD5UaGlzIGxpc3RlbmFibGUgZnV0dXJlIHdpbGwgcmV0dXJuIG51bGwgaWYgbm8gZ3JvdXAgZXhpc3RzIG9yIGhhcyBiZWVuIGRvd25sb2FkZWQgZm9yIHRoZQorICAgKiBnaXZlbiBncm91cCBuYW1lLgorICAgKgorICAgKiBAcGFyYW0gZ2V0RmlsZUdyb3VwUmVxdWVzdCBUaGUgcmVxdWVzdCB0byBnZXQgYSBzaW5nbGUgZmlsZSBncm91cC4KKyAgICogQHJldHVybiBUaGUgTGlzdGVuYWJsZUZ1dHVyZSBvZiByZXF1ZXN0ZWQgY2xpZW50IGZpbGUgZ3JvdXAgZm9yIHRoZSBnaXZlbiByZXF1ZXN0LgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxDbGllbnRGaWxlR3JvdXA+IGdldEZpbGVHcm91cChHZXRGaWxlR3JvdXBSZXF1ZXN0IGdldEZpbGVHcm91cFJlcXVlc3QpOworCisgIC8qKgorICAgKiBSZXR1cm5zIGFsbCB0aGUgZGF0YSB0aGF0IHdlIGhhdmUgZm9yIHRoZSBnaXZlbiB7QGxpbmsgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdH0uCisgICAqCisgICAqIDxwPlRoaXMgbGlzdGVuYWJsZSBmdXR1cmUgd2lsbCByZXR1cm4gYSBsaXN0IG9mIGZpbGUgZ3JvdXBzIHdpdGggdGhlaXIgY3VycmVudCBkb3dubG9hZCBzdGF0dXMuCisgICAqCisgICAqIDxwPk9ubHkgcHJlc2VudCBmaWVsZHMgaW4ge0BsaW5rIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3R9IHdpbGwgYmUgdXNlZCB0byBwZXJmb3JtIHRoZQorICAgKiBmaWx0ZXJpbmcsIGkuZS4gd2hlbiBubyBhY2NvdW50IGlzIHNwZWNpZmllZCBpbiB0aGUgZmlsdGVyLCBmaWxlIGdyb3VwcyB3b24ndCBiZSBmaWx0ZXJlZCBiYXNlZAorICAgKiBvbiBhY2NvdW50LgorICAgKgorICAgKiBAcGFyYW0gZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCBUaGUgcmVxdWVzdCB0byBnZXQgbXVsdGlwbGUgZmlsZSBncm91cHMgYWZ0ZXIgZmlsdGVyaW5nLgorICAgKiBAcmV0dXJuIFRoZSBMaXN0ZW5hYmxlRnV0dXJlIHRoYXQgd2lsbCByZXNvbHZlIHRvIGEgbGlzdCBvZiB0aGUgcmVxdWVzdGVkIGNsaWVudCBmaWxlIGdyb3VwcywKKyAgICogICAgIGluY2x1ZGluZyBwZW5kaW5nIGFuZCBkb3dubG9hZGVkIHZlcnNpb25zOyB0aGlzIExpc3RlbmFibGVGdXR1cmUgd2lsbCByZXNvbHZlIHRvIGFsbCBjbGllbnQKKyAgICogICAgIGZpbGUgZ3JvdXBzIHdoZW4ge0Bjb2RlIGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QuaW5jbHVkZUFsbEdyb3Vwc30gaXMgdHJ1ZS4KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8SW1tdXRhYmxlTGlzdDxDbGllbnRGaWxlR3JvdXA+PiBnZXRGaWxlR3JvdXBzQnlGaWx0ZXIoCisgICAgICBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0IGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QpOworCisgIC8qKgorICAgKiBJbXBvcnRzIElubGluZSBGaWxlcyBpbnRvIGFuIEV4aXN0aW5nIE1ERCBGaWxlIEdyb3VwLgorICAgKgorICAgKiA8cD5UaGlzIGFwaSB0YWtlcyBhIHtAbGluayBJbXBvcnRGaWxlc1JlcXVlc3R9IGNvbnRhaW5pbmcgaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24gYWJvdXQgYW4KKyAgICogZXhpc3RpbmcgRmlsZSBHcm91cCwgYW4gb3B0aW9uYWwgbGlzdCBvZiB7QGxpbmsgRGF0YUZpbGV9cyB0byBpbXBvcnQgaW50byB0aGUgZXhpc3RpbmcgRmlsZQorICAgKiBHcm91cCwgYW5kIGEgTWFwIG9mIGZpbGUgY29udGVudCB0byBpbXBvcnQgaW50byBNREQuCisgICAqCisgICAqIDxwPlRoZSBpZGVudGlmeWluZyBpbmZvcm1hdGlvbiBpcyB1c2VkIHRvIGlkZW50aWZ5IGEgZmlsZSBncm91cCBhbmQgaXRzIHNwZWNpZmljIHZlcnNpb24uIFRoaXMKKyAgICogcHJldmVudHMgdGhlIGNhbGxlciBmcm9tIGFjY2lkZW50YWxseSBpbXBvcnRpbmcgZmlsZXMgaW50byB0aGUgd3JvbmcgZmlsZSBncm91cCBvciB0aGUgd3JvbmcKKyAgICogdmVyc2lvbiBvZiB0aGUgZmlsZSBncm91cC4gQW4gb3B0aW9uYWwge0BsaW5rIEFjY291bnR9IHBhcmFtZXRlciBjYW4gYWxzbyBiZSBzcGVjaWZpZWQgaWYgdGhlCisgICAqIGV4aXN0aW5nIGZpbGUgZ3JvdXAgd2FzIGFzc29jaWF0ZWQgd2l0aCBhbiBhY2NvdW50LgorICAgKgorICAgKiA8cD5UaGUgZ2l2ZW4ge0BsaW5rIERhdGFGaWxlfSBsaXN0IGFsbG93cyB1cGRhdGVkIGZpbGVzIChzdGlsbCBjb21wYXRpYmxlIHdpdGggYSBnaXZlbiBmaWxlCisgICAqIGdyb3VwIHZlcnNpb24pIHRvIGJlIGltcG9ydGVkIGludG8gTURELiBUaGlzIEFQSSB3bGwgbWVyZ2UgdGhlIGdpdmVuIERhdGFGaWxlcyBpbnRvIHRoZQorICAgKiBleGlzdGluZyBmaWxlIGdyb3VwIGluIHRoZSBmb2xsb3dpbmcgbWFubmVyOgorICAgKgorICAgKiA8dWw+CisgICAqICAgPGxpPkRhdGFGaWxlcyBpbmNsdWRlZCBpbiB0aGUgRGF0YUZpbGUgbGlzdCBidXQgbm90IHRoZSBleGlzdGluZyBmaWxlIGdyb3VwIHdpbGwgYmUgYWRkZWQgYXMKKyAgICogICAgICAgbmV3IERhdGFGaWxlcworICAgKiAgIDxsaT5EYXRhRmlsZXMgaW5jbHVkZWQgaW4gdGhlIERhdGFGaWxlIGxpc3Qgd2lsbCByZXBsYWNlIERhdGFGaWxlcyBpbiB0aGUgZXhpc3RpbmcgZmlsZSBncm91cAorICAgKiAgICAgICBpZiB0aGVpciBmaWxlIElkcyBtYXRjaC4KKyAgICogICA8bGk+RGF0YUZpbGVzIGluY2x1ZGVkIGluIHRoZSBleGlzdGluZyBmaWxlIGdyb3VwIGJ1dCBub3QgdGhlIERhdGFGaWxlIGxpc3Qgd2lsbCByZW1haW4KKyAgICogICAgICAgdW50b3VjaGVkLgorICAgKiA8L3VsPgorICAgKgorICAgKiA8cD57QGxpbmsgSW1wb3J0RmlsZXNSZXF1ZXN0fSBhbHNvIHJlcXVpcmVzIGEgTWFwIG9mIGZpbGUgc291cmNlcyB0aGF0IHNob3VsZCBiZSBpbXBvcnRlZCBieQorICAgKiBNREQuIFRoZSBNYXAgaXMga2V5ZWQgYnkgdGhlIGZpbGVJZHMgb2YgRGF0YUZpbGVzIGFuZCBjb250YWlucyB0aGUgY29udGVudHMgb2YgdGhlIGZpbGUgdG8KKyAgICogaW1wb3J0IHdpdGhpbiBhIHtAbGluayBCeXRlU3RyaW5nfS4gVGhpcyBNYXAgbXVzdCBjb250YWlucyBhbiBlbnRyeSBmb3IgYWxsIHtAbGluayBEYXRhRmlsZX1zCisgICAqIHdoaWNoIHJlcXVpcmUgYW4gaW5saW5lIGZpbGUgc291cmNlLiBPbmx5ICJJbmxpbmUiIHtAbGluayBEYXRhRmlsZX1zIHNob3VsZCBiZSBpbmNsdWRlZCBpbiB0aGlzCisgICAqIG1hcCAoc2VlIGRldGFpbHMgYmVsb3cpLgorICAgKgorICAgKiA8cD5BbiBpbmxpbmUge0BsaW5rIERhdGFGaWxlfSBpcyB0aGUgc2FtZSBhcyBhIHN0YW5kYXJkIHtAbGluayBEYXRhRmlsZX0sIGJ1dCBpbnN0ZWFkIG9mIGFuCisgICAqICJodHRwcyIgdXJsLCB0aGUgdXJsIHNob3VsZCBtYXRjaCB0aGUgZm9sbG93aW5nIGZvcm1hdDoKKyAgICoKKyAgICogPHByZT57QGNvZGUgImlubGluZWZpbGU6PGtleT4ifTwvcHJlPgorICAgKgorICAgKiA8cD5XaGVyZSB7QGNvZGUga2V5fSBpcyBhIHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBmaWxlLiBJbiBtb3N0IGNhc2VzLCB0aGUgY2hlY2tzdW0gc2hvdWxkIGJlCisgICAqIHVzZWQgYXMgdGhpcyBrZXkuIElmIHRoZSBjaGVja3N1bSBpcyBub3QgdXNlZCwgYW5vdGhlciB1bmlxdWUgaWRlbnRpZmllciBzaG91bGQgYmUgdXNlZCB0bworICAgKiBhbGxvdyBwcm9wZXIgZGVkdXBpbmcgb2YgdGhlIGZpbGUgaW1wb3J0IHdpdGhpbiBNREQuCisgICAqCisgICAqIDxwPkV4YW1wbGUgaW5saW5lIGZpbGUgdXJsOgorICAgKgorICAgKiA8cHJlPntAY29kZSBpbmxpbmVmaWxlOnNoYTE6OWE0ZWEzY2E4MWQzZjFkNjMxNTMxY2JjMjE2YTYyZDliMTA1MDllZX08L3ByZT4KKyAgICoKKyAgICogPHA+Tk9URTogSW5saW5lIGZpbGVzIGNhbiBiZSBzcGVjaWZpZWQgYnkgdGhlIGdpdmVuIERhdGFGaWxlIGxpc3QgaW4ge0BsaW5rCisgICAqIEltcG9ydEZpbGVzUmVxdWVzdH0sIGJ1dCBjYW4gYWxzbyBiZSBzcGVjaWZpZWQgYnkgYSB7QGxpbmsgRGF0YUZpbGVHcm91cH0gYWRkZWQgdmlhIHtAbGluaworICAgKiAjYWRkRmlsZUdyb3VwfS4gQSBGaWxlIEdyb3VwIHRoYXQgY29udGFpbnMgaW5saW5lIGZpbGVzIHdpbGwgbm90IGJlIGNvbnNpZGVyZWQgRE9XTkxPQURFRCB1bnRpbAorICAgKiBhbGwgaW5saW5lIGZpbGVzIGFyZSBpbXBvcnRlZCB2aWEgdGhpcyBBUEkuCisgICAqCisgICAqIDxwPkJlY2F1c2UgdGhpcyBtZXRob2QgcGVyZm9ybXMgYW4gdXBkYXRlIHRvIHRoZSBzdG9yZWQgRmlsZSBHcm91cCBtZXRhZGF0YSwgdGhlIGdpdmVuIHtAbGluaworICAgKiBJbXBvcnRGaWxlc1JlcXVlc3R9IG11c3Qgc2F0aXNmeSB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CisgICAqCisgICAqIDx1bD4KKyAgICogICA8bGk+VGhlIHJlcXVlc3RzIGlkZW50aWZ5aW5nIGluZm9ybWF0aW9uIG11c3QgbWF0Y2ggYW4gZXhpc3RpbmcgRmlsZSBHcm91cAorICAgKiAgIDxsaT5BbGwgaW5saW5lIERhdGFGaWxlcyBtdXN0IGhhdmUgZmlsZSBjb250ZW50IHNwZWNpZmllZCBpbiB0aGUgcmVxdWVzdCdzIElubGluZSBGaWxlIE1hcAorICAgKiA8L3VsPgorICAgKgorICAgKiA8cD5JZiBlaXRoZXIgb2YgdGhlc2UgY29uZGl0aW9ucyBpcyBub3QgbWV0LCB0aGlzIG9wZXJhdGlvbiB3aWxsIHJldHVybiBhIGZhaWxlZAorICAgKiBMaXN0ZW5hYmxlRnV0dXJlLgorICAgKgorICAgKiA8cD5GaW5hbGx5LCB0aGlzIEFQSSBpcyBhIGF0b21pYyBvcGVyYXRpb24uIFRoYXQgaXMsIDxlbT5laXRoZXIgYWxsIGlubGluZSBmaWxlcyB3aWxsIGJlCisgICAqIGltcG9ydGVkIHN1Y2Nlc3NmdWxseSBvciBub25lIHdpbGwgYmUgaW1wb3J0ZWQ8L2VtPi4gSWYgdGhlcmUgaXMgYSBmYWlsdXJlIHdpdGggaW1wb3J0aW5nIGEKKyAgICogZmlsZSwgTUREIHdpbGwgbm90IHVwZGF0ZSB0aGUgZmlsZSBncm91cCAoaS5lLiBmdXR1cmUgY2FsbHMgdG8ge0BsaW5rICNnZXRGaWxlR3JvdXB9IHdpbGwKKyAgICogcmV0dXJuIHRoZSBzYW1lIHtAbGluayBDbGllbnRGaWxlR3JvdXB9IGFzIGJlZm9yZSB0aGlzIGNhbGwpLgorICAgKgorICAgKiBAcGFyYW0gaW1wb3J0RmlsZXNSZXF1ZXN0IFJlcXVlc3QgY29udGFpbmluZyByZXF1aXJlZCBwYXJhbWV0ZXJzIHRvIHBlcmZvcm0gaW1wb3J0IGZpbGVzCisgICAqICAgICBvcGVyYXRpb24uCisgICAqIEByZXR1cm4gTGlzdGVuYWJsZUZ1dHVyZSB0aGF0IHJlc29sdmVzIHdoZW4gYWxsIGlubGluZSBmaWxlcyBhcmUgc3VjY2Vzc2Z1bGx5IGltcG9ydGVkLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBpbXBvcnRGaWxlcyhJbXBvcnRGaWxlc1JlcXVlc3QgaW1wb3J0RmlsZXNSZXF1ZXN0KTsKKworICAvKioKKyAgICogRG93bmxvYWRzIGEgc2luZ2xlIGZpbGUuCisgICAqCisgICAqIDxwPlRoaXMgYXBpIHRha2VzIHtAbGluayBTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0fSwgd2hpY2ggY29udGFpbnMgYSBkb3dubG9hZCB1cmwgb2YgdGhlIGZpbGUKKyAgICogdG8gZG93bmxvYWQuIHRoZSBkZXN0aW5hdGlvbiBsb2NhdGlvbiBvbiBkZXZpY2UgbXVzdCBhbHNvIGJlIHNwZWNpZmllZC4gU2VlCisgICAqIFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QgZm9yIGZ1bGwgbGlzdCBvZiByZXF1aXJlZC9vcHRpb25hbCBwYXJhbWV0ZXJzLgorICAgKgorICAgKiA8cD5UaGUgcmV0dXJuZWQgTGlzdGVuYWJsZUZ1dHVyZSB3aWxsIGZhaWwgaWYgdGhlcmUgaXMgYW4gZXJyb3IgZHVyaW5nIHRoZSBkb3dubG9hZC4gVGhlIGNhbGxlcgorICAgKiBpcyByZXNwb25zaWJsZSBmb3IgY2FsbGluZyBkb3dubG9hZEZpbGUgYWdhaW4gdG8gcmVzdGFydCB0aGUgZG93bmxvYWQuCisgICAqCisgICAqIDxwPlRoZSBjYWxsZXIgY2FuIGJlIG5vdGlmaWVkIG9mIHByb2dyZXNzIGJ5IHByb3ZpZGluZyBhIHtAbGluayBTaW5nbGVGaWxlRG93bmxvYWRMaXN0ZW5lcn0uCisgICAqIFRoaXMgbGlzdGVuZXIgd2lsbCBhbHNvIHByb3ZpZGUgY2FsbGJhY2tzIGZvciBhIGNvbXBsZXRlZCBkb3dubG9hZCwgZmFpbGVkIGRvd25sb2FkLCBvciBwYXVzZWQKKyAgICogZG93bmxvYWQgZHVlIHRvIGNvbm5lY3Rpdml0eSBsb3NzLgorICAgKgorICAgKiA8cD5UaGUgY2FsbGVyIGNhbiBzcGVjaWZ5IGNvbnN0cmFpbnRzIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHRoZSBkb3dubG9hZCBieSBwcm92aWRpbmcgYQorICAgKiB7QGxpbmsgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZENvbnN0cmFpbnRzfS4gVGhpcworICAgKiBhbGxvd3MgZG93bmxvYWRzIHRvIG9ubHkgc3RhcnQgd2hlbiBvbiBXaWZpLCBmb3IgZXhhbXBsZS4gQnkgZGVmYXVsdCwgbm8gY29uc3RyYWludHMgYXJlCisgICAqIHNwZWNpZmllZC4KKyAgICoKKyAgICogQHBhcmFtIHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QgVGhlIHJlcXVlc3QgdG8gZG93bmxvYWQgYSBmaWxlLgorICAgKiBAcmV0dXJuIExpc3RlbmFibGVGdXR1cmUgdGhhdCByZXNvbHZlcyB3aGVuIGZpbGUgaXMgZG93bmxvYWRlZC4KKyAgICovCisgIEBDaGVja1JldHVyblZhbHVlCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGaWxlKFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3Qgc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCk7CisKKyAgLyoqCisgICAqIERvd25sb2FkcyBhbmQgcmV0dXJucyB0aGUgbGF0ZXN0IGRvd25sb2FkZWQgZGF0YSB0aGF0IHdlIGhhdmUgZm9yIHRoZSBnaXZlbiBncm91cCBuYW1lLgorICAgKgorICAgKiA8cD5UaGlzIGFwaSB0YWtlcyB7QGxpbmsgRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0fSB0aGF0IGNvbnRhaW5zIGdyb3VwIG5hbWUsIGFuZCBpdCBjYW4gYmUgdXNlZAorICAgKiB0byBzZXQgZXh0cmEgcGFyYW1zIHN1Y2ggYXMgYWNjb3VudCwgZG93bmxvYWQgY29uZGl0aW9ucywgYW5kIGRvd25sb2FkIGxpc3RlbmVyLgorICAgKgorICAgKiA8cD5UaGUgZ3JvdXAgbmFtZSBtdXN0IGJlIGFkZGVkIHVzaW5nIHtAbGluayAjYWRkRmlsZUdyb3VwfSBiZWZvcmUgZG93bmxvYWRpbmcgdGhlIGZpbGUgZ3JvdXAuCisgICAqCisgICAqIDxwPlRoZSByZXR1cm5lZCBMaXN0ZW5hYmxlRnV0dXJlIHdpbGwgYmUgcmVzb2x2ZWQgd2hlbiB0aGUgZmlsZSBncm91cCBpcyBkb3dubG9hZGVkLiBJdCBjYW4KKyAgICogYWxzbyBiZSB1c2VkIHRvIGNhbmNlbCB0aGUgZG93bmxvYWQuCisgICAqCisgICAqIDxwPlRoZSByZXR1cm5lZCBMaXN0ZW5hYmxlRnV0dXJlIHdvdWxkIGZhaWwgaWYgdGhlcmUgaXMgYW55IGVycm9yIGR1cmluZyB0aGUgZG93bmxvYWQuIENsaWVudAorICAgKiBpcyByZXNwb25zaWJsZSB0byBjYWxsIHRoZSBkb3dubG9hZEZpbGVHcm91cCB0byByZXN1bWUgdGhlIGRvd25sb2FkLgorICAgKgorICAgKiA8cD5Eb3dubG9hZCBwcm9ncmVzcyBpcyBzdXBwb3J0ZWQgdGhyb3VnaCB0aGUgRG93bmxvYWRMaXN0ZW5lci4KKyAgICoKKyAgICogPHA+VG8gZG93bmxvYWQgdW5kZXIgYW55IGNvbmRpdGlvbnMsIGNsaWVudHMgc2hvdWxkIHVzZSB7QGxpbmsKKyAgICogQ29uc3RhbnRzLk5PX1JFU1RSSUNUSU9OU19ET1dOTE9BRF9DT05ESVRJT05TfQorICAgKgorICAgKiBAcGFyYW0gZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0IFRoZSByZXF1ZXN0IHRvIGRvd25sb2FkIGZpbGUgZ3JvdXAuCisgICAqLworICAvLyBUT0RPOiBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgYSBjbGllbnQgY2FsbHMgdGhpcyBBUEkgZm9yIHRoZSBzYW1lIGdyb3VwIHdoZW4gdGhlCisgIC8vICBlYXJsaWVyIGNhbGwgaGFzIG5vdCBmaW5pc2hlZC4KKyAgTGlzdGVuYWJsZUZ1dHVyZTxDbGllbnRGaWxlR3JvdXA+IGRvd25sb2FkRmlsZUdyb3VwKAorICAgICAgRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0IGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdCk7CisKKyAgLyoqCisgICAqIERvd25sb2FkcyBhIGZpbGUgdXNpbmcgYSBmb3JlZ3JvdW5kIHNlcnZpY2UgYW5kIG5vdGlmaWNhdGlvbi4KKyAgICoKKyAgICogPHA+VGhpcyBpcyBzaW1pbGFyIHRvIHtAbGluayAjZG93bmxvYWRGaWxlfSwgYnV0IGFsbG93cyB0aGUgZG93bmxvYWQgdG8gY29udGludWUgcnVubmluZyB3aGVuCisgICAqIHRoZSBhcHAgZW50ZXJzIHRoZSBiYWNrZ3JvdW5kLgorICAgKgorICAgKiA8cD5UaGUgbm90aWZpY2F0aW9uIGNyZWF0ZWQgZm9yIHRoZSBkb3dubG9hZCBpbmNsdWRlcyBhIGNhbmNlbCBhY3Rpb24uIFRoaXMgd2lsbCBhbGxvdyB0aGUKKyAgICogZG93bmxvYWQgdG8gYmUgY2FuY2VsbGVkIGV2ZW4gd2hlbiB0aGUgYXBwIGlzIGluIHRoZSBiYWNrZ3JvdW5kLgorICAgKgorICAgKiA8cD5UaGUgY2FuY2VsIGFjdGlvbiBpbiB0aGUgbm90aWZpY2F0aW9uIG1lbnUgcmVxdWlyZXMgdGhlIEZvcmVncm91bmRTZXJ2aWNlIHRvIGJlIHJlZ2lzdGVyZWQKKyAgICogd2l0aCB0aGUgYXBwbGljYXRpb24gKHZpYSB0aGUgQW5kcm9pZE1hbmlmZXN0LnhtbCkuIFRoaXMgYWxsb3dzIHRoZSBjYW5jZWxsYXRpb24gaW50ZW50cyB0byBiZQorICAgKiBwcm9wZXJseSBwaWNrZWQgdXAuIFRvIHJlZ2lzdGVyIHRoZSBzZXJ2aWNlLCB0aGUgZm9sbG93aW5nIGxpbmVzIG11c3QgYmUgaW5jbHVkZWQgaW4gdGhlIGFwcCdzCisgICAqIHtAY29kZSBBbmRyb2lkTWFuaWZlc3QueG1sfToKKyAgICoKKyAgICogPHByZT57QGNvZGUKKyAgICogPCEtLSBOZWVkZWQgYnkgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlIC0tPgorICAgKiA8dXNlcy1wZXJtaXNzaW9uIGFuZHJvaWQ6bmFtZT0iYW5kcm9pZC5wZXJtaXNzaW9uLkZPUkVHUk9VTkRfU0VSVklDRSIgLz4KKyAgICoKKyAgICogPCEtLSBTZXJ2aWNlIGZvciBNREQgZm9yZWdyb3VuZCBkb3dubG9hZHMgLS0+CisgICAqIDxzZXJ2aWNlCisgICAqICAgYW5kcm9pZDpuYW1lPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5mb3JlZ3JvdW5kLnN0aW5nLkZvcmVncm91bmREb3dubG9hZFNlcnZpY2UiCisgICAqICAgYW5kcm9pZDpleHBvcnRlZD0iZmFsc2UiIC8+CisgICAqIH08L3ByZT4KKyAgICoKKyAgICogPHA+Tk9URTogVGhlIGFib3ZlIGV4Y2VycHQgaXMgZm9yIEZyYW1ld29yayBhbmQgU3RpbmcgYXBwcy4gRGFnZ2VyIGFwcHMgc2hvdWxkIHVzZSB0aGUgc2FtZQorICAgKiBleGNlcnB0LCBidXQgY2hhbmdlIHRoZSB7QGNvZGUgYW5kcm9pZDpuYW1lfSBwcm9wZXJ0eSB0bzoKKyAgICoKKyAgICogPHByZT57QGNvZGUKKyAgICogYW5kcm9pZDpuYW1lPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5mb3JlZ3JvdW5kLmRhZ2dlci5Gb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlIgorICAgKiB9PC9wcmU+CisgICAqLworICBAQ2hlY2tSZXR1cm5WYWx1ZQorICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRmlsZVdpdGhGb3JlZ3JvdW5kU2VydmljZSgKKyAgICAgIFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3Qgc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCk7CisKKyAgLyoqCisgICAqIERvd25sb2FkIGEgZmlsZSBncm91cCBhbmQgc2hvdyBmb3JlZ3JvdW5kIGRvd25sb2FkIHByb2dyZXNzIGluIGEgbm90aWZpY2F0aW9uLiBVc2VyIGNhbiBjYW5jZWwKKyAgICogdGhlIGRvd25sb2FkIGZyb20gdGhlIG5vdGlmaWNhdGlvbiBtZW51LgorICAgKgorICAgKiA8cD5UaGUgY2FuY2VsIGFjdGlvbiBpbiB0aGUgbm90aWZpY2F0aW9uIG1lbnUgcmVxdWlyZXMgdGhlIEZvcmVncm91bmRTZXJ2aWNlIHRvIGJlIHJlZ2lzdGVyZWQKKyAgICogd2l0aCB0aGUgYXBwbGljYXRpb24gKHZpYSB0aGUgQW5kcm9pZE1hbmlmZXN0LnhtbCkuIFRoaXMgYWxsb3dzIHRoZSBjYW5jZWxsYXRpb24gaW50ZW50cyB0byBiZQorICAgKiBwcm9wZXJseSBwaWNrZWQgdXAuIFRvIHJlZ2lzdGVyIHRoZSBzZXJ2aWNlLCB0aGUgZm9sbG93aW5nIGxpbmVzIG11c3QgYmUgaW5jbHVkZWQgaW4gdGhlIGFwcCdzCisgICAqIHtAY29kZSBBbmRyb2lkTWFuaWZlc3QueG1sfToKKyAgICoKKyAgICogPHByZT57QGNvZGUKKyAgICogPCEtLSBOZWVkZWQgYnkgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlIC0tPgorICAgKiA8dXNlcy1wZXJtaXNzaW9uIGFuZHJvaWQ6bmFtZT0iYW5kcm9pZC5wZXJtaXNzaW9uLkZPUkVHUk9VTkRfU0VSVklDRSIgLz4KKyAgICoKKyAgICogPCEtLSBTZXJ2aWNlIGZvciBNREQgZm9yZWdyb3VuZCBkb3dubG9hZHMgLS0+CisgICAqIDxzZXJ2aWNlCisgICAqICAgYW5kcm9pZDpuYW1lPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5mb3JlZ3JvdW5kLnN0aW5nLkZvcmVncm91bmREb3dubG9hZFNlcnZpY2UiCisgICAqICAgYW5kcm9pZDpleHBvcnRlZD0iZmFsc2UiIC8+CisgICAqIH08L3ByZT4KKyAgICoKKyAgICogPHA+Tk9URTogVGhlIGFib3ZlIGV4Y2VycHQgaXMgZm9yIEZyYW1ld29yayBhbmQgU3RpbmcgYXBwcy4gRGFnZ2VyIGFwcHMgc2hvdWxkIHVzZSB0aGUgc2FtZQorICAgKiBleGNlcnB0LCBidXQgY2hhbmdlIHRoZSB7QGNvZGUgYW5kcm9pZDpuYW1lfSBwcm9wZXJ0eSB0bzoKKyAgICoKKyAgICogPHByZT57QGNvZGUKKyAgICogYW5kcm9pZDpuYW1lPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5mb3JlZ3JvdW5kLmRhZ2dlci5Gb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlIgorICAgKiB9PC9wcmU+CisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPENsaWVudEZpbGVHcm91cD4gZG93bmxvYWRGaWxlR3JvdXBXaXRoRm9yZWdyb3VuZFNlcnZpY2UoCisgICAgICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QgZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0KTsKKworICAvKioKKyAgICogQ2FuY2VsIGFuIG9uLWdvaW5nIGZvcmVncm91bmQgZG93bmxvYWQuCisgICAqCisgICAqIDxwPkF0dGVtcHRzIHRvIGNhbmNlbCBhbiBvbi1nb2luZyBmb3JlZ3JvdW5kIGRvd25sb2FkIHVzaW5nIGJlc3QgZWZmb3J0LiBJZiBkb3dubG9hZCBpcyB1bmtub3duCisgICAqIHRvIE1ERCwgdGhpcyBvcGVyYXRpb24gaXMgYSBub29wLgorICAgKgorICAgKiA8cD5JZiB0aGUgZG93bmxvYWQgd2FzIHN0YXJ0ZWQgd2l0aCB7QGxpbmsKKyAgICogI2Rvd25sb2FkRmlsZUdyb3VwV2l0aEZvcmVncm91bmRTZXJ2aWNlKERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdCl9LCB0aGUgc3BlY2lmaWMge0Bjb2RlCisgICAqIGRvd25sb2FkS2V5fSBtdXN0IGJlIHRoZSBncm91cCBuYW1lIG9mIHRoZSBmaWxlIGdyb3VwLgorICAgKgorICAgKiA8cD5JZiB0aGUgZG93bmxvYWQgd2FzIHN0YXJ0ZWQgd2l0aCB7QGxpbmsKKyAgICogI2Rvd25sb2FkRmlsZVdpdGhGb3JlZ3JvdW5kU2VydmljZShTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0KX0sIHRoZSBzcGVjaWZpYyB7QGNvZGUKKyAgICogZG93bmxvYWRLZXl9IG11c3QgYmUgdGhlIGRlc3RpbmF0aW9uIGZpbGUgdXJpIChpbiBzdHJpbmcgZm9ybSkuCisgICAqCisgICAqIEBwYXJhbSBkb3dubG9hZEtleSB0aGUga2V5IGFzc29jaWF0ZWQgd2l0aCB0aGUgZG93bmxvYWQKKyAgICovCisgIHZvaWQgY2FuY2VsRm9yZWdyb3VuZERvd25sb2FkKFN0cmluZyBkb3dubG9hZEtleSk7CisKKyAgLyoqCisgICAqIFRyaWdnZXJzIHRoZSBleGVjdXRpb24gb2YgTUREIG1haW50ZW5hbmNlLgorICAgKgorICAgKiA8cD5NREQgbmVlZHMgdG8gcnVuIG1haW50ZW5hbmNlIHRhc2sgb25jZSBhIGRheS4gSWYgeW91IGNhbGwge0BsaW5rCisgICAqICNzY2hlZHVsZVBlcmlvZGljQmFja2dyb3VuZFRhc2tzfSBhcGksIHRoZSBtYWludGVuYW5jZSB3aWxsIGJlIGNhbGxlZCBhdXRvbWF0aWNhbGx5LiBJbiBjYXNlCisgICAqIHlvdSBkb24ndCB3YW50IHRvIHNjaGVkdWxlIE1ERCB0YXNrcywgeW91IGNhbiBjYWxsIHRoaXMgbWFpbnRlbmFuY2UgbWV0aG9kIGRpcmVjdGx5LgorICAgKgorICAgKiA8cD5JZiB5b3UgZG8gbmVlZCB0byBjYWxsIHRoaXMgYXBpLCBtYWtlIHN1cmUgdGhhdCB0aGlzIGFwaSBpcyBjYWxsZWQgZXhhY3RseSBvbmNlIGV2ZXJ5IGRheS4KKyAgICoKKyAgICogPHA+VGhlIHJldHVybmVkIExpc3RlbmFibGVGdXR1cmUgd291bGQgZmFpbCBpZiB0aGUgbWFpbnRlbmFuY2UgZXhlY3V0aW9uIGRvZXNuJ3Qgc3VjY2VlZC4KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gbWFpbnRlbmFuY2UoKTsKKworICAvKioKKyAgICogU2NoZWR1bGUgcGVyaW9kaWMgdGFza3MgdGhhdCB3aWxsIGRvd25sb2FkIGFuZCB2ZXJpZnkgYWxsIGZpbGUgZ3JvdXBzIHdoZW4gdGhlIHJlcXVpcmVkCisgICAqIGNvbmRpdGlvbnMgYXJlIG1ldCwgdXNpbmcgdGhlIGdpdmVuIHtAbGluayBUYXNrU2NoZWR1bGVyfS4KKyAgICoKKyAgICogPHA+SWYgdGhlIGhvc3QgYXBwIGRvZXNuJ3QgcHJvdmlkZSBhIFRhc2tTY2hlZHVsZXIsIGNhbGxpbmcgdGhpcyBBUEkgd2lsbCBiZSBhIG5vLW9wLgorICAgKgorICAgKiBAZGVwcmVjYXRlZCBVc2UgdGhlIHtAbGluayBzY2hlZHVsZVBlcmlvZGljQmFja2dyb3VuZFRhc2tzfSBpbnN0ZWFkLgorICAgKi8KKyAgQERlcHJlY2F0ZWQKKyAgdm9pZCBzY2hlZHVsZVBlcmlvZGljVGFza3MoKTsKKworICAvKioKKyAgICogU2NoZWR1bGUgcGVyaW9kaWMgYmFja2dyb3VuZCB0YXNrcyB0aGF0IHdpbGwgZG93bmxvYWQgYW5kIHZlcmlmeSBhbGwgZmlsZSBncm91cHMgd2hlbiB0aGUKKyAgICogcmVxdWlyZWQgY29uZGl0aW9ucyBhcmUgbWV0LCB1c2luZyB0aGUgZ2l2ZW4ge0BsaW5rIFRhc2tTY2hlZHVsZXJ9LgorICAgKgorICAgKiA8cD5JZiB0aGUgaG9zdCBhcHAgZG9lc24ndCBwcm92aWRlIGEgVGFza1NjaGVkdWxlciwgY2FsbGluZyB0aGlzIEFQSSB3aWxsIGJlIGEgbm8tb3AuCisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHNjaGVkdWxlUGVyaW9kaWNCYWNrZ3JvdW5kVGFza3MoKTsKKworICAvKioKKyAgICogU2NoZWR1bGUgcGVyaW9kaWMgYmFja2dyb3VuZCB0YXNrcyB0aGF0IHdpbGwgZG93bmxvYWQgYW5kIHZlcmlmeSBhbGwgZmlsZSBncm91cHMgd2hlbiB0aGUKKyAgICogcmVxdWlyZWQgY29uZGl0aW9ucyBhcmUgbWV0LCB1c2luZyB0aGUgZ2l2ZW4ge0BsaW5rIFRhc2tTY2hlZHVsZXJ9LgorICAgKgorICAgKiA8cD5JZiB0aGUgaG9zdCBhcHAgZG9lc24ndCBwcm92aWRlIGEgVGFza1NjaGVkdWxlciwgY2FsbGluZyB0aGlzIEFQSSB3aWxsIGJlIGEgbm8tb3AuCisgICAqCisgICAqIEBwYXJhbSBjb25zdHJhaW50T3ZlcnJpZGVzTWFwIHRvIGFsbG93IGNsaWVudHMgdG8gb3ZlcnJpZGUgY29uc3RyYWludHMgcmVxdWlyZW1lbnRzLgorICAgKiAgICAgPHA+PGNvZGU+e0Bjb2RlCisgICAqICBDb25zdHJhaW50T3ZlcnJpZGVzIHdpZmlPdmVycmlkZXMgPQorICAgKiAgICAgQ29uc3RyYWludE92ZXJyaWRlcy5uZXdCdWlsZGVyKCkKKyAgICogICAgICAgICAuc2V0UmVxdWlyZXNDaGFyZ2luZyhmYWxzZSkKKyAgICogICAgICAgICAuc2V0UmVxdWlyZXNEZXZpY2VJZGxlKHRydWUpCisgICAqICAgICAgICAgLmJ1aWxkKCk7CisgICAqIENvbnN0cmFpbnRPdmVycmlkZXMgY2VsbHVsYXJPdmVycmlkZXMgPQorICAgKiAgICAgQ29uc3RyYWludE92ZXJyaWRlcy5uZXdCdWlsZGVyKCkKKyAgICogICAgICAgICAuc2V0UmVxdWlyZXNDaGFyZ2luZyh0cnVlKQorICAgKiAgICAgICAgIC5zZXRSZXF1aXJlc0RldmljZUlkbGUoZmFsc2UpCisgICAqICAgICAgICAgLmJ1aWxkKCk7CisgICAqCisgICAqICBNYXA8U3RyaW5nLCBDb25zdHJhaW50T3ZlcnJpZGVzPiBjb25zdHJhaW50T3ZlcnJpZGVzTWFwID0gbmV3IEhhc2hNYXA8PigpOworICAgKiAgY29uc3RyYWludE92ZXJyaWRlc01hcC5wdXQoVGFza1NjaGVkdWxlci5XSUZJX0NIQVJHSU5HX1BFUklPRElDX1RBU0ssIHdpZmlPdmVycmlkZXMpOworICAgKiAgY29uc3RyYWludE92ZXJyaWRlc01hcC5wdXQoVGFza1NjaGVkdWxlci5DRUxMVUxBUl9DSEFSR0lOR19QRVJJT0RJQ19UQVNLLCBjZWxsdWxhck92ZXJyaWRlcyk7CisgICAqCisgICAqICBtb2JpbGVEYXRhRG93bmxvYWQuc2NoZWR1bGVQZXJpb2RpY0JhY2tncm91bmRUYXNrcyhPcHRpb25hbC5vZihjb25zdHJhaW50T3ZlcnJpZGVzTWFwKSkuZ2V0KCk7CisgICAqIH08L2NvZGU+CisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHNjaGVkdWxlUGVyaW9kaWNCYWNrZ3JvdW5kVGFza3MoCisgICAgICBPcHRpb25hbDxNYXA8U3RyaW5nLCBDb25zdHJhaW50T3ZlcnJpZGVzPj4gY29uc3RyYWludE92ZXJyaWRlc01hcCk7CisKKyAgLyoqCisgICAqIEhhbmRsZSBhIHRhc2sgc2NoZWR1bGVkIHZpYSBhIHRhc2sgc2NoZWR1bGluZyBzZXJ2aWNlLgorICAgKgorICAgKiA8cD5UaGlzIG1ldGhvZCBzaG91bGQgbm90IGJlIGNhbGxlZCBvbiB0aGUgbWFpbiB0aHJlYWQsIGFzIGl0IGRvZXMgd29yayBvbiB0aGUgdGhyZWFkIGl0IGlzCisgICAqIGNhbGxlZCBvbi4KKyAgICoKKyAgICogQHJldHVybiBhIGxpc3RlbmFibGUgZnV0dXJlIHdoaWNoIGluZGljYXRlcyB3aGVuIGFueSBhc3luYyB0YXNrIHNjaGVkdWxlZCBpcyBjb21wbGV0ZS4KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gaGFuZGxlVGFzayhTdHJpbmcgdGFnKTsKKworICAvKiogQ2xlYXIgTUREIG1ldGFkYXRhIGFuZCBpdHMgbWFuYWdlZCBmaWxlcy4gTUREIHdpbGwgYmUgcmVzZXQgdG8gYSBjbGVhbiBzdGF0ZS4gKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjbGVhcigpOworCisgIC8qKgorICAgKiBSZXR1cm4gTUREIGRlYnVnIGluZm8gYXMgYSBzdHJpbmcuIFRoaXMgY291bGQgcmV0dXJuIHNvbWUgUElJIGluZm9ybWF0aW9uIHNvIGl0J3Mgbm90CisgICAqIHJlY29tbWVuZGVkIHRvIGJlIGNhbGxlZCBpbiBwcm9kdWN0aW9uIGJ1aWxkLgorICAgKgorICAgKiA8cD5UaGlzIGRlYnVnIGluZm8gc3RyaW5nIGNvdWxkIGJlIHZlcnkgbG9uZy4gSW4gb3JkZXIgdG8gcHJpbnQgdGhlbSBpbiBhZGIgbG9nY2F0LCB3ZSBoYXZlIHRvCisgICAqIHNwbGl0IHRoZSBzdHJpbmcuIFNlZSBob3cgaXQgaXMgZG9uZSBpbiBvdXIgc2FtcGxlIGFwcDogPGludGVybmFsPgorICAgKi8KKyAgU3RyaW5nIGdldERlYnVnSW5mb0FzU3RyaW5nKCk7CisKKyAgLyoqCisgICAqIFJlcG9ydHMgdXNhZ2Ugb2YgYSBmaWxlIGdyb3VwIGJhY2sgdG8gTURELiBUaGlzIGNhbiBiZSB1c2VkIHRvIHRyYWNrIGVycm9ycyB3aXRoIGZpbGUgZ3JvdXAKKyAgICogcm9sbCBvdXRzLiBFYWNoIHVzYWdlIG9mIHRoZSBmaWxlIGdyb3VwIHNob3VsZCByZXN1bHQgaW4gYSBzaW5nbGUgY2FsbCBvZiB0aGlzIG1ldGhvZCBpbiBvcmRlcgorICAgKiB0byBhbGxvdyBmb3IgYWNjdXJhdGUgbWV0cmljcyBzZXJ2ZXIgc2lkZS4KKyAgICoKKyAgICogQHBhcmFtIHVzYWdlRXZlbnQgdGhhdCB3aWxsIGJlIGxvZ2dlZC4KKyAgICogQHJldHVybiBhIGxpc3RlbmFibGUgZnV0dXJlIHdoaWNoIGluZGljYXRlcyB0aGF0IHRoZSBVc2FnZUV2ZW50IGhhcyBiZWVuIGxvZ2dlZC4KKyAgICovCisgIEBDYW5JZ25vcmVSZXR1cm5WYWx1ZQorICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlcG9ydFVzYWdlKFVzYWdlRXZlbnQgdXNhZ2VFdmVudCk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL01vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjZmIwZWIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL01vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIuamF2YQpAQCAtMCwwICsxLDM4NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5hY2NvdW50LkFjY291bnRNYW5hZ2VyQWNjb3VudFNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kZWx0YS5EZWx0YURlY29kZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZGFnZ2VyLkFwcGxpY2F0aW9uQ29udGV4dE1vZHVsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kYWdnZXIuRGFnZ2VyU3RhbmRhbG9uZUNvbXBvbmVudDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kYWdnZXIuRG93bmxvYWRlck1vZHVsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kYWdnZXIuRXhlY3V0b3JzTW9kdWxlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmRhZ2dlci5NYWluTWRkTGliTW9kdWxlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmRhZ2dlci5TdGFuZGFsb25lQ29tcG9uZW50OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuRXZlbnRMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dTYW1wbGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLk1kZEV2ZW50TG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTm9PcEV2ZW50TG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmxpdGUuRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuTmV0d29ya1VzYWdlTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuUHJlY29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlQ2FsbGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LlNlY3VyZVJhbmRvbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworCisvKioKKyAqIEEgQnVpbGRlciBmb3IgdGhlIHtAbGluayBNb2JpbGVEYXRhRG93bmxvYWR9LgorICoKKyAqIDxwPldBUk5JTkc6IE9ubHkgb25lIG9iamVjdCBzaG91bGQgYmUgYnVpbHQuIE90aGVyd2lzZSwgdGhlcmUgbWF5IGJlIGxvY2tpbmcgZXJyb3JzIG9uIHRoZQorICogdW5kZXJseWluZyBkYXRhYmFzZSBhbmQgdW5uZWNlc3NhcnkgbWVtb3J5IGNvbnN1bXB0aW9uLgorICoKKyAqIDxwPkZ1cnRoZXJtb3JlLCB0aGVyZSBtYXkgYmUgaW50ZXJmZXJlbmNlIGJldHdlZW4gc2NoZWR1bGVkIHRhc2suCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIjsKKworICBwcml2YXRlIGZpbmFsIERhZ2dlclN0YW5kYWxvbmVDb21wb25lbnQuQnVpbGRlciBjb21wb25lbnRCdWlsZGVyOworCisgIHByaXZhdGUgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIExpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSBjb250cm9sRXhlY3V0b3I7CisgIHByaXZhdGUgZmluYWwgTGlzdDxGaWxlR3JvdXBQb3B1bGF0b3I+IGZpbGVHcm91cFBvcHVsYXRvckxpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgcHJpdmF0ZSBPcHRpb25hbDxUYXNrU2NoZWR1bGVyPiB0YXNrU2NoZWR1bGVyT3B0aW9uYWwgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIE5ldHdvcmtVc2FnZU1vbml0b3IgbmV0d29ya1VzYWdlTW9uaXRvcjsKKyAgcHJpdmF0ZSBPcHRpb25hbDxEb3dubG9hZFByb2dyZXNzTW9uaXRvcj4gZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHJpdmF0ZSBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllcjsKKyAgcHJpdmF0ZSBPcHRpb25hbDxEZWx0YURlY29kZXI+IGRlbHRhRGVjb2Rlck9wdGlvbmFsID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHByaXZhdGUgT3B0aW9uYWw8Q29uZmlndXJhdG9yPiBjb25maWd1cmF0b3IgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHJpdmF0ZSBPcHRpb25hbDxMb2dnZXI+IGxvZ2dlck9wdGlvbmFsID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHByaXZhdGUgT3B0aW9uYWw8U2lsZW50RmVlZGJhY2s+IHNpbGVudEZlZWRiYWNrT3B0aW9uYWwgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHJpdmF0ZSBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWRPcHRpb25hbCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwcml2YXRlIE9wdGlvbmFsPENsYXNzPD8+PiBmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwcml2YXRlIE9wdGlvbmFsPEZsYWdzPiBmbGFnc09wdGlvbmFsID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHByaXZhdGUgT3B0aW9uYWw8QWNjb3VudFNvdXJjZT4gYWNjb3VudFNvdXJjZU9wdGlvbmFsID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHByaXZhdGUgYm9vbGVhbiB1c2VEZWZhdWx0QWNjb3VudFNvdXJjZSA9IHRydWU7CisgIHByaXZhdGUgT3B0aW9uYWw8Q3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3JPcHRpb25hbCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwcml2YXRlIE9wdGlvbmFsPEV4cGVyaW1lbnRhdGlvbkNvbmZpZz4gZXhwZXJpbWVudGF0aW9uQ29uZmlnT3B0aW9uYWwgPSBPcHRpb25hbC5hYnNlbnQoKTsKKworICBwdWJsaWMgc3RhdGljIE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIoKTsKKyAgfQorCisgIHByaXZhdGUgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlcigpIHsKKyAgICBjb21wb25lbnRCdWlsZGVyID0gRGFnZ2VyU3RhbmRhbG9uZUNvbXBvbmVudC5idWlsZGVyKCk7CisgIH0KKworICBwdWJsaWMgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlciBzZXRDb250ZXh0KENvbnRleHQgY29udGV4dCkgeworICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvKioKKyAgICogU2V0IFVuaXF1ZSBJbnN0YW5jZSBJRCBvZiB0aGlzIGluc3RhbmNlIG9mIE1vYmlsZURhdGFEb3dubG9hZC4gSW5zdGFuY2UgSUQgbXVzdCBiZSBub24tZW1wdHkKKyAgICogYW5kIFthLXpdIChsb3dlciBjYXNlKS4KKyAgICoKKyAgICogPHA+TW9zdCBhcHBzIHNob3VsZCB1c2UgQFNpbmdsZXRvbiBNREQuIElmIGFuIGFwcCB3YW50cyB0byB1c2UgbXVsdGlwbGUgaW5zdGFuY2VzIG9mIE1ERCwKKyAgICogcGxlYXNlIGJlIGF3YXJlIG9mIGZvbGxvd2luZyBjYXZlYXRzOiBFYWNoIGluc3RhbmNlIG9mIE1ERCB3aWxsIGhhdmUgaXRzIG93biBtZXRhZGF0YSwgYmFzZQorICAgKiBkaXJlY3RvcnksIGFuZCBwZXJpb2RpYyBiYWNrYnJvdW5kIHRhc2tzLiBUaGVyZSBpcyBubyBzaGFyaW5nIGFuZCBuby1kZWR1cCBiZXR3ZWVuIGluc3RhbmNlcy4KKyAgICogUGxlYXNlIHRhbGsgdG8gPGludGVybmFsPkAgYmVmb3JlIHVzaW5nIHRoaXMuCisgICAqLworICBwdWJsaWMgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlciBzZXRJbnN0YW5jZUlkT3B0aW9uYWwoT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkT3B0aW9uYWwpIHsKKyAgICB0aGlzLmluc3RhbmNlSWRPcHRpb25hbCA9IGluc3RhbmNlSWRPcHRpb25hbDsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgdGhlIENvbnRyb2wgRXhlY3V0b3Igd2hpY2ggd2lsbCBtYW5hZ2UgTUREIG1ldGEgZGF0YS4KKyAgICoKKyAgICogPHA+Tk9URTogQ29udHJvbCBFeGVjdXRvciBtdXN0IG5vdCBiZSBzaW5nbGUgdGhyZWFkIGV4ZWN1dG9yIG90aGVyd2lzZSBpdCBjb3VsZCBsZWFkIHRvCisgICAqIGRlYWRsb2NrIG9yIG90aGVyIHNpZGUgZWZmZWN0cy4KKyAgICovCisgIHB1YmxpYyBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIHNldENvbnRyb2xFeGVjdXRvcihMaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2UgY29udHJvbEV4ZWN1dG9yKSB7CisgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwoY29udHJvbEV4ZWN1dG9yKTsKKyAgICAvLyBFeGVjdXRvciB0aGF0IHdpbGwgZXhlY3V0ZSB0YXNrcyBzZXF1ZW50aWFsbHkuCisgICAgdGhpcy5jb250cm9sRXhlY3V0b3IgPSBjb250cm9sRXhlY3V0b3I7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvKioKKyAgICogU2V0cyBhIGNvbmZpZyBwb3B1bGF0b3IgdGhhdCB3aWxsIGJlIHVzZWQgYnkgTUREIHRvIHBlcmlvZGljYWxseSByZWZyZXNoIHRoZSBkYXRhIGZpbGUgZ3JvdXBzLgorICAgKgorICAgKiA8cD5JZiB0aGlzIGlzIG5vdCBzZXQsIHRoZW4gdGhlIGNsaWVudCBpcyByZXNwb25zaWJsZSBmb3IgcmVmcmVzaGluZyB0aGUgbGlzdCBvZiBmaWxlIGdyb3VwcyBpbgorICAgKiBNREQgYXMgYW5kIHdoZW4gdGhleSBzZWUgZml0LgorICAgKi8KKyAgcHVibGljIE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIgYWRkRmlsZUdyb3VwUG9wdWxhdG9yKEZpbGVHcm91cFBvcHVsYXRvciBmaWxlR3JvdXBQb3B1bGF0b3IpIHsKKyAgICB0aGlzLmZpbGVHcm91cFBvcHVsYXRvckxpc3QuYWRkKGZpbGVHcm91cFBvcHVsYXRvcik7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvKioKKyAgICogQWRkIGEgbGlzdCBvZiBjb25maWcgcG9wdWxhdG9yIHRoYXQgd2lsbCBiZSB1c2VkIGJ5IE1ERCB0byBwZXJpb2RpY2FsbHkgcmVmcmVzaCB0aGUgZGF0YSBmaWxlCisgICAqIGdyb3Vwcy4KKyAgICoKKyAgICogPHA+SWYgdGhpcyBpcyBub3Qgc2V0LCB0aGVuIHRoZSBjbGllbnQgaXMgcmVzcG9uc2libGUgZm9yIHJlZnJlc2hpbmcgdGhlIGxpc3Qgb2YgZmlsZSBncm91cHMgaW4KKyAgICogTUREIGFzIGFuZCB3aGVuIHRoZXkgc2VlIGZpdC4KKyAgICovCisgIHB1YmxpYyBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIGFkZEZpbGVHcm91cFBvcHVsYXRvcnMoCisgICAgICBJbW11dGFibGVMaXN0PEZpbGVHcm91cFBvcHVsYXRvcj4gZmlsZUdyb3VwUG9wdWxhdG9ycykgeworICAgIHRoaXMuZmlsZUdyb3VwUG9wdWxhdG9yTGlzdC5hZGRBbGwoZmlsZUdyb3VwUG9wdWxhdG9ycyk7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvKioKKyAgICogU2V0IHRoZSB0YXNrIHNjaGVkdWxlciB0aGF0IHdpbGwgYmUgdXNlZCBieSBNREQgdG8gc2NoZWR1bGUgcGVyaW9kaWMgYW5kIG9uZS1vZmYgdGFza3MuIENsaWVudHMKKyAgICogY2FuIHVzZSBHQ00sIEZKRCBvciBXb3JrIE1hbmFnZXIgdG8gc2NoZWR1bGUgdGFza3MsIGFuZCB0aGVuIGZvcndhcmQgdGhlIG5vdGlmaWNhdGlvbiB0byB7QGxpbmsKKyAgICogTW9iaWxlRGF0YURvd25sb2FkI2hhbmRsZVRhc2soU3RyaW5nKX0uCisgICAqLworICBwdWJsaWMgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlciBzZXRUYXNrU2NoZWR1bGVyKE9wdGlvbmFsPFRhc2tTY2hlZHVsZXI+IHRhc2tTY2hlZHVsZXJPcHRpb25hbCkgeworICAgIHRoaXMudGFza1NjaGVkdWxlck9wdGlvbmFsID0gdGFza1NjaGVkdWxlck9wdGlvbmFsOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqIFNldCB0aGUgb3B0aW9uYWwgQ29uZmlndXJhdG9yIHdoaWNoIGlmIHByZXNlbnQgd2lsbCBiZSB1c2VkIGJ5IE1ERCB0byBjb25maWd1cmUgaXRzIGZsYWdzLiAqLworICBwdWJsaWMgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlciBzZXRDb25maWd1cmF0b3JPcHRpb25hbChPcHRpb25hbDxDb25maWd1cmF0b3I+IGNvbmZpZ3VyYXRvcikgeworICAgIHRoaXMuY29uZmlndXJhdG9yID0gY29uZmlndXJhdG9yOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqIFNldCB0aGUgb3B0aW9uYWwgTG9nZ2VyIHdoaWNoIGlmIHByZXNlbnQgd2lsbCBiZSB1c2VkIGJ5IE1ERCB0byBsb2cgZXZlbnRzLiAqLworICBwdWJsaWMgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlciBzZXRMb2dnZXJPcHRpb25hbChPcHRpb25hbDxMb2dnZXI+IGxvZ2dlcikgeworICAgIHRoaXMubG9nZ2VyT3B0aW9uYWwgPSBsb2dnZXI7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvKiogU2V0IHRoZSBmbGFncyBvdGhlcndpc2UgZGVmYXVsdCB2YWx1ZXMgd2lsbCBiZSB1c2VkIG9ubHkuICovCisgIHB1YmxpYyBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIHNldEZsYWdzT3B0aW9uYWwoT3B0aW9uYWw8RmxhZ3M+IGZsYWdzKSB7CisgICAgdGhpcy5mbGFnc09wdGlvbmFsID0gZmxhZ3M7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvKioKKyAgICogU2V0IHRoZSBvcHRpb25hbCBTaWxlbnRGZWVkYmFjayB3aGljaCBpZiBwcmVzZW50IHdpbGwgYmUgdXNlZCBieSBNREQgdG8gc2VuZCBzaWxlbnQgZmVlZGJhY2tzLgorICAgKi8KKyAgcHVibGljIE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIgc2V0U2lsZW50RmVlZGJhY2tPcHRpb25hbCgKKyAgICAgIE9wdGlvbmFsPFNpbGVudEZlZWRiYWNrPiBzaWxlbnRGZWVkYmFja09wdGlvbmFsKSB7CisgICAgdGhpcy5zaWxlbnRGZWVkYmFja09wdGlvbmFsID0gc2lsZW50RmVlZGJhY2tPcHRpb25hbDsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgdGhlIE1vYlN0b3JlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UuIElkZWFsbHkgdGhpcyBzaG91bGQgYmUgdGhlIHNhbWUgb2JqZWN0IGFzIHRoZSBvbmUgdXNlZAorICAgKiBieSB0aGUgY2xpZW50IGFwcCB0byByZWFkIGZpbGVzIGZyb20gTURECisgICAqLworICBwdWJsaWMgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlciBzZXRGaWxlU3RvcmFnZShTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlKSB7CisgICAgdGhpcy5maWxlU3RvcmFnZSA9IGZpbGVTdG9yYWdlOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqCisgICAqIFNldCB0aGUgTmV0d29ya1VzYWdlTW9uaXRvci4gVGhpcyBOZXR3b3JrVXNhZ2VNb25pdG9yIGluc3RhbmNlIG11c3QgYmUgdGhlIHNhbWUgaW5zdGFuY2UgdGhhdAorICAgKiBpcyByZWdpc3RlcmVkIHdpdGggU3luY2hyb25vdXNGaWxlU3RvcmFnZS4KKyAgICovCisgIHB1YmxpYyBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIHNldE5ldHdvcmtVc2FnZU1vbml0b3IoTmV0d29ya1VzYWdlTW9uaXRvciBuZXR3b3JrVXNhZ2VNb25pdG9yKSB7CisgICAgdGhpcy5uZXR3b3JrVXNhZ2VNb25pdG9yID0gbmV0d29ya1VzYWdlTW9uaXRvcjsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgdGhlIERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLiBUaGlzIERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIGluc3RhbmNlIG11c3QgYmUgdGhlIHNhbWUKKyAgICogaW5zdGFuY2UgdGhhdCBpcyByZWdpc3RlcmVkIHdpdGggU3luY2hyb25vdXNGaWxlU3RvcmFnZS4KKyAgICovCisgIHB1YmxpYyBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIHNldERvd25sb2FkTW9uaXRvck9wdGlvbmFsKAorICAgICAgT3B0aW9uYWw8RG93bmxvYWRQcm9ncmVzc01vbml0b3I+IGRvd25sb2FkTW9uaXRvck9wdGlvbmFsKSB7CisgICAgdGhpcy5kb3dubG9hZE1vbml0b3JPcHRpb25hbCA9IGRvd25sb2FkTW9uaXRvck9wdGlvbmFsOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqCisgICAqIFNldCB0aGUgRmlsZURvd25sb2FkZXIgU3VwcGxpZXIuIE1ERCB0YWtlcyBpbiBhIFN1cHBsaWVyIG9mIEZpbGVEb3dubG9hZCB0byBzdXBwb3J0IGxhenkKKyAgICogaW5zdGFudGlhdGlvbiBvZiB0aGUgRmlsZURvd25sb2FkZXIKKyAgICovCisgIHB1YmxpYyBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIHNldEZpbGVEb3dubG9hZGVyU3VwcGxpZXIoCisgICAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllcikgeworICAgIHRoaXMuZmlsZURvd25sb2FkZXJTdXBwbGllciA9IGZpbGVEb3dubG9hZGVyU3VwcGxpZXI7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvKiogU2V0IHRoZSBEZWx0YSBmaWxlIGRlY29kZXIuICovCisgIHB1YmxpYyBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIHNldERlbHRhRGVjb2Rlck9wdGlvbmFsKAorICAgICAgT3B0aW9uYWw8RGVsdGFEZWNvZGVyPiBkZWx0YURlY29kZXJPcHRpb25hbCkgeworICAgIHRoaXMuZGVsdGFEZWNvZGVyT3B0aW9uYWwgPSBkZWx0YURlY29kZXJPcHRpb25hbDsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgdGhlIEZvcmVncm91bmQgRG93bmxvYWQgU2VydmljZS4gVGhpcyBmb3JlZ3JvdW5kIHNlcnZpY2Ugd2lsbCBrZWVwIHRoZSBkb3dubG9hZCBhbGl2ZSBldmVuCisgICAqIGlmIHRoZSB1c2VyIG5hdmlnYXRlcyBhd2F5IGZyb20gdGhlIGhvc3QgYXBwLiBUaGlzIGVuc3VyZXMgbG9uZyBkb3dubG9hZCBjYW4gZmluaXNoLgorICAgKgorICAgKiA8cD5JZiB0aGUgaG9zdCBuZWVkcyB0byB1c2UgYm90aCBNRERMaXRlIGFuZCBGdWxsIE1ERCwgdGhlIEZvcmVncm91bmQgRG93bmxvYWQgU2VydmljZSBjYW4gYmUKKyAgICogc2hhcmVkIGFzIGFuIG9wdGltaXphdGlvbi4gUGxlYXNlIHRhbGsgdG8gPGludGVybmFsPkAgb24gaG93IHRvIHNldHVwIGEgc2hhcmVkIEZvcmVncm91bmQKKyAgICogRG93bmxvYWQgU2VydmljZS4KKyAgICovCisgIHB1YmxpYyBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIHNldEZvcmVncm91bmREb3dubG9hZFNlcnZpY2VPcHRpb25hbCgKKyAgICAgIE9wdGlvbmFsPENsYXNzPD8+PiBmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3MpIHsKKyAgICB0aGlzLmZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsID0gZm9yZWdyb3VuZERvd25sb2FkU2VydmljZUNsYXNzOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqCisgICAqIFNldHMgdGhlIEFjY291bnRTb3VyY2UgdGhhdCdzIHVzZWQgdG8gd2lwZW91dCBhY2NvdW50LXJlbGF0ZWQgZGF0YSBhdCBtYWludGVuYW5jZSB0aW1lLiBJZiB0aGlzCisgICAqIG1ldGhvZCBpcyBub3QgY2FsbGVkLCBhbiBhY2NvdW50IHNvdXJjZSBiYXNlZCBvbiBBY2NvdW50TWFuYWdlciB3aWxsIGJlIGluamVjdGVkLgorICAgKi8KKyAgcHVibGljIE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIgc2V0QWNjb3VudFNvdXJjZU9wdGlvbmFsKAorICAgICAgT3B0aW9uYWw8QWNjb3VudFNvdXJjZT4gYWNjb3VudFNvdXJjZU9wdGlvbmFsKSB7CisgICAgdGhpcy5hY2NvdW50U291cmNlT3B0aW9uYWwgPSBhY2NvdW50U291cmNlT3B0aW9uYWw7CisgICAgdXNlRGVmYXVsdEFjY291bnRTb3VyY2UgPSBmYWxzZTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHB1YmxpYyBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIHNldEN1c3RvbUZpbGVHcm91cFZhbGlkYXRvck9wdGlvbmFsKAorICAgICAgT3B0aW9uYWw8Q3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3JPcHRpb25hbCkgeworICAgIHRoaXMuY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yT3B0aW9uYWwgPSBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3JPcHRpb25hbDsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBTZXRzIHRoZSBFeHBlcmltZW50YXRpb25Db25maWcgdGhhdCdzIHVzZWQgd2hlbiBwcm9wYWdhdGluZyBleHBlcmltZW50IGlkcyB0byBleHRlcm5hbCBsb2cKKyAgICogc291cmNlcy4gSWYgdGhpcyBpcyBub3QgY2FsbGVkLCBleHBlcmltZW50IGlkcyBhcmUgbm90IHByb3BhZ2F0ZWQuIFNlZSA8aW50ZXJuYWw+IGZvciBtb3JlCisgICAqIGRldGFpbHMuCisgICAqLworICBwdWJsaWMgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlciBzZXRFeHBlcmltZW50YXRpb25Db25maWdPcHRpb25hbCgKKyAgICAgIE9wdGlvbmFsPEV4cGVyaW1lbnRhdGlvbkNvbmZpZz4gZXhwZXJpbWVudGF0aW9uQ29uZmlnT3B0aW9uYWwpIHsKKyAgICB0aGlzLmV4cGVyaW1lbnRhdGlvbkNvbmZpZ09wdGlvbmFsID0gZXhwZXJpbWVudGF0aW9uQ29uZmlnT3B0aW9uYWw7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvLyBXZSB1c2UgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3IgZGlyZWN0bHkgdG8gY3JlYXRlIGRlZmF1bHQgQ29udHJvbCBFeGVjdXRvciBhbmQKKyAgLy8gRG93bmxvYWQgRXhlY3V0b3IuCisgIHB1YmxpYyBNb2JpbGVEYXRhRG93bmxvYWQgYnVpbGQoKSB7CisgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwoY29udGV4dCk7CisgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwodGFza1NjaGVkdWxlck9wdGlvbmFsKTsKKyAgICBQcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChmaWxlU3RvcmFnZSk7CisKKyAgICBQcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChuZXR3b3JrVXNhZ2VNb25pdG9yKTsKKyAgICBQcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChkb3dubG9hZE1vbml0b3JPcHRpb25hbCk7CisgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwoZmlsZURvd25sb2FkZXJTdXBwbGllcik7CisgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwoY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yT3B0aW9uYWwpOworCisgICAgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciA9IE1vcmVFeGVjdXRvcnMubmV3U2VxdWVudGlhbEV4ZWN1dG9yKGNvbnRyb2xFeGVjdXRvcik7CisgICAgaWYgKGNvbmZpZ3VyYXRvci5pc1ByZXNlbnQoKSkgeworICAgICAgLy8gU3VibWl0IGNvbW1pdCB0YXNrIHRvIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgdG8gZW5zdXJlIHRoYXQgdGhlIGNvbW1pdCB0YXNrIGZpbmlzaGVzCisgICAgICAvLyBiZWZvcmUgYW55IG90aGVyIEFQSSB0YXNrcyBjYW4gcnVuLgorICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjb21taXRGdXR1cmUgPQorICAgICAgICAgIEZ1dHVyZXMuc3VibWl0QXN5bmMoCisgICAgICAgICAgICAgICgpIC0+IGNvbmZpZ3VyYXRvci5nZXQoKS5jb21taXRUb0ZsYWdTbmFwc2hvdCgpLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKworICAgICAgRnV0dXJlcy5hZGRDYWxsYmFjaygKKyAgICAgICAgICBjb21taXRGdXR1cmUsCisgICAgICAgICAgbmV3IEZ1dHVyZUNhbGxiYWNrPFZvaWQ+KCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoVm9pZCByZXN1bHQpIHsKKyAgICAgICAgICAgICAgTG9nVXRpbC5kKCIlczogU3VjY2VlZGVkIGNvbW1pdFRvRmxhZ1NuYXBzaG90LiIsIFRBRyk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgcHVibGljIHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICAgIExvZ1V0aWwudygiJXM6IEZhaWxlZCB0byBjb21taXRUb0ZsYWdTbmFwc2hvdDogJXMiLCBUQUcsIHQpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0sCisgICAgICAgICAgTW9yZUV4ZWN1dG9ycy5kaXJlY3RFeGVjdXRvcigpIC8qZmluZSB0byB1c2UgZGlyZWN0RXhlY3V0b3Igc2luY2UgaXQgb25seSBwcmludCBsb2dzKi8pOworICAgIH0KKworICAgIGNvbXBvbmVudEJ1aWxkZXIuYXBwbGljYXRpb25Db250ZXh0TW9kdWxlKG5ldyBBcHBsaWNhdGlvbkNvbnRleHRNb2R1bGUoY29udGV4dCkpOworCisgICAgY29tcG9uZW50QnVpbGRlci5leGVjdXRvcnNNb2R1bGUobmV3IEV4ZWN1dG9yc01vZHVsZShzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKSk7CisKKyAgICBjb21wb25lbnRCdWlsZGVyLmRvd25sb2FkZXJNb2R1bGUoCisgICAgICAgIG5ldyBEb3dubG9hZGVyTW9kdWxlKGRlbHRhRGVjb2Rlck9wdGlvbmFsLCBmaWxlRG93bmxvYWRlclN1cHBsaWVyKSk7CisKKyAgICBGbGFncyBmbGFncyA9IGZsYWdzT3B0aW9uYWwub3IobmV3IEZsYWdzKCkge30pOworCisgICAgLy8gRXZlbnRMb2dnZXIgaXMgbmVlZGVkIGluIEZyYW1ld29ya1Byb3RvRGF0YVN0b3JlTW9kdWxlLCB3aGljaCBpcyBhIHN0aW5nIG1vZHVsZS4gQXMgc3VjaCBpdAorICAgIC8vIGNhbm5vdCBiZSBjb25zdHJ1Y3RlZCBpbiBvdXIgaW50ZXJuYWwgZGFnZ2VyIG1vZHVsZSBpZiB3ZSB3YW50IHRvIHNoYXJlIHRoZSBzYW1lIEV2ZW50TG9nZ2VyCisgICAgLy8gdGhyb3VnaG91dCB0aGUgbGlicmFyeS4KKyAgICBmaW5hbCBFdmVudExvZ2dlciBldmVudExvZ2dlcjsKKyAgICBpZiAobG9nZ2VyT3B0aW9uYWwuaXNQcmVzZW50KCkpIHsKKyAgICAgIGV2ZW50TG9nZ2VyID0KKyAgICAgICAgICBuZXcgTWRkRXZlbnRMb2dnZXIoCisgICAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICAgIGxvZ2dlck9wdGlvbmFsLmdldCgpLAorICAgICAgICAgICAgICBDb25zdGFudHMuTUREX0xJQl9WRVJTSU9OLAorICAgICAgICAgICAgICBuZXcgTG9nU2FtcGxlcihmbGFncywgbmV3IFNlY3VyZVJhbmRvbSgpKSwKKyAgICAgICAgICAgICAgZmxhZ3MpOworICAgIH0gZWxzZSB7CisgICAgICBldmVudExvZ2dlciA9IG5ldyBOb09wRXZlbnRMb2dnZXIoKTsKKyAgICB9CisKKyAgICBpZiAodXNlRGVmYXVsdEFjY291bnRTb3VyY2UpIHsKKyAgICAgIGFjY291bnRTb3VyY2VPcHRpb25hbCA9IE9wdGlvbmFsLm9mKG5ldyBBY2NvdW50TWFuYWdlckFjY291bnRTb3VyY2UoY29udGV4dCkpOworICAgIH0KKworICAgIGNvbXBvbmVudEJ1aWxkZXIubWFpbk1kZExpYk1vZHVsZSgKKyAgICAgICAgbmV3IE1haW5NZGRMaWJNb2R1bGUoCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIG5ldHdvcmtVc2FnZU1vbml0b3IsCisgICAgICAgICAgICBldmVudExvZ2dlciwKKyAgICAgICAgICAgIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLAorICAgICAgICAgICAgc2lsZW50RmVlZGJhY2tPcHRpb25hbCwKKyAgICAgICAgICAgIGluc3RhbmNlSWRPcHRpb25hbCwKKyAgICAgICAgICAgIGFjY291bnRTb3VyY2VPcHRpb25hbCwKKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgZXhwZXJpbWVudGF0aW9uQ29uZmlnT3B0aW9uYWwpKTsKKworICAgIFN0YW5kYWxvbmVDb21wb25lbnQgY29tcG9uZW50ID0gY29tcG9uZW50QnVpbGRlci5idWlsZCgpOworCisgICAgaWYgKGV2ZW50TG9nZ2VyIGluc3RhbmNlb2YgTWRkRXZlbnRMb2dnZXIpIHsKKyAgICAgICgoTWRkRXZlbnRMb2dnZXIpIGV2ZW50TG9nZ2VyKS5zZXRMb2dnaW5nU3RhdGVTdG9yZShjb21wb25lbnQuZ2V0TG9nZ2luZ1N0YXRlU3RvcmUoKSk7CisgICAgfQorCisgICAgRG93bmxvYWRlci5CdWlsZGVyIHNpbmdsZUZpbGVEb3dubG9hZGVyQnVpbGRlciA9CisgICAgICAgIERvd25sb2FkZXIubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0Q29udGV4dChjb250ZXh0KQorICAgICAgICAgICAgLnNldENvbnRyb2xFeGVjdXRvcihzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAgICAgLnNldEZpbGVEb3dubG9hZGVyU3VwcGxpZXIoZmlsZURvd25sb2FkZXJTdXBwbGllcik7CisKKyAgICBpZiAoZG93bmxvYWRNb25pdG9yT3B0aW9uYWwuaXNQcmVzZW50KCkpIHsKKyAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyQnVpbGRlci5zZXREb3dubG9hZE1vbml0b3IoZG93bmxvYWRNb25pdG9yT3B0aW9uYWwuZ2V0KCkpOworICAgIH0KKworICAgIGlmIChmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXJCdWlsZGVyLnNldEZvcmVncm91bmREb3dubG9hZFNlcnZpY2UoCisgICAgICAgICAgZm9yZWdyb3VuZERvd25sb2FkU2VydmljZUNsYXNzT3B0aW9uYWwuZ2V0KCkpOworICAgIH0KKyAgICBEb3dubG9hZGVyIHNpbmdsZUZpbGVEb3dubG9hZGVyID0gc2luZ2xlRmlsZURvd25sb2FkZXJCdWlsZGVyLmJ1aWxkKCk7CisKKyAgICByZXR1cm4gbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgIGNvbnRleHQsCisgICAgICAgIGNvbXBvbmVudC5nZXRFdmVudExvZ2dlcigpLAorICAgICAgICBjb21wb25lbnQuZ2V0TW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcigpLAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLAorICAgICAgICBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0LAorICAgICAgICB0YXNrU2NoZWR1bGVyT3B0aW9uYWwsCisgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICBkb3dubG9hZE1vbml0b3JPcHRpb25hbCwKKyAgICAgICAgZm9yZWdyb3VuZERvd25sb2FkU2VydmljZUNsYXNzT3B0aW9uYWwsCisgICAgICAgIGZsYWdzLAorICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yT3B0aW9uYWwpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL01vYmlsZURhdGFEb3dubG9hZEltcGwuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvTW9iaWxlRGF0YURvd25sb2FkSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQyMDFiMTkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL01vYmlsZURhdGFEb3dubG9hZEltcGwuamF2YQpAQCAtMCwwICsxLDEzMTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRyYWNpbmcuVHJhY2VQcm9wYWdhdGlvbi5wcm9wYWdhdGVBc3luY0NhbGxhYmxlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlRyYWNlUHJvcGFnYXRpb24ucHJvcGFnYXRlQXN5bmNGdW5jdGlvbjsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5UcmFjZVByb3BhZ2F0aW9uLnByb3BhZ2F0ZUNhbGxhYmxlOworCitpbXBvcnQgYW5kcm9pZC5hY2NvdW50cy5BY2NvdW50OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnRleHQuVGV4dFV0aWxzOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGFuZHJvaWR4LmFubm90YXRpb24uVmlzaWJsZUZvclRlc3Rpbmc7CitpbXBvcnQgYW5kcm9pZHguY29yZS5hcHAuTm90aWZpY2F0aW9uQ29tcGF0OworaW1wb3J0IGFuZHJvaWR4LmNvcmUuYXBwLk5vdGlmaWNhdGlvbk1hbmFnZXJDb21wYXQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb24uRG93bmxvYWRSZXN1bHRDb2RlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlRhc2tTY2hlZHVsZXIuQ29uc3RyYWludE92ZXJyaWRlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UYXNrU2NoZWR1bGVyLk5ldHdvcmtTdGF0ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5hY2NvdW50LkFjY291bnRVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5mb3JlZ3JvdW5kLk5vdGlmaWNhdGlvblV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkV2ZW50TG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLk1kZExpdGVDb252ZXJzaW9uVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLlByb3RvQ29udmVyc2lvblV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubGl0ZS5Eb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuRG93bmxvYWRQcm9ncmVzc01vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlByZWNvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlU2V0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Bc3luY0Z1bmN0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25TZXF1ZW5jZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZsdWVudEZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlQ2FsbGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuQ2xpZW50Q29uZmlnUHJvdG8uQ2xpZW50RmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5DbGllbnRDb25maWdQcm90by5DbGllbnRGaWxlR3JvdXA7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90bzsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlR3JvdXA7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkdyb3VwS2V5OworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuQW55OworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZUxpdGU7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZW91dEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworLyoqCisgKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvciB7QGxpbmsKKyAqIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLk1vYmlsZURhdGFEb3dubG9hZH0uCisgKi8KK2NsYXNzIE1vYmlsZURhdGFEb3dubG9hZEltcGwgaW1wbGVtZW50cyBNb2JpbGVEYXRhRG93bmxvYWQgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIk1vYmlsZURhdGFEb3dubG9hZCI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgRFVNUF9ERUJVR19JTkZPX1RJTUVPVVQgPSAzOworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIGZpbmFsIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyOworICBwcml2YXRlIGZpbmFsIExpc3Q8RmlsZUdyb3VwUG9wdWxhdG9yPiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0OworICBwcml2YXRlIGZpbmFsIE9wdGlvbmFsPFRhc2tTY2hlZHVsZXI+IHRhc2tTY2hlZHVsZXJPcHRpb25hbDsKKyAgcHJpdmF0ZSBmaW5hbCBNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyIG1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXI7CisgIHByaXZhdGUgZmluYWwgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHJpdmF0ZSBmaW5hbCBGbGFncyBmbGFnczsKKyAgcHJpdmF0ZSBmaW5hbCBEb3dubG9hZGVyIHNpbmdsZUZpbGVEb3dubG9hZGVyOworCisgIC8vIFRoaXMgZXhlY3V0b3Igd2lsbCBleGVjdXRlIHRhc2tzIHNlcXVlbnRpYWxseS4KKyAgcHJpdmF0ZSBmaW5hbCBFeGVjdXRvciBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworICAvLyBFeGVjdXRpb25TZXF1ZW5jZXIgd2lsbCBleGVjdXRlIGEgTGlzdGVuYWJsZUZ1dHVyZSBhbmQgaXRzIEZ1dHVyZXMudHJhbnNmb3JtcyBiZWZvcmUgdGFraW5nIHRoZQorICAvLyBuZXh0IHRhc2sgKDxpbnRlcm5hbD4pLiBNb3N0IG9mIE1ERCBBUEkgc2hvdWxkIHVzZQorICAvLyBFeGVjdXRpb25TZXF1ZW5jZXIgdG8gZ3VhcmFudGVlIE1ldGFkYXRhIHN5bmNocm9uaXphdGlvbi4gQ3VycmVudGx5IG9ubHkgZG93bmxvYWRGaWxlR3JvdXAgYW5kCisgIC8vIGhhbmRsZVRhc2sgQVBJcyBkbyBub3QgdXNlIEV4ZWN1dGlvblNlcXVlbmNlciBzaW5jZSB0aGVpciBleGVjdXRpb24gY291bGQgdGFrZSBsb25nIHRpbWUgYW5kCisgIC8vIHVzaW5nIEV4ZWN1dGlvblNlcXVlbmNlciB3b3VsZCBibG9jayBvdGhlciBBUElzLgorICBwcml2YXRlIGZpbmFsIEV4ZWN1dGlvblNlcXVlbmNlciBmdXR1cmVTZXJpYWxpemVyID0gRXhlY3V0aW9uU2VxdWVuY2VyLmNyZWF0ZSgpOworICBwcml2YXRlIGZpbmFsIE9wdGlvbmFsPERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yPiBkb3dubG9hZE1vbml0b3JPcHRpb25hbDsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxDbGFzczw/Pj4gZm9yZWdyb3VuZERvd25sb2FkU2VydmljZUNsYXNzT3B0aW9uYWw7CisgIHByaXZhdGUgZmluYWwgQXN5bmNGdW5jdGlvbjxEYXRhRmlsZUdyb3VwSW50ZXJuYWwsIEJvb2xlYW4+IGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvcjsKKworICAvLyBTeW5jaHJvbml6YXRpb24gd2lsbCBiZSBkb25lIHRocm91Z2ggc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcgorICAvLyBLZWVwIGFsbCB0aGUgb24tZ29pbmcgZm9yZWdyb3VuZCBkb3dubG9hZHMuCisgIEBWaXNpYmxlRm9yVGVzdGluZworICBmaW5hbCBNYXA8U3RyaW5nLCBMaXN0ZW5hYmxlRnV0dXJlPENsaWVudEZpbGVHcm91cD4+IGtleVRvTGlzdGVuYWJsZUZ1dHVyZSA9IG5ldyBIYXNoTWFwPD4oKTsKKworICBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgQ29udGV4dCBjb250ZXh0LAorICAgICAgRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXIsCisgICAgICBNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyIG1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICBFeGVjdXRvciBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLAorICAgICAgTGlzdDxGaWxlR3JvdXBQb3B1bGF0b3I+IGZpbGVHcm91cFBvcHVsYXRvckxpc3QsCisgICAgICBPcHRpb25hbDxUYXNrU2NoZWR1bGVyPiB0YXNrU2NoZWR1bGVyT3B0aW9uYWwsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLAorICAgICAgT3B0aW9uYWw8RG93bmxvYWRQcm9ncmVzc01vbml0b3I+IGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLAorICAgICAgT3B0aW9uYWw8Q2xhc3M8Pz4+IGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsLAorICAgICAgRmxhZ3MgZmxhZ3MsCisgICAgICBEb3dubG9hZGVyIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgT3B0aW9uYWw8Q3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yPiBjdXN0b21WYWxpZGF0b3JPcHRpb25hbCkgeworICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CisgICAgdGhpcy5ldmVudExvZ2dlciA9IGV2ZW50TG9nZ2VyOworICAgIHRoaXMuZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9IGZpbGVHcm91cFBvcHVsYXRvckxpc3Q7CisgICAgdGhpcy50YXNrU2NoZWR1bGVyT3B0aW9uYWwgPSB0YXNrU2NoZWR1bGVyT3B0aW9uYWw7CisgICAgdGhpcy5zZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yID0gc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKyAgICB0aGlzLm1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIgPSBtb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyOworICAgIHRoaXMuZmlsZVN0b3JhZ2UgPSBmaWxlU3RvcmFnZTsKKyAgICB0aGlzLmRvd25sb2FkTW9uaXRvck9wdGlvbmFsID0gZG93bmxvYWRNb25pdG9yT3B0aW9uYWw7CisgICAgdGhpcy5mb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbCA9IGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsOworICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKKyAgICB0aGlzLnNpbmdsZUZpbGVEb3dubG9hZGVyID0gc2luZ2xlRmlsZURvd25sb2FkZXI7CisgICAgdGhpcy5jdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgPQorICAgICAgICBjcmVhdGVDdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IoCisgICAgICAgICAgICBjdXN0b21WYWxpZGF0b3JPcHRpb25hbCwKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UpOworICB9CisKKyAgLy8gV3JhcHMgdGhlIGN1c3RvbSB2YWxpZGF0b3IgYmVjYXVzZSB0aGUgdmFsaWRhdGlvbiBhdCBhIGxvd2VyIGxldmVsIG9mIHRoZSBzdGFjayB3aGVyZQorICAvLyB0aGUgQ2xpZW50RmlsZUdyb3VwIGlzIG5vdCBhdmFpbGFibGUsIHlldCBDbGllbnRGaWxlR3JvdXAgaXMgdGhlIGNsaWVudC1mYWNpbmcgQVBJIHdlJ2QKKyAgLy8gbGlrZSB0byBleHBvc2UuCisgIHByaXZhdGUgc3RhdGljIEFzeW5jRnVuY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsLCBCb29sZWFuPiBjcmVhdGVDdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IoCisgICAgICBPcHRpb25hbDxDdXN0b21GaWxlR3JvdXBWYWxpZGF0b3I+IHZhbGlkYXRvck9wdGlvbmFsLAorICAgICAgTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciBtb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgRXhlY3V0b3IgZXhlY3V0b3IsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlKSB7CisgICAgaWYgKCF2YWxpZGF0b3JPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgcmV0dXJuIHVudXNlZCAtPiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKTsKKyAgICB9CisKKyAgICByZXR1cm4gaW50ZXJuYWxGaWxlR3JvdXAgLT4KKyAgICAgICAgRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIGNyZWF0ZUNsaWVudEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICBpbnRlcm5hbEZpbGVHcm91cCwKKyAgICAgICAgICAgICAgICAvKiBhY2NvdW50PSAqLyBudWxsLAorICAgICAgICAgICAgICAgIENsaWVudEZpbGVHcm91cC5TdGF0dXMuUEVORElOR19DVVNUT01fVkFMSURBVElPTiwKKyAgICAgICAgICAgICAgICAvKiBwcmVzZXJ2ZVppcERpcmVjdG9yaWVzPSAqLyBmYWxzZSwKKyAgICAgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgICAgIGV4ZWN1dG9yLAorICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlKSwKKyAgICAgICAgICAgIHByb3BhZ2F0ZUFzeW5jRnVuY3Rpb24oCisgICAgICAgICAgICAgICAgY2xpZW50RmlsZUdyb3VwIC0+IHZhbGlkYXRvck9wdGlvbmFsLmdldCgpLnZhbGlkYXRlRmlsZUdyb3VwKGNsaWVudEZpbGVHcm91cCkpLAorICAgICAgICAgICAgZXhlY3V0b3IpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IGFkZEZpbGVHcm91cChBZGRGaWxlR3JvdXBSZXF1ZXN0IGFkZEZpbGVHcm91cFJlcXVlc3QpIHsKKyAgICByZXR1cm4gZnV0dXJlU2VyaWFsaXplci5zdWJtaXRBc3luYygKKyAgICAgICAgcHJvcGFnYXRlQXN5bmNDYWxsYWJsZSgKKyAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgTG9nVXRpbC5kKAorICAgICAgICAgICAgICAgICAgIiVzOiBBZGRpbmcgZm9yIGRvd25sb2FkIGdyb3VwID0gJyVzJywgdmFyaWFudCA9ICclcycgYW5kIGFzc29jaWF0aW5nIGl0IHdpdGgiCisgICAgICAgICAgICAgICAgICAgICAgKyAiIGFjY291bnQgPSAnJXMnLCB2YXJpYW50ID0gJyVzJyIsCisgICAgICAgICAgICAgICAgICBUQUcsCisgICAgICAgICAgICAgICAgICBhZGRGaWxlR3JvdXBSZXF1ZXN0LmRhdGFGaWxlR3JvdXAoKS5nZXRHcm91cE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgIGFkZEZpbGVHcm91cFJlcXVlc3QuZGF0YUZpbGVHcm91cCgpLmdldFZhcmlhbnRJZCgpLAorICAgICAgICAgICAgICAgICAgU3RyaW5nLnZhbHVlT2YoYWRkRmlsZUdyb3VwUmVxdWVzdC5hY2NvdW50T3B0aW9uYWwoKS5vck51bGwoKSksCisgICAgICAgICAgICAgICAgICBTdHJpbmcudmFsdWVPZihhZGRGaWxlR3JvdXBSZXF1ZXN0LnZhcmlhbnRJZE9wdGlvbmFsKCkub3JOdWxsKCkpKTsKKworICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXAgPSBhZGRGaWxlR3JvdXBSZXF1ZXN0LmRhdGFGaWxlR3JvdXAoKTsKKworICAgICAgICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgb3duZXIgcGFja2FnZSBpcyBhbHdheXMgc2V0IGFzIHRoZSBob3N0IGFwcC4KKyAgICAgICAgICAgICAgaWYgKCFkYXRhRmlsZUdyb3VwLmhhc093bmVyUGFja2FnZSgpKSB7CisgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkuYnVpbGQoKTsKKyAgICAgICAgICAgICAgfSBlbHNlIGlmICghY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLmVxdWFscyhkYXRhRmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKSkgeworICAgICAgICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgICAgICAgIiVzOiBBZGRlZCBncm91cCA9ICclcycgd2l0aCB3cm9uZyBvd25lciBwYWNrYWdlOiAnJXMnIHYucy4gJyVzJyAiLAorICAgICAgICAgICAgICAgICAgICBUQUcsCisgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCksCisgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRPd25lclBhY2thZ2UoKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIEdyb3VwS2V5LkJ1aWxkZXIgZ3JvdXBLZXlCdWlsZGVyID0KKyAgICAgICAgICAgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkKKyAgICAgICAgICAgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGRhdGFGaWxlR3JvdXAuZ2V0T3duZXJQYWNrYWdlKCkpOworCisgICAgICAgICAgICAgIGlmIChhZGRGaWxlR3JvdXBSZXF1ZXN0LmFjY291bnRPcHRpb25hbCgpLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICAgICAgZ3JvdXBLZXlCdWlsZGVyLnNldEFjY291bnQoCisgICAgICAgICAgICAgICAgICAgIEFjY291bnRVdGlsLnNlcmlhbGl6ZShhZGRGaWxlR3JvdXBSZXF1ZXN0LmFjY291bnRPcHRpb25hbCgpLmdldCgpKSk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICBpZiAoYWRkRmlsZUdyb3VwUmVxdWVzdC52YXJpYW50SWRPcHRpb25hbCgpLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICAgICAgZ3JvdXBLZXlCdWlsZGVyLnNldFZhcmlhbnRJZChhZGRGaWxlR3JvdXBSZXF1ZXN0LnZhcmlhbnRJZE9wdGlvbmFsKCkuZ2V0KCkpOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cEludGVybmFsID0KKyAgICAgICAgICAgICAgICAgICAgUHJvdG9Db252ZXJzaW9uVXRpbC5jb252ZXJ0KGRhdGFGaWxlR3JvdXApOworICAgICAgICAgICAgICAgIHJldHVybiBtb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWRJbnRlcm5hbCgKKyAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXlCdWlsZGVyLmJ1aWxkKCksIGRhdGFGaWxlR3JvdXBJbnRlcm5hbCwgY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yKTsKKyAgICAgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAvLyBUT0RPKGIvMTE4MTM3NjcyKTogQ29uc2lkZXIgcmV0aHJvdyBleGNlcHRpb24gaW5zdGVhZCBvZiByZXR1cm5pbmcgZmFsc2UuCisgICAgICAgICAgICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICAgICAgICAgICBlLCAiJXM6IFVuYWJsZSB0byBjb252ZXJ0IGZyb20gRGF0YUZpbGVHcm91cCB0byBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuIiwgVEFHKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmFsc2UpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvLyBUT0RPOiBDaGFuZ2UgdG8gcmV0dXJuIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4uCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiByZW1vdmVGaWxlR3JvdXAoUmVtb3ZlRmlsZUdyb3VwUmVxdWVzdCByZW1vdmVGaWxlR3JvdXBSZXF1ZXN0KSB7CisgICAgcmV0dXJuIGZ1dHVyZVNlcmlhbGl6ZXIuc3VibWl0QXN5bmMoCisgICAgICAgICgpIC0+IHsKKyAgICAgICAgICBHcm91cEtleS5CdWlsZGVyIGdyb3VwS2V5QnVpbGRlciA9CisgICAgICAgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShyZW1vdmVGaWxlR3JvdXBSZXF1ZXN0Lmdyb3VwTmFtZSgpKQorICAgICAgICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgICAgICAgIGlmIChyZW1vdmVGaWxlR3JvdXBSZXF1ZXN0LmFjY291bnRPcHRpb25hbCgpLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICBncm91cEtleUJ1aWxkZXIuc2V0QWNjb3VudCgKKyAgICAgICAgICAgICAgICBBY2NvdW50VXRpbC5zZXJpYWxpemUocmVtb3ZlRmlsZUdyb3VwUmVxdWVzdC5hY2NvdW50T3B0aW9uYWwoKS5nZXQoKSkpOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAocmVtb3ZlRmlsZUdyb3VwUmVxdWVzdC52YXJpYW50SWRPcHRpb25hbCgpLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICBncm91cEtleUJ1aWxkZXIuc2V0VmFyaWFudElkKHJlbW92ZUZpbGVHcm91cFJlcXVlc3QudmFyaWFudElkT3B0aW9uYWwoKS5nZXQoKSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPSBncm91cEtleUJ1aWxkZXIuYnVpbGQoKTsKKyAgICAgICAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm0oCisgICAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIucmVtb3ZlRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksIHJlbW92ZUZpbGVHcm91cFJlcXVlc3QucGVuZGluZ09ubHkoKSksCisgICAgICAgICAgICAgIHZvaWRBcmcgLT4gdHJ1ZSwKKyAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlc3BvbnNlPiByZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXIoCisgICAgICBSZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0IHJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QpIHsKKyAgICByZXR1cm4gZnV0dXJlU2VyaWFsaXplci5zdWJtaXRBc3luYygKKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIEZsdWVudEZ1dHVyZS5mcm9tKG1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0QWxsRnJlc2hHcm91cHMoKSkKKyAgICAgICAgICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgIGFsbEZyZXNoR3JvdXBzIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICBJbW11dGFibGVTZXQuQnVpbGRlcjxHcm91cEtleT4gZ3JvdXBLZXlzVG9SZW1vdmVCdWlsZGVyID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgSW1tdXRhYmxlU2V0LmJ1aWxkZXIoKTsKKyAgICAgICAgICAgICAgICAgICAgICBmb3IgKFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4ga2V5RGF0YUZpbGVHcm91cFBhaXIgOgorICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxGcmVzaEdyb3VwcykgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFwcGx5UmVtb3ZlRmlsZUdyb3Vwc0ZpbHRlcigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0LCBrZXlEYXRhRmlsZUdyb3VwUGFpcikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGRvd25sb2FkZWQgc3RhdHVzIHNvIHBlbmRpbmcvZG93bmxvYWRlZCB2ZXJzaW9ucyBvZiB0aGUgc2FtZQorICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBncm91cCBhcmUgdHJlYXRlZCBhcyBvbmUuCisgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5c1RvUmVtb3ZlQnVpbGRlci5hZGQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlEYXRhRmlsZUdyb3VwUGFpci5maXJzdC50b0J1aWxkZXIoKS5jbGVhckRvd25sb2FkZWQoKS5idWlsZCgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgSW1tdXRhYmxlU2V0PEdyb3VwS2V5PiBncm91cEtleXNUb1JlbW92ZSA9IGdyb3VwS2V5c1RvUmVtb3ZlQnVpbGRlci5idWlsZCgpOworICAgICAgICAgICAgICAgICAgICAgIGlmIChncm91cEtleXNUb1JlbW92ZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXNwb25zZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFJlbW92ZWRGaWxlR3JvdXBzQ291bnQoMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIucmVtb3ZlRmlsZUdyb3Vwcyhncm91cEtleXNUb1JlbW92ZS5hc0xpc3QoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgIHVudXNlZCAtPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVzcG9uc2UubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFJlbW92ZWRGaWxlR3JvdXBzQ291bnQoZ3JvdXBLZXlzVG9SZW1vdmUuc2l6ZSgpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciksCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLy8gUGVyZm9ybSBmaWx0ZXJpbmcgdXNpbmcgb3B0aW9ucyBmcm9tIFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QKKyAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBhcHBseVJlbW92ZUZpbGVHcm91cHNGaWx0ZXIoCisgICAgICBSZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0IHJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QsCisgICAgICBQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGtleURhdGFGaWxlR3JvdXBQYWlyKSB7CisgICAgLy8gSWYgcmVxdWVzdCBmaWx0ZXJzIGJ5IGFjY291bnQsIGVuc3VyZSBhY2NvdW50IGlzIHByZXNlbnQgYW5kIGlzIGVxdWFsCisgICAgT3B0aW9uYWw8QWNjb3VudD4gYWNjb3VudE9wdGlvbmFsID0gcmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5hY2NvdW50T3B0aW9uYWwoKTsKKyAgICBpZiAoIWFjY291bnRPcHRpb25hbC5pc1ByZXNlbnQoKSAmJiBrZXlEYXRhRmlsZUdyb3VwUGFpci5maXJzdC5oYXNBY2NvdW50KCkpIHsKKyAgICAgIC8vIEFjY291bnQgbXVzdCBleHBsaWNpdGx5IGJlIHByb3ZpZGVkIGluIG9yZGVyIHRvIHJlbW92ZSBhY2NvdW50IGFzc29jaWF0ZWQgZmlsZSBncm91cHMuCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChhY2NvdW50T3B0aW9uYWwuaXNQcmVzZW50KCkKKyAgICAgICAgJiYgIUFjY291bnRVdGlsLnNlcmlhbGl6ZShhY2NvdW50T3B0aW9uYWwuZ2V0KCkpCisgICAgICAgICAgICAuZXF1YWxzKGtleURhdGFGaWxlR3JvdXBQYWlyLmZpcnN0LmdldEFjY291bnQoKSkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIFRPRE86IEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpIHVzZXMgYSBkaWZmZXJlbnQgYW5ub3RhdGlvbiBmb3IgTnVsbGFibGUuCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJudWxsbmVzcyIpCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxDbGllbnRGaWxlR3JvdXA+IGdldEZpbGVHcm91cChHZXRGaWxlR3JvdXBSZXF1ZXN0IGdldEZpbGVHcm91cFJlcXVlc3QpIHsKKyAgICByZXR1cm4gZnV0dXJlU2VyaWFsaXplci5zdWJtaXRBc3luYygKKyAgICAgICAgKCkgLT4geworICAgICAgICAgIEdyb3VwS2V5LkJ1aWxkZXIgZ3JvdXBLZXlCdWlsZGVyID0KKyAgICAgICAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKGdldEZpbGVHcm91cFJlcXVlc3QuZ3JvdXBOYW1lKCkpCisgICAgICAgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisKKyAgICAgICAgICBpZiAoZ2V0RmlsZUdyb3VwUmVxdWVzdC5hY2NvdW50T3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgZ3JvdXBLZXlCdWlsZGVyLnNldEFjY291bnQoCisgICAgICAgICAgICAgICAgQWNjb3VudFV0aWwuc2VyaWFsaXplKGdldEZpbGVHcm91cFJlcXVlc3QuYWNjb3VudE9wdGlvbmFsKCkuZ2V0KCkpKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICBpZiAoZ2V0RmlsZUdyb3VwUmVxdWVzdC52YXJpYW50SWRPcHRpb25hbCgpLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICBncm91cEtleUJ1aWxkZXIuc2V0VmFyaWFudElkKGdldEZpbGVHcm91cFJlcXVlc3QudmFyaWFudElkT3B0aW9uYWwoKS5nZXQoKSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPSBncm91cEtleUJ1aWxkZXIuYnVpbGQoKTsKKyAgICAgICAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXksIC8qZG93bmxvYWRlZD0qLyB0cnVlKSwKKyAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cCAtPgorICAgICAgICAgICAgICAgICAgY3JlYXRlQ2xpZW50RmlsZUdyb3VwQW5kTG9nUXVlcnlTdGF0cygKKyAgICAgICAgICAgICAgICAgICAgICBncm91cEtleSwKKyAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLAorICAgICAgICAgICAgICAgICAgICAgIC8qZG93bmxvYWRlZD0qLyB0cnVlLAorICAgICAgICAgICAgICAgICAgICAgIGdldEZpbGVHcm91cFJlcXVlc3QucHJlc2VydmVaaXBEaXJlY3RvcmllcygpKSwKKyAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPENsaWVudEZpbGVHcm91cD4gY3JlYXRlQ2xpZW50RmlsZUdyb3VwQW5kTG9nUXVlcnlTdGF0cygKKyAgICAgIEdyb3VwS2V5IGdyb3VwS2V5LAorICAgICAgQE51bGxhYmxlIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwLAorICAgICAgYm9vbGVhbiBkb3dubG9hZGVkLAorICAgICAgYm9vbGVhbiBwcmVzZXJ2ZVppcERpcmVjdG9yaWVzKSB7CisgICAgcmV0dXJuIEZ1dHVyZXMudHJhbnNmb3JtKAorICAgICAgICBjcmVhdGVDbGllbnRGaWxlR3JvdXAoCisgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLAorICAgICAgICAgICAgZ3JvdXBLZXkuaGFzQWNjb3VudCgpID8gZ3JvdXBLZXkuZ2V0QWNjb3VudCgpIDogbnVsbCwKKyAgICAgICAgICAgIGRvd25sb2FkZWQgPyBDbGllbnRGaWxlR3JvdXAuU3RhdHVzLkRPV05MT0FERUQgOiBDbGllbnRGaWxlR3JvdXAuU3RhdHVzLlBFTkRJTkcsCisgICAgICAgICAgICBwcmVzZXJ2ZVppcERpcmVjdG9yaWVzLAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IsCisgICAgICAgICAgICBmaWxlU3RvcmFnZSksCisgICAgICAgIGNsaWVudEZpbGVHcm91cCAtPiB7CisgICAgICAgICAgaWYgKGNsaWVudEZpbGVHcm91cCAhPSBudWxsKSB7CisgICAgICAgICAgICBldmVudExvZ2dlci5sb2dNZGRRdWVyeVN0YXRzKGNyZWF0ZUZpbGVHcm91cERldGFpbHMoY2xpZW50RmlsZUdyb3VwKSk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBjbGllbnRGaWxlR3JvdXA7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgQFN1cHByZXNzV2FybmluZ3MoIm51bGxuZXNzIikKKyAgcHJpdmF0ZSBzdGF0aWMgTGlzdGVuYWJsZUZ1dHVyZTxDbGllbnRGaWxlR3JvdXA+IGNyZWF0ZUNsaWVudEZpbGVHcm91cCgKKyAgICAgIEBOdWxsYWJsZSBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCwKKyAgICAgIEBOdWxsYWJsZSBTdHJpbmcgYWNjb3VudCwKKyAgICAgIENsaWVudEZpbGVHcm91cC5TdGF0dXMgc3RhdHVzLAorICAgICAgYm9vbGVhbiBwcmVzZXJ2ZVppcERpcmVjdG9yaWVzLAorICAgICAgTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciBtYW5hZ2VyLAorICAgICAgRXhlY3V0b3IgZXhlY3V0b3IsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlKSB7CisgICAgaWYgKGRhdGFGaWxlR3JvdXAgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpOworICAgIH0KKyAgICBDbGllbnRGaWxlR3JvdXAuQnVpbGRlciBjbGllbnRGaWxlR3JvdXBCdWlsZGVySW5pdCA9CisgICAgICAgIENsaWVudEZpbGVHcm91cC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoZGF0YUZpbGVHcm91cC5nZXRPd25lclBhY2thZ2UoKSkKKyAgICAgICAgICAgIC5zZXRWZXJzaW9uTnVtYmVyKGRhdGFGaWxlR3JvdXAuZ2V0RmlsZUdyb3VwVmVyc2lvbk51bWJlcigpKQorICAgICAgICAgICAgLnNldEJ1aWxkSWQoZGF0YUZpbGVHcm91cC5nZXRCdWlsZElkKCkpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKGRhdGFGaWxlR3JvdXAuZ2V0VmFyaWFudElkKCkpCisgICAgICAgICAgICAuc2V0U3RhdHVzKHN0YXR1cykKKyAgICAgICAgICAgIC5hZGRBbGxMb2NhbGUoZGF0YUZpbGVHcm91cC5nZXRMb2NhbGVMaXN0KCkpOworCisgICAgaWYgKGFjY291bnQgIT0gbnVsbCkgeworICAgICAgY2xpZW50RmlsZUdyb3VwQnVpbGRlckluaXQuc2V0QWNjb3VudChhY2NvdW50KTsKKyAgICB9CisKKyAgICBpZiAoZGF0YUZpbGVHcm91cC5oYXNDdXN0b21NZXRhZGF0YSgpKSB7CisgICAgICBjbGllbnRGaWxlR3JvdXBCdWlsZGVySW5pdC5zZXRDdXN0b21NZXRhZGF0YShkYXRhRmlsZUdyb3VwLmdldEN1c3RvbU1ldGFkYXRhKCkpOworICAgIH0KKworICAgIExpc3RlbmFibGVGdXR1cmU8Q2xpZW50RmlsZUdyb3VwLkJ1aWxkZXI+IGNsaWVudEZpbGVHcm91cEJ1aWxkZXJGdXR1cmUgPQorICAgICAgICBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShjbGllbnRGaWxlR3JvdXBCdWlsZGVySW5pdCk7CisgICAgZm9yIChEYXRhRmlsZSBkYXRhRmlsZSA6IGRhdGFGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKSkgeworICAgICAgY2xpZW50RmlsZUdyb3VwQnVpbGRlckZ1dHVyZSA9CisgICAgICAgICAgRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgY2xpZW50RmlsZUdyb3VwQnVpbGRlckZ1dHVyZSwKKyAgICAgICAgICAgICAgY2xpZW50RmlsZUdyb3VwQnVpbGRlciAtPiB7CisgICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSBDbGllbnRGaWxlR3JvdXAuU3RhdHVzLkRPV05MT0FERUQKKyAgICAgICAgICAgICAgICAgICAgfHwgc3RhdHVzID09IENsaWVudEZpbGVHcm91cC5TdGF0dXMuUEVORElOR19DVVNUT01fVkFMSURBVElPTikgeworICAgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgbWFuYWdlci5nZXREYXRhRmlsZVVyaShkYXRhRmlsZSwgZGF0YUZpbGVHcm91cCksCisgICAgICAgICAgICAgICAgICAgICAgZmlsZVVyaSAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZVVyaSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERvd25sb2FkUmVzdWx0Q29kZS5ET1dOTE9BREVEX0ZJTEVfTk9UX0ZPVU5EX0VSUk9SKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRNZXNzYWdlKCJnZXREYXRhRmlsZVVyaSgpIHJlc29sdmVkIHRvIG51bGwiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcHJlc2VydmVaaXBEaXJlY3RvcmllcyAmJiBmaWxlU3RvcmFnZS5pc0RpcmVjdG9yeShmaWxlVXJpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyByb290UGF0aCA9IGZpbGVVcmkuZ2V0UGF0aCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyb290UGF0aCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRGaWxlR3JvdXBCdWlsZGVyLmFkZEFsbEZpbGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdEFsbENsaWVudEZpbGVzT2ZEaXJlY3RvcnkoZmlsZVN0b3JhZ2UsIGZpbGVVcmksIHJvb3RQYXRoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudEZpbGVHcm91cEJ1aWxkZXIuYWRkRmlsZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ2xpZW50RmlsZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0Qnl0ZVNpemUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLmdldERvd25sb2FkZWRGaWxlQnl0ZVNpemUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVVcmkudG9TdHJpbmcoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLmhhc0N1c3RvbU1ldGFkYXRhKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGRhdGFGaWxlLmdldEN1c3RvbU1ldGFkYXRhKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGwpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoZSwgIkZhaWxlZCB0byBsaXN0IGZpbGVzIHVuZGVyIGRpcmVjdG9yeToiICsgZmlsZVVyaSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoY2xpZW50RmlsZUdyb3VwQnVpbGRlcik7CisgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICBleGVjdXRvcik7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgIGNsaWVudEZpbGVHcm91cEJ1aWxkZXIuYWRkRmlsZSgKKyAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDbGllbnRGaWxlKAorICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0Qnl0ZVNpemUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0RG93bmxvYWRlZEZpbGVCeXRlU2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB1cmkgPSAqLyBudWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZS5oYXNDdXN0b21NZXRhZGF0YSgpID8gZGF0YUZpbGUuZ2V0Q3VzdG9tTWV0YWRhdGEoKSA6IG51bGwpKTsKKyAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShjbGllbnRGaWxlR3JvdXBCdWlsZGVyKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgIGV4ZWN1dG9yKTsKKyAgICB9CisKKyAgICByZXR1cm4gRmx1ZW50RnV0dXJlLmZyb20oY2xpZW50RmlsZUdyb3VwQnVpbGRlckZ1dHVyZSkKKyAgICAgICAgLnRyYW5zZm9ybShHZW5lcmF0ZWRNZXNzYWdlTGl0ZS5CdWlsZGVyOjpidWlsZCwgZXhlY3V0b3IpCisgICAgICAgIC5jYXRjaGluZyhEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcywgZXhuIC0+IG51bGwsIGV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIENsaWVudEZpbGUgY3JlYXRlQ2xpZW50RmlsZSgKKyAgICAgIFN0cmluZyBmaWxlSWQsCisgICAgICBpbnQgYnl0ZVNpemUsCisgICAgICBpbnQgZG93bmxvYWRCeXRlU2l6ZSwKKyAgICAgIEBOdWxsYWJsZSBTdHJpbmcgdXJpLAorICAgICAgQE51bGxhYmxlIEFueSBjdXN0b21NZXRhZGF0YSkgeworICAgIENsaWVudEZpbGUuQnVpbGRlciBjbGllbnRGaWxlQnVpbGRlciA9CisgICAgICAgIENsaWVudEZpbGUubmV3QnVpbGRlcigpLnNldEZpbGVJZChmaWxlSWQpLnNldEZ1bGxTaXplSW5CeXRlcyhieXRlU2l6ZSk7CisgICAgaWYgKGRvd25sb2FkQnl0ZVNpemUgPiAwKSB7CisgICAgICAvLyBGaWxlcyB3aXRoIGRvd25sb2FkZWQgdHJhbnNmb3JtcyBsaWtlIGNvbXByZXNzIGFuZCB6aXAgY291bGQgaGF2ZSBkaWZmZXJlbnQgZG93bmxvYWRlZAorICAgICAgLy8gZmlsZSBzaXplIHRoYW4gdGhlIGZpbmFsIGZpbGUgc2l6ZSBvbiBkaXNrLiBSZXR1cm4gdGhlIGRvd25sb2FkZWQgZmlsZSBzaXplIGZvciBjbGllbnQgdG8KKyAgICAgIC8vIHRyYWNrIGFuZCBjYWxjdWxhdGUgdGhlIGRvd25sb2FkIHByb2dyZXNzLgorICAgICAgY2xpZW50RmlsZUJ1aWxkZXIuc2V0RG93bmxvYWRTaXplSW5CeXRlcyhkb3dubG9hZEJ5dGVTaXplKTsKKyAgICB9CisgICAgaWYgKHVyaSAhPSBudWxsKSB7CisgICAgICBjbGllbnRGaWxlQnVpbGRlci5zZXRGaWxlVXJpKHVyaSk7CisgICAgfQorICAgIGlmIChjdXN0b21NZXRhZGF0YSAhPSBudWxsKSB7CisgICAgICBjbGllbnRGaWxlQnVpbGRlci5zZXRDdXN0b21NZXRhZGF0YShjdXN0b21NZXRhZGF0YSk7CisgICAgfQorICAgIHJldHVybiBjbGllbnRGaWxlQnVpbGRlci5idWlsZCgpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgTGlzdDxDbGllbnRGaWxlPiBsaXN0QWxsQ2xpZW50RmlsZXNPZkRpcmVjdG9yeSgKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsIFVyaSBkaXJVcmksIFN0cmluZyByb290RGlyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIExpc3Q8Q2xpZW50RmlsZT4gY2xpZW50RmlsZUxpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBmb3IgKFVyaSBjaGlsZFVyaSA6IGZpbGVTdG9yYWdlLmNoaWxkcmVuKGRpclVyaSkpIHsKKyAgICAgIGlmIChmaWxlU3RvcmFnZS5pc0RpcmVjdG9yeShjaGlsZFVyaSkpIHsKKyAgICAgICAgY2xpZW50RmlsZUxpc3QuYWRkQWxsKGxpc3RBbGxDbGllbnRGaWxlc09mRGlyZWN0b3J5KGZpbGVTdG9yYWdlLCBjaGlsZFVyaSwgcm9vdERpcikpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgU3RyaW5nIGNoaWxkUGF0aCA9IGNoaWxkVXJpLmdldFBhdGgoKTsKKyAgICAgICAgaWYgKGNoaWxkUGF0aCAhPSBudWxsKSB7CisgICAgICAgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0KKyAgICAgICAgICAgICAgQ2xpZW50RmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoY2hpbGRQYXRoLnJlcGxhY2VGaXJzdChyb290RGlyLCAiIikpCisgICAgICAgICAgICAgICAgICAuc2V0RnVsbFNpemVJbkJ5dGVzKChpbnQpIGZpbGVTdG9yYWdlLmZpbGVTaXplKGNoaWxkVXJpKSkKKyAgICAgICAgICAgICAgICAgIC5zZXRGaWxlVXJpKGNoaWxkVXJpLnRvU3RyaW5nKCkpCisgICAgICAgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAgICAgICBjbGllbnRGaWxlTGlzdC5hZGQoY2xpZW50RmlsZSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGNsaWVudEZpbGVMaXN0OworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPEltbXV0YWJsZUxpc3Q8Q2xpZW50RmlsZUdyb3VwPj4gZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyKAorICAgICAgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCBnZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0KSB7CisgICAgcmV0dXJuIGZ1dHVyZVNlcmlhbGl6ZXIuc3VibWl0QXN5bmMoCisgICAgICAgICgpIC0+CisgICAgICAgICAgICBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0QWxsRnJlc2hHcm91cHMoKSwKKyAgICAgICAgICAgICAgICBhbGxGcmVzaEdyb3VwcyAtPiB7CisgICAgICAgICAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPEltbXV0YWJsZUxpc3QuQnVpbGRlcjxDbGllbnRGaWxlR3JvdXA+PgorICAgICAgICAgICAgICAgICAgICAgIGNsaWVudEZpbGVHcm91cHNCdWlsZGVyRnV0dXJlID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoSW1tdXRhYmxlTGlzdC48Q2xpZW50RmlsZUdyb3VwPmJ1aWxkZXIoKSk7CisgICAgICAgICAgICAgICAgICBmb3IgKFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4ga2V5RGF0YUZpbGVHcm91cFBhaXIgOgorICAgICAgICAgICAgICAgICAgICAgIGFsbEZyZXNoR3JvdXBzKSB7CisgICAgICAgICAgICAgICAgICAgIGNsaWVudEZpbGVHcm91cHNCdWlsZGVyRnV0dXJlID0KKyAgICAgICAgICAgICAgICAgICAgICAgIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50RmlsZUdyb3Vwc0J1aWxkZXJGdXR1cmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpZW50RmlsZUdyb3Vwc0J1aWxkZXIgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPSBrZXlEYXRhRmlsZUdyb3VwUGFpci5maXJzdDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0ga2V5RGF0YUZpbGVHcm91cFBhaXIuc2Vjb25kOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFwcGx5RmlsdGVyKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QsIGdyb3VwS2V5LCBkYXRhRmlsZUdyb3VwKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDbGllbnRGaWxlR3JvdXBBbmRMb2dRdWVyeVN0YXRzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXkuZ2V0RG93bmxvYWRlZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QucHJlc2VydmVaaXBEaXJlY3RvcmllcygpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudEZpbGVHcm91cCAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjbGllbnRGaWxlR3JvdXAgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudEZpbGVHcm91cHNCdWlsZGVyLmFkZChjbGllbnRGaWxlR3JvdXApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRGaWxlR3JvdXBzQnVpbGRlcjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShjbGllbnRGaWxlR3JvdXBzQnVpbGRlcik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMudHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgIGNsaWVudEZpbGVHcm91cHNCdWlsZGVyRnV0dXJlLAorICAgICAgICAgICAgICAgICAgICAgIEltbXV0YWJsZUxpc3QuQnVpbGRlcjo6YnVpbGQsCisgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvLyBQZXJmb3JtIGZpbHRlcmluZyB1c2luZyBvcHRpb25zIGZyb20gR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdAorICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGFwcGx5RmlsdGVyKAorICAgICAgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCBnZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0LAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwKSB7CisgICAgaWYgKGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QuaW5jbHVkZUFsbEdyb3VwcygpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisKKyAgICAvLyBJZiByZXF1ZXN0IGZpbHRlcnMgYnkgZ3JvdXAgbmFtZSwgZW5zdXJlIG5hbWUgaXMgZXF1YWwKKyAgICBPcHRpb25hbDxTdHJpbmc+IGdyb3VwTmFtZU9wdGlvbmFsID0gZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5ncm91cE5hbWVPcHRpb25hbCgpOworICAgIGlmIChncm91cE5hbWVPcHRpb25hbC5pc1ByZXNlbnQoKQorICAgICAgICAmJiAhVGV4dFV0aWxzLmVxdWFscyhncm91cE5hbWVPcHRpb25hbC5nZXQoKSwgZ3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCkpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8gV2hlbiB0aGUgY2FsbGVyIHJlcXVlc3RzIGFjY291bnQgaW5kZXBlbmRlbnQgZ3JvdXBzIG9ubHkuCisgICAgaWYgKGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QuZ3JvdXBXaXRoTm9BY2NvdW50T25seSgpKSB7CisgICAgICByZXR1cm4gIWdyb3VwS2V5Lmhhc0FjY291bnQoKTsKKyAgICB9CisKKyAgICAvLyBXaGVuIHRoZSBjYWxsZXIgcmVxdWVzdHMgYWNjb3VudCBkZXBlbmRlbnQgZ3JvdXBzIGFzIHdlbGwuCisgICAgaWYgKGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QuYWNjb3VudE9wdGlvbmFsKCkuaXNQcmVzZW50KCkKKyAgICAgICAgJiYgIUFjY291bnRVdGlsLnNlcmlhbGl6ZShnZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0LmFjY291bnRPcHRpb25hbCgpLmdldCgpKQorICAgICAgICAgICAgLmVxdWFscyhncm91cEtleS5nZXRBY2NvdW50KCkpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMge0BsaW5rIEljaW5nRGF0YURvd25sb2FkRmlsZUdyb3VwU3RhdHN9IGZyb20ge0BsaW5rIENsaWVudEZpbGVHcm91cH0gZm9yIHJlbW90ZSBsb2dnaW5nCisgICAqIHB1cnBvc2VzLgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgVm9pZCBjcmVhdGVGaWxlR3JvdXBEZXRhaWxzKENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXApIHsKKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBpbXBvcnRGaWxlcyhJbXBvcnRGaWxlc1JlcXVlc3QgaW1wb3J0RmlsZXNSZXF1ZXN0KSB7CisgICAgR3JvdXBLZXkuQnVpbGRlciBncm91cEtleUJ1aWxkZXIgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoaW1wb3J0RmlsZXNSZXF1ZXN0Lmdyb3VwTmFtZSgpKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworCisgICAgaWYgKGltcG9ydEZpbGVzUmVxdWVzdC5hY2NvdW50T3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgZ3JvdXBLZXlCdWlsZGVyLnNldEFjY291bnQoQWNjb3VudFV0aWwuc2VyaWFsaXplKGltcG9ydEZpbGVzUmVxdWVzdC5hY2NvdW50T3B0aW9uYWwoKS5nZXQoKSkpOworICAgIH0KKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gZ3JvdXBLZXlCdWlsZGVyLmJ1aWxkKCk7CisKKyAgICBJbW11dGFibGVMaXN0LkJ1aWxkZXI8RGF0YUZpbGU+IHVwZGF0ZWREYXRhRmlsZUxpc3RCdWlsZGVyID0KKyAgICAgICAgSW1tdXRhYmxlTGlzdC5idWlsZGVyV2l0aEV4cGVjdGVkU2l6ZShpbXBvcnRGaWxlc1JlcXVlc3QudXBkYXRlZERhdGFGaWxlTGlzdCgpLnNpemUoKSk7CisgICAgZm9yIChEb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlIGRhdGFGaWxlIDogaW1wb3J0RmlsZXNSZXF1ZXN0LnVwZGF0ZWREYXRhRmlsZUxpc3QoKSkgeworICAgICAgdXBkYXRlZERhdGFGaWxlTGlzdEJ1aWxkZXIuYWRkKFByb3RvQ29udmVyc2lvblV0aWwuY29udmVydERhdGFGaWxlKGRhdGFGaWxlKSk7CisgICAgfQorCisgICAgcmV0dXJuIGZ1dHVyZVNlcmlhbGl6ZXIuc3VibWl0QXN5bmMoCisgICAgICAgICgpIC0+CisgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmltcG9ydEZpbGVzKAorICAgICAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgICAgIGltcG9ydEZpbGVzUmVxdWVzdC5idWlsZElkKCksCisgICAgICAgICAgICAgICAgaW1wb3J0RmlsZXNSZXF1ZXN0LnZhcmlhbnRJZCgpLAorICAgICAgICAgICAgICAgIHVwZGF0ZWREYXRhRmlsZUxpc3RCdWlsZGVyLmJ1aWxkKCksCisgICAgICAgICAgICAgICAgaW1wb3J0RmlsZXNSZXF1ZXN0LmlubGluZUZpbGVNYXAoKSwKKyAgICAgICAgICAgICAgICBpbXBvcnRGaWxlc1JlcXVlc3QuY3VzdG9tUHJvcGVydHlPcHRpb25hbCgpLAorICAgICAgICAgICAgICAgIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciksCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRmlsZShTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0IHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QpIHsKKyAgICByZXR1cm4gc2luZ2xlRmlsZURvd25sb2FkZXIuZG93bmxvYWQoCisgICAgICAgIE1kZExpdGVDb252ZXJzaW9uVXRpbC5jb252ZXJ0VG9Eb3dubG9hZFJlcXVlc3Qoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPENsaWVudEZpbGVHcm91cD4gZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QgZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0KSB7CisgICAgU3RyaW5nIGdyb3VwTmFtZSA9IGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5ncm91cE5hbWUoKTsKKyAgICBHcm91cEtleS5CdWlsZGVyIGdyb3VwS2V5QnVpbGRlciA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoZ3JvdXBOYW1lKS5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKworICAgIGlmIChkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuYWNjb3VudE9wdGlvbmFsKCkuaXNQcmVzZW50KCkpIHsKKyAgICAgIGdyb3VwS2V5QnVpbGRlci5zZXRBY2NvdW50KAorICAgICAgICAgIEFjY291bnRVdGlsLnNlcmlhbGl6ZShkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuYWNjb3VudE9wdGlvbmFsKCkuZ2V0KCkpKTsKKyAgICB9CisgICAgaWYgKGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC52YXJpYW50SWRPcHRpb25hbCgpLmlzUHJlc2VudCgpKSB7CisgICAgICBncm91cEtleUJ1aWxkZXIuc2V0VmFyaWFudElkKGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC52YXJpYW50SWRPcHRpb25hbCgpLmdldCgpKTsKKyAgICB9CisKKyAgICBHcm91cEtleSBncm91cEtleSA9IGdyb3VwS2V5QnVpbGRlci5idWlsZCgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxDbGllbnRGaWxlR3JvdXA+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgRnV0dXJlcy5zdWJtaXRBc3luYygKKyAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgaWYgKGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuaXNQcmVzZW50KCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoZG93bmxvYWRNb25pdG9yT3B0aW9uYWwuaXNQcmVzZW50KCkpIHsKKyAgICAgICAgICAgICAgICAgIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsCisgICAgICAgICAgICAgICAgICAgICAgLmdldCgpCisgICAgICAgICAgICAgICAgICAgICAgLmFkZERvd25sb2FkTGlzdGVuZXIoCisgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwTmFtZSwgZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKS5nZXQoKSk7CisgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERvd25sb2FkUmVzdWx0Q29kZS5ET1dOTE9BRF9NT05JVE9SX05PVF9QUk9WSURFRF9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldE1lc3NhZ2UoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZG93bmxvYWRGaWxlR3JvdXA6IERvd25sb2FkTGlzdGVuZXIgaXMgcHJlc2VudCBidXQgRG93bmxvYWQgTW9uaXRvciIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgaXMgbm90IHByb3ZpZGVkISIpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICBPcHRpb25hbDxEb3dubG9hZENvbmRpdGlvbnM+IGRvd25sb2FkQ29uZGl0aW9ucyA9CisgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuZG93bmxvYWRDb25kaXRpb25zT3B0aW9uYWwoKS5pc1ByZXNlbnQoKQorICAgICAgICAgICAgICAgICAgICAgID8gT3B0aW9uYWwub2YoCisgICAgICAgICAgICAgICAgICAgICAgICAgIFByb3RvQ29udmVyc2lvblV0aWwuY29udmVydCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5kb3dubG9hZENvbmRpdGlvbnNPcHRpb25hbCgpLmdldCgpKSkKKyAgICAgICAgICAgICAgICAgICAgICA6IE9wdGlvbmFsLmFic2VudCgpOworICAgICAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZG93bmxvYWRGaWxlR3JvdXBGdXR1cmUgPQorICAgICAgICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgICBncm91cEtleSwgZG93bmxvYWRDb25kaXRpb25zLCBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpOworCisgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICAgICAgZG93bmxvYWRGaWxlR3JvdXBGdXR1cmUsCisgICAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMudHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ2xpZW50RmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0LmFjY291bnRPcHRpb25hbCgpLmlzUHJlc2VudCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gQWNjb3VudFV0aWwuc2VyaWFsaXplKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0LmFjY291bnRPcHRpb25hbCgpLmdldCgpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xpZW50RmlsZUdyb3VwLlN0YXR1cy5ET1dOTE9BREVELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5wcmVzZXJ2ZVppcERpcmVjdG9yaWVzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFByZWNvbmRpdGlvbnM6OmNoZWNrTm90TnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxDbGllbnRGaWxlR3JvdXA+IHRyYW5zZm9ybUZ1dHVyZSA9CisgICAgICAgIEZ1dHVyZXMudHJhbnNmb3JtKAorICAgICAgICAgICAgZG93bmxvYWRGdXR1cmUsCisgICAgICAgICAgICBjbGllbnRGaWxlR3JvdXAgLT4geworICAgICAgICAgICAgICBpZiAoZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkub25Db21wbGV0ZShjbGllbnRGaWxlR3JvdXApOworICAgICAgICAgICAgICAgIGlmIChkb3dubG9hZE1vbml0b3JPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgICAgZG93bmxvYWRNb25pdG9yT3B0aW9uYWwuZ2V0KCkucmVtb3ZlRG93bmxvYWRMaXN0ZW5lcihncm91cE5hbWUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICByZXR1cm4gY2xpZW50RmlsZUdyb3VwOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworCisgICAgRnV0dXJlcy5hZGRDYWxsYmFjaygKKyAgICAgICAgdHJhbnNmb3JtRnV0dXJlLAorICAgICAgICBuZXcgRnV0dXJlQ2FsbGJhY2s8Q2xpZW50RmlsZUdyb3VwPigpIHsKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoQ2xpZW50RmlsZUdyb3VwIHJlc3VsdCkge30KKworICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgIHB1YmxpYyB2b2lkIG9uRmFpbHVyZShUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgaWYgKGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuaXNQcmVzZW50KCkKKyAgICAgICAgICAgICAgICAmJiBkb3dubG9hZE1vbml0b3JPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICBkb3dubG9hZE1vbml0b3JPcHRpb25hbC5nZXQoKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGdyb3VwTmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9LAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKworICAgIHJldHVybiB0cmFuc2Zvcm1GdXR1cmU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGaWxlV2l0aEZvcmVncm91bmRTZXJ2aWNlKAorICAgICAgU2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCBzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0KSB7CisgICAgcmV0dXJuIHNpbmdsZUZpbGVEb3dubG9hZGVyLmRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlKAorICAgICAgICBNZGRMaXRlQ29udmVyc2lvblV0aWwuY29udmVydFRvRG93bmxvYWRSZXF1ZXN0KHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxDbGllbnRGaWxlR3JvdXA+IGRvd25sb2FkRmlsZUdyb3VwV2l0aEZvcmVncm91bmRTZXJ2aWNlKAorICAgICAgRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0IGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdCkgeworICAgIExvZ1V0aWwuZCgiJXM6IGRvd25sb2FkRmlsZUdyb3VwV2l0aEZvcmVncm91bmRTZXJ2aWNlIHN0YXJ0LiIsIFRBRyk7CisgICAgaWYgKCFmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgIG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICJkb3dubG9hZEZpbGVHcm91cFdpdGhGb3JlZ3JvdW5kU2VydmljZTogRm9yZWdyb3VuZERvd25sb2FkU2VydmljZSBpcyBub3QiCisgICAgICAgICAgICAgICAgICArICIgcHJvdmlkZWQhIikpOworICAgIH0KKworICAgIGlmICghZG93bmxvYWRNb25pdG9yT3B0aW9uYWwuaXNQcmVzZW50KCkpIHsKKyAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuRE9XTkxPQURfTU9OSVRPUl9OT1RfUFJPVklERURfRVJST1IpCisgICAgICAgICAgICAgIC5zZXRNZXNzYWdlKAorICAgICAgICAgICAgICAgICAgImRvd25sb2FkRmlsZUdyb3VwV2l0aEZvcmVncm91bmRTZXJ2aWNlOiBEb3dubG9hZCBNb25pdG9yIGlzIG5vdCBwcm92aWRlZCEiKQorICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgfQorCisgICAgLy8gSXQncyBPSyB0byByZWNyZWF0ZSB0aGUgTm90aWZpY2F0aW9uQ2hhbm5lbCBzaW5jZSBpdCBjYW4gYWxzbyBiZSB1c2VkIHRvIHJlc3RvcmUgYQorICAgIC8vIGRlbGV0ZWQgY2hhbm5lbCBhbmQgdG8gdXBkYXRlIGFuIGV4aXN0aW5nIGNoYW5uZWwncyBuYW1lLCBkZXNjcmlwdGlvbiwgZ3JvdXAsIGFuZC9vcgorICAgIC8vIGltcG9ydGFuY2UuCisgICAgTm90aWZpY2F0aW9uVXRpbC5jcmVhdGVOb3RpZmljYXRpb25DaGFubmVsKGNvbnRleHQpOworCisgICAgU3RyaW5nIGdyb3VwTmFtZSA9IGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5ncm91cE5hbWUoKTsKKyAgICBHcm91cEtleS5CdWlsZGVyIGdyb3VwS2V5QnVpbGRlciA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoZ3JvdXBOYW1lKS5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKworICAgIGlmIChkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuYWNjb3VudE9wdGlvbmFsKCkuaXNQcmVzZW50KCkpIHsKKyAgICAgIGdyb3VwS2V5QnVpbGRlci5zZXRBY2NvdW50KAorICAgICAgICAgIEFjY291bnRVdGlsLnNlcmlhbGl6ZShkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuYWNjb3VudE9wdGlvbmFsKCkuZ2V0KCkpKTsKKyAgICB9CisgICAgaWYgKGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC52YXJpYW50SWRPcHRpb25hbCgpLmlzUHJlc2VudCgpKSB7CisgICAgICBncm91cEtleUJ1aWxkZXIuc2V0VmFyaWFudElkKGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC52YXJpYW50SWRPcHRpb25hbCgpLmdldCgpKTsKKyAgICB9CisKKyAgICBHcm91cEtleSBncm91cEtleSA9IGdyb3VwS2V5QnVpbGRlci5idWlsZCgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxDbGllbnRGaWxlR3JvdXA+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIC8vIENoZWNrIGlmIHJlcXVlc3RlZCBmaWxlIGdyb3VwIGhhcyBhbHJlYWR5IGJlZW4gZG93bmxvYWRlZAorICAgICAgICAgICAgdHJ5VG9HZXREb3dubG9hZGVkRmlsZUdyb3VwKGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdCksCisgICAgICAgICAgICBkb3dubG9hZGVkRmlsZUdyb3VwT3B0aW9uYWwgLT4geworICAgICAgICAgICAgICAvLyBJZiB0aGUgZmlsZSBncm91cCBoYXMgYWxyZWFkeSBiZWVuIGRvd25sb2FkZWQsIHJldHVybiB0aGF0IG9uZS4KKyAgICAgICAgICAgICAgaWYgKGRvd25sb2FkZWRGaWxlR3JvdXBPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkb3dubG9hZGVkRmlsZUdyb3VwT3B0aW9uYWwuZ2V0KCkpOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgdGhlIHNhbWUgb24tZ29pbmcgcmVxdWVzdCwgcmV0dXJuIHRoYXQgb25lLgorICAgICAgICAgICAgICBpZiAoa2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmNvbnRhaW5zS2V5KGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5ncm91cE5hbWUoKSkpIHsKKyAgICAgICAgICAgICAgICAvLyBrZXlUb0xpc3RlbmFibGVGdXR1cmUuZ2V0IG11c3QgcmV0dXJuIE5vbi1udWxsIHNpbmNlIHdlIGNoZWNrIHRoZSBjb250YWluc0tleQorICAgICAgICAgICAgICAgIC8vIGFib3ZlLgorICAgICAgICAgICAgICAgIC8vIGNoZWNrTm90TnVsbCBpcyB0byBzdXBwcmVzcyBmYWxzZSBhbGFybSBhYm91dCBATnVsbGFibGUgcmVzdWx0LgorICAgICAgICAgICAgICAgIHJldHVybiBQcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbCgKKyAgICAgICAgICAgICAgICAgICAga2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmdldChkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuZ3JvdXBOYW1lKCkpKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIC8vIE9ubHkgc3RhcnQgdGhlIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZSB3aGVuIHRoaXMgaXMgdGhlIGZpcnN0IGRvd25sb2FkCisgICAgICAgICAgICAgIC8vIHJlcXVlc3QuCisgICAgICAgICAgICAgIGlmIChrZXlUb0xpc3RlbmFibGVGdXR1cmUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgTm90aWZpY2F0aW9uVXRpbC5zdGFydEZvcmVncm91bmREb3dubG9hZFNlcnZpY2UoCisgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgIGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsLmdldCgpLAorICAgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuZ3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgRG93bmxvYWRMaXN0ZW5lciBkb3dubG9hZExpc3RlbmVyV2l0aE5vdGlmaWNhdGlvbiA9CisgICAgICAgICAgICAgICAgICBjcmVhdGVEb3dubG9hZExpc3RlbmVyV2l0aE5vdGlmaWNhdGlvbihkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QpOworICAgICAgICAgICAgICAvLyBUaGUgZG93bmxvYWRNb25pdG9yIHdpbGwgdHJpZ2dlciB0aGUgRG93bmxvYWRMaXN0ZW5lci4KKyAgICAgICAgICAgICAgZG93bmxvYWRNb25pdG9yT3B0aW9uYWwKKyAgICAgICAgICAgICAgICAgIC5nZXQoKQorICAgICAgICAgICAgICAgICAgLmFkZERvd25sb2FkTGlzdGVuZXIoCisgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0Lmdyb3VwTmFtZSgpLCBkb3dubG9hZExpc3RlbmVyV2l0aE5vdGlmaWNhdGlvbik7CisKKyAgICAgICAgICAgICAgT3B0aW9uYWw8RG93bmxvYWRDb25kaXRpb25zPiBkb3dubG9hZENvbmRpdGlvbnMgPQorICAgICAgICAgICAgICAgICAgZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0LmRvd25sb2FkQ29uZGl0aW9uc09wdGlvbmFsKCkuaXNQcmVzZW50KCkKKyAgICAgICAgICAgICAgICAgICAgICA/IE9wdGlvbmFsLm9mKAorICAgICAgICAgICAgICAgICAgICAgICAgICBQcm90b0NvbnZlcnNpb25VdGlsLmNvbnZlcnQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuZG93bmxvYWRDb25kaXRpb25zT3B0aW9uYWwoKS5nZXQoKSkpCisgICAgICAgICAgICAgICAgICAgICAgOiBPcHRpb25hbC5hYnNlbnQoKTsKKyAgICAgICAgICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRvd25sb2FkRmlsZUdyb3VwRnV0dXJlID0KKyAgICAgICAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksIGRvd25sb2FkQ29uZGl0aW9ucywgY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yKTsKKworICAgICAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPENsaWVudEZpbGVHcm91cD4gdHJhbnNmb3JtRnV0dXJlID0KKyAgICAgICAgICAgICAgICAgIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRGaWxlR3JvdXBGdXR1cmUsCisgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cCAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ2xpZW50RmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuYWNjb3VudE9wdGlvbmFsKCkuaXNQcmVzZW50KCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gQWNjb3VudFV0aWwuc2VyaWFsaXplKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5hY2NvdW50T3B0aW9uYWwoKS5nZXQoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xpZW50RmlsZUdyb3VwLlN0YXR1cy5ET1dOTE9BREVELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QucHJlc2VydmVaaXBEaXJlY3RvcmllcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJlY29uZGl0aW9uczo6Y2hlY2tOb3ROdWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisKKyAgICAgICAgICAgICAgRnV0dXJlcy5hZGRDYWxsYmFjaygKKyAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybUZ1dHVyZSwKKyAgICAgICAgICAgICAgICAgIG5ldyBGdXR1cmVDYWxsYmFjazxDbGllbnRGaWxlR3JvdXA+KCkgeworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25TdWNjZXNzKENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXApIHsKKyAgICAgICAgICAgICAgICAgICAgICAvLyBDdXJyZW50bHkgdGhlIE1vYlN0b3JlIG1vbml0b3IgZG9lcyBub3Qgc3VwcG9ydCBvblN1Y2Nlc3Mgc28gd2UgaGF2ZSB0byBhZGQKKyAgICAgICAgICAgICAgICAgICAgICAvLyBjYWxsYmFjayB0byB0aGUgZG93bmxvYWQgZnV0dXJlIGhlcmUuCisgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyhiLzE0ODA1NzY3NCk6IFVzZSB0aGUgc2FtZSBsb2dpYyBhcyBNRERMaXRlIHRvIGtlZXAgdGhlIGZvcmVncm91bmQKKyAgICAgICAgICAgICAgICAgICAgICAvLyBkb3dubG9hZCBzZXJ2aWNlIGFsaXZlIHVudGlsIHRoZSBjbGllbnQncyBvbkNvbXBsZXRlIGZpbmlzaGVzLgorICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkTGlzdGVuZXJXaXRoTm90aWZpY2F0aW9uLm9uQ29tcGxldGUoY2xpZW50RmlsZUdyb3VwKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkZhaWx1cmUoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAvLyBDdXJyZW50bHkgdGhlIE1vYlN0b3JlIG1vbml0b3IgZG9lcyBub3Qgc3VwcG9ydCBvbkZhaWx1cmUgc28gd2UgaGF2ZSB0byBhZGQKKyAgICAgICAgICAgICAgICAgICAgICAvLyBjYWxsYmFjayB0byB0aGUgZG93bmxvYWQgZnV0dXJlIGhlcmUuCisgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRMaXN0ZW5lcldpdGhOb3RpZmljYXRpb24ub25GYWlsdXJlKHQpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisKKyAgICAgICAgICAgICAga2V5VG9MaXN0ZW5hYmxlRnV0dXJlLnB1dChkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuZ3JvdXBOYW1lKCksIHRyYW5zZm9ybUZ1dHVyZSk7CisgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1GdXR1cmU7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisKKyAgICByZXR1cm4gZG93bmxvYWRGdXR1cmU7CisgIH0KKworICAvKiogSGVscGVyIG1ldGhvZCB0byBjaGVjayBpZiBmaWxlIGdyb3VwIGhhcyBiZWVuIGRvd25sb2FkZWQgYW5kIHJldHVybiBpdCBlYXJseS4gKi8KKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPE9wdGlvbmFsPENsaWVudEZpbGVHcm91cD4+IHRyeVRvR2V0RG93bmxvYWRlZEZpbGVHcm91cCgKKyAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdCBkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QpIHsKKyAgICBTdHJpbmcgZ3JvdXBOYW1lID0gZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0Lmdyb3VwTmFtZSgpOworICAgIEdyb3VwS2V5LkJ1aWxkZXIgZ3JvdXBLZXlCdWlsZGVyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShncm91cE5hbWUpLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworCisgICAgaWYgKGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5hY2NvdW50T3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgZ3JvdXBLZXlCdWlsZGVyLnNldEFjY291bnQoCisgICAgICAgICAgQWNjb3VudFV0aWwuc2VyaWFsaXplKGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5hY2NvdW50T3B0aW9uYWwoKS5nZXQoKSkpOworICAgIH0KKyAgICBib29sZWFuIGlzRG93bmxvYWRMaXN0ZW5lclByZXNlbnQgPSBkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QubGlzdGVuZXJPcHRpb25hbCgpLmlzUHJlc2VudCgpOworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gZ3JvdXBLZXlCdWlsZGVyLmJ1aWxkKCk7CisKKyAgICAvLyBHZXQgcGVuZGluZyBhbmQgZG93bmxvYWRlZCB2ZXJzaW9ucyB0byB0ZWxsIGlmIHdlIHNob3VsZCByZXR1cm4gZG93bmxvYWRlZCB2ZXJzaW9uIGVhcmx5CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxQYWlyPERhdGFGaWxlR3JvdXBJbnRlcm5hbCwgRGF0YUZpbGVHcm91cEludGVybmFsPj4gZmlsZUdyb3VwVmVyc2lvbnNGdXR1cmUgPQorICAgICAgICBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXksIC8qIGRvd25sb2FkZWQgPSAqLyBmYWxzZSksCisgICAgICAgICAgICBwZW5kaW5nRGF0YUZpbGVHcm91cCAtPgorICAgICAgICAgICAgICAgIEZ1dHVyZXMudHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChncm91cEtleSwgLyogZG93bmxvYWRlZCA9ICovIHRydWUpLAorICAgICAgICAgICAgICAgICAgICBkb3dubG9hZGVkRGF0YUZpbGVHcm91cCAtPgorICAgICAgICAgICAgICAgICAgICAgICAgUGFpci5jcmVhdGUocGVuZGluZ0RhdGFGaWxlR3JvdXAsIGRvd25sb2FkZWREYXRhRmlsZUdyb3VwKSwKKyAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciksCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBmaWxlR3JvdXBWZXJzaW9uc0Z1dHVyZSwKKyAgICAgICAgZmlsZUdyb3VwVmVyc2lvbnNQYWlyIC0+IHsKKyAgICAgICAgICAvLyBpZiBwZW5kaW5nIHZlcnNpb24gaXMgbm90IG51bGwsIHJldHVybiBhYnNlbnQKKyAgICAgICAgICBpZiAoZmlsZUdyb3VwVmVyc2lvbnNQYWlyLmZpcnN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShPcHRpb25hbC5hYnNlbnQoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIC8vIElmIGJvdGggZ3JvdXBzIGFyZSBudWxsLCByZXR1cm4gZ3JvdXAgbm90IGZvdW5kIGZhaWx1cmUKKyAgICAgICAgICBpZiAoZmlsZUdyb3VwVmVyc2lvbnNQYWlyLnNlY29uZCA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBUT0RPKGIvMTc0ODA4NDEwKTogQWRkIExvZ2dpbmcKKyAgICAgICAgICAgIC8vIGZpbGUgZ3JvdXAgaXMgbm90IHBlbmRpbmcgbm9yIGRvd25sb2FkZWQgLS0gcmV0dXJuIGZhaWx1cmUuCisgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbiBmYWlsdXJlID0KKyAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuR1JPVVBfTk9UX0ZPVU5EX0VSUk9SKQorICAgICAgICAgICAgICAgICAgICAuc2V0TWVzc2FnZSgiTm90aGluZyB0byBkb3dubG9hZCBmb3IgZmlsZSBncm91cDogIiArIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAgICAgICAgIGlmIChpc0Rvd25sb2FkTGlzdGVuZXJQcmVzZW50KSB7CisgICAgICAgICAgICAgIGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkub25GYWlsdXJlKGZhaWx1cmUpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGZhaWx1cmUpOworICAgICAgICAgIH0KKworICAgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkRGF0YUZpbGVHcm91cCA9IGZpbGVHcm91cFZlcnNpb25zUGFpci5zZWNvbmQ7CisKKyAgICAgICAgICAvLyBOb3RpZnkgZG93bmxvYWQgbGlzdGVuZXIgKGlmIHByZXNlbnQpIHRoYXQgZmlsZSBncm91cCBoYXMgYmVlbiBkb3dubG9hZGVkLgorICAgICAgICAgIGlmIChpc0Rvd25sb2FkTGlzdGVuZXJQcmVzZW50KSB7CisgICAgICAgICAgICBkb3dubG9hZE1vbml0b3JPcHRpb25hbAorICAgICAgICAgICAgICAgIC5nZXQoKQorICAgICAgICAgICAgICAgIC5hZGREb3dubG9hZExpc3RlbmVyKAorICAgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuZ3JvdXBOYW1lKCksCisgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkpOworICAgICAgICAgIH0KKyAgICAgICAgICBGbHVlbnRGdXR1cmU8T3B0aW9uYWw8Q2xpZW50RmlsZUdyb3VwPj4gdHJhbnNmb3JtRnV0dXJlID0KKyAgICAgICAgICAgICAgRmx1ZW50RnV0dXJlLmZyb20oCisgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ2xpZW50RmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZGVkRGF0YUZpbGVHcm91cCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0LmFjY291bnRPcHRpb25hbCgpLmlzUHJlc2VudCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IEFjY291bnRVdGlsLnNlcmlhbGl6ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QuYWNjb3VudE9wdGlvbmFsKCkuZ2V0KCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgIENsaWVudEZpbGVHcm91cC5TdGF0dXMuRE9XTkxPQURFRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0LnByZXNlcnZlWmlwRGlyZWN0b3JpZXMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVN0b3JhZ2UpKQorICAgICAgICAgICAgICAgICAgLnRyYW5zZm9ybShQcmVjb25kaXRpb25zOjpjaGVja05vdE51bGwsIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgICAgICAgICAgICAudHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgIGNsaWVudEZpbGVHcm91cCAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNEb3dubG9hZExpc3RlbmVyUHJlc2VudCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVHcm91cFJlcXVlc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5saXN0ZW5lck9wdGlvbmFsKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXQoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uQ29tcGxldGUoY2xpZW50RmlsZUdyb3VwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRNb25pdG9yT3B0aW9uYWwuZ2V0KCkucmVtb3ZlRG93bmxvYWRMaXN0ZW5lcihncm91cE5hbWUpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9wdGlvbmFsLm9mKGNsaWVudEZpbGVHcm91cCk7CisgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgICB0cmFuc2Zvcm1GdXR1cmUuYWRkQ2FsbGJhY2soCisgICAgICAgICAgICAgIG5ldyBGdXR1cmVDYWxsYmFjazxPcHRpb25hbDxDbGllbnRGaWxlR3JvdXA+PigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoT3B0aW9uYWw8Q2xpZW50RmlsZUdyb3VwPiByZXN1bHQpIHt9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkZhaWx1cmUoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAgIGlmIChpc0Rvd25sb2FkTGlzdGVuZXJQcmVzZW50KSB7CisgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLmdldCgpLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoZ3JvdXBOYW1lKTsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworCisgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybUZ1dHVyZTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIERvd25sb2FkTGlzdGVuZXIgY3JlYXRlRG93bmxvYWRMaXN0ZW5lcldpdGhOb3RpZmljYXRpb24oCisgICAgICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QgZG93bmxvYWRSZXF1ZXN0KSB7CisgICAgTm90aWZpY2F0aW9uTWFuYWdlckNvbXBhdCBub3RpZmljYXRpb25NYW5hZ2VyID0gTm90aWZpY2F0aW9uTWFuYWdlckNvbXBhdC5mcm9tKGNvbnRleHQpOworCisgICAgTm90aWZpY2F0aW9uQ29tcGF0LkJ1aWxkZXIgbm90aWZpY2F0aW9uID0KKyAgICAgICAgTm90aWZpY2F0aW9uVXRpbC5jcmVhdGVOb3RpZmljYXRpb25CdWlsZGVyKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5ncm91cFNpemVCeXRlcygpLAorICAgICAgICAgICAgZG93bmxvYWRSZXF1ZXN0LmNvbnRlbnRUaXRsZU9wdGlvbmFsKCkub3IoZG93bmxvYWRSZXF1ZXN0Lmdyb3VwTmFtZSgpKSwKKyAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5jb250ZW50VGV4dE9wdGlvbmFsKCkub3IoZG93bmxvYWRSZXF1ZXN0Lmdyb3VwTmFtZSgpKSk7CisgICAgaW50IG5vdGlmaWNhdGlvbktleSA9IE5vdGlmaWNhdGlvblV0aWwubm90aWZpY2F0aW9uS2V5Rm9yS2V5KGRvd25sb2FkUmVxdWVzdC5ncm91cE5hbWUoKSk7CisKKyAgICBpZiAoZG93bmxvYWRSZXF1ZXN0LnNob3dOb3RpZmljYXRpb25zKCkgPT0gRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0LlNob3dOb3RpZmljYXRpb25zLkFMTCkgeworICAgICAgTm90aWZpY2F0aW9uVXRpbC5jcmVhdGVDYW5jZWxBY3Rpb24oCisgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICBmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbC5nZXQoKSwKKyAgICAgICAgICBkb3dubG9hZFJlcXVlc3QuZ3JvdXBOYW1lKCksCisgICAgICAgICAgbm90aWZpY2F0aW9uLAorICAgICAgICAgIG5vdGlmaWNhdGlvbktleSk7CisKKyAgICAgIG5vdGlmaWNhdGlvbk1hbmFnZXIubm90aWZ5KG5vdGlmaWNhdGlvbktleSwgbm90aWZpY2F0aW9uLmJ1aWxkKCkpOworICAgIH0KKworICAgIHJldHVybiBuZXcgRG93bmxvYWRMaXN0ZW5lcigpIHsKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKSB7CisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IuZXhlY3V0ZSgKKyAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgLy8gVGhlcmUgY2FuIGJlIGEgcmFjZSBjb25kaXRpb24sIHdoZXJlIG9uUGF1c2VkRm9yQ29ubmVjdGl2aXR5IGNhbiBiZSBjYWxsZWQKKyAgICAgICAgICAgICAgLy8gYWZ0ZXIgb25Db21wbGV0ZSBvciBvbkZhaWx1cmUgd2hpY2ggcmVtb3ZlcyB0aGUgZnV0dXJlIGFuZCB0aGUgbm90aWZpY2F0aW9uLgorICAgICAgICAgICAgICBpZiAoa2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmNvbnRhaW5zS2V5KGRvd25sb2FkUmVxdWVzdC5ncm91cE5hbWUoKSkKKyAgICAgICAgICAgICAgICAgICYmIGRvd25sb2FkUmVxdWVzdC5zaG93Tm90aWZpY2F0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgPT0gRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0LlNob3dOb3RpZmljYXRpb25zLkFMTCkgeworICAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbgorICAgICAgICAgICAgICAgICAgICAuc2V0Q2F0ZWdvcnkoTm90aWZpY2F0aW9uQ29tcGF0LkNBVEVHT1JZX1BST0dSRVNTKQorICAgICAgICAgICAgICAgICAgICAuc2V0U21hbGxJY29uKGFuZHJvaWQuUi5kcmF3YWJsZS5zdGF0X3N5c19kb3dubG9hZCkKKyAgICAgICAgICAgICAgICAgICAgLnNldFByb2dyZXNzKAorICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRSZXF1ZXN0Lmdyb3VwU2l6ZUJ5dGVzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAoaW50KSBjdXJyZW50U2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGluZGV0ZXJtaW5hdGUgPSAqLyBkb3dubG9hZFJlcXVlc3QuZ3JvdXBTaXplQnl0ZXMoKSA8PSAwKTsKKyAgICAgICAgICAgICAgICBub3RpZmljYXRpb25NYW5hZ2VyLm5vdGlmeShub3RpZmljYXRpb25LZXksIG5vdGlmaWNhdGlvbi5idWlsZCgpKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBpZiAoZG93bmxvYWRSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkub25Qcm9ncmVzcyhjdXJyZW50U2l6ZSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIHBhdXNlZEZvckNvbm5lY3Rpdml0eSgpIHsKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvci5leGVjdXRlKAorICAgICAgICAgICAgKCkgLT4geworICAgICAgICAgICAgICAvLyBUaGVyZSBjYW4gYmUgYSByYWNlIGNvbmRpdGlvbiwgd2hlcmUgcGF1c2VkRm9yQ29ubmVjdGl2aXR5IGNhbiBiZSBjYWxsZWQKKyAgICAgICAgICAgICAgLy8gYWZ0ZXIgb25Db21wbGV0ZSBvciBvbkZhaWx1cmUgd2hpY2ggcmVtb3ZlcyB0aGUgZnV0dXJlIGFuZCB0aGUgbm90aWZpY2F0aW9uLgorICAgICAgICAgICAgICBpZiAoa2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmNvbnRhaW5zS2V5KGRvd25sb2FkUmVxdWVzdC5ncm91cE5hbWUoKSkKKyAgICAgICAgICAgICAgICAgICYmIGRvd25sb2FkUmVxdWVzdC5zaG93Tm90aWZpY2F0aW9ucygpCisgICAgICAgICAgICAgICAgICAgICAgPT0gRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0LlNob3dOb3RpZmljYXRpb25zLkFMTCkgeworICAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbgorICAgICAgICAgICAgICAgICAgICAuc2V0Q2F0ZWdvcnkoTm90aWZpY2F0aW9uQ29tcGF0LkNBVEVHT1JZX1NUQVRVUykKKyAgICAgICAgICAgICAgICAgICAgLnNldENvbnRlbnRUZXh0KE5vdGlmaWNhdGlvblV0aWwuZ2V0RG93bmxvYWRQYXVzZWRNZXNzYWdlKGNvbnRleHQpKQorICAgICAgICAgICAgICAgICAgICAuc2V0U21hbGxJY29uKGFuZHJvaWQuUi5kcmF3YWJsZS5zdGF0X3N5c19kb3dubG9hZCkKKyAgICAgICAgICAgICAgICAgICAgLnNldE9uZ29pbmcodHJ1ZSkKKyAgICAgICAgICAgICAgICAgICAgLy8gaGlkZSBwcm9ncmVzcyBiYXIuCisgICAgICAgICAgICAgICAgICAgIC5zZXRQcm9ncmVzcygwLCAwLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgbm90aWZpY2F0aW9uTWFuYWdlci5ub3RpZnkobm90aWZpY2F0aW9uS2V5LCBub3RpZmljYXRpb24uYnVpbGQoKSk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICBpZiAoZG93bmxvYWRSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkucGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIG9uQ29tcGxldGUoQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCkgeworICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLmV4ZWN1dGUoCisgICAgICAgICAgICAoKSAtPiB7CisgICAgICAgICAgICAgIC8vIENsZWFyIHRoZSBub3RpZmljYXRpb24gYWN0aW9uLgorICAgICAgICAgICAgICBpZiAoZG93bmxvYWRSZXF1ZXN0LnNob3dOb3RpZmljYXRpb25zKCkKKyAgICAgICAgICAgICAgICAgID09IERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5TaG93Tm90aWZpY2F0aW9ucy5BTEwpIHsKKyAgICAgICAgICAgICAgICBub3RpZmljYXRpb24ubUFjdGlvbnMuY2xlYXIoKTsKKworICAgICAgICAgICAgICAgIE5vdGlmaWNhdGlvblV0aWwuY2FuY2VsTm90aWZpY2F0aW9uRm9yS2V5KGNvbnRleHQsIGRvd25sb2FkUmVxdWVzdC5ncm91cE5hbWUoKSk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICBrZXlUb0xpc3RlbmFibGVGdXR1cmUucmVtb3ZlKGRvd25sb2FkUmVxdWVzdC5ncm91cE5hbWUoKSk7CisgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIG90aGVyIG9uLWdvaW5nIGZvcmVncm91bmQgZG93bmxvYWQsIHNodXRkb3duIHRoZQorICAgICAgICAgICAgICAvLyBGb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlCisgICAgICAgICAgICAgIGlmIChrZXlUb0xpc3RlbmFibGVGdXR1cmUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgTm90aWZpY2F0aW9uVXRpbC5zdG9wRm9yZWdyb3VuZERvd25sb2FkU2VydmljZSgKKyAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgZm9yZWdyb3VuZERvd25sb2FkU2VydmljZUNsYXNzT3B0aW9uYWwuZ2V0KCkpOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgaWYgKGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuaXNQcmVzZW50KCkpIHsKKyAgICAgICAgICAgICAgICBkb3dubG9hZFJlcXVlc3QubGlzdGVuZXJPcHRpb25hbCgpLmdldCgpLm9uQ29tcGxldGUoY2xpZW50RmlsZUdyb3VwKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLmdldCgpLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoZG93bmxvYWRSZXF1ZXN0Lmdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgIH0pOworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIG9uRmFpbHVyZShUaHJvd2FibGUgdCkgeworICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLmV4ZWN1dGUoCisgICAgICAgICAgICAoKSAtPiB7CisgICAgICAgICAgICAgIGlmIChkb3dubG9hZFJlcXVlc3Quc2hvd05vdGlmaWNhdGlvbnMoKQorICAgICAgICAgICAgICAgICAgPT0gRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0LlNob3dOb3RpZmljYXRpb25zLkFMTCkgeworICAgICAgICAgICAgICAgIC8vIENsZWFyIHRoZSBub3RpZmljYXRpb24gYWN0aW9uLgorICAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbi5tQWN0aW9ucy5jbGVhcigpOworCisgICAgICAgICAgICAgICAgLy8gU2hvdyBkb3dubG9hZCBmYWlsZWQgaW4gbm90aWZpY2F0aW9uLgorICAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbgorICAgICAgICAgICAgICAgICAgICAuc2V0Q2F0ZWdvcnkoTm90aWZpY2F0aW9uQ29tcGF0LkNBVEVHT1JZX1NUQVRVUykKKyAgICAgICAgICAgICAgICAgICAgLnNldENvbnRlbnRUZXh0KE5vdGlmaWNhdGlvblV0aWwuZ2V0RG93bmxvYWRGYWlsZWRNZXNzYWdlKGNvbnRleHQpKQorICAgICAgICAgICAgICAgICAgICAuc2V0T25nb2luZyhmYWxzZSkKKyAgICAgICAgICAgICAgICAgICAgLnNldFNtYWxsSWNvbihhbmRyb2lkLlIuZHJhd2FibGUuc3RhdF9zeXNfd2FybmluZykKKyAgICAgICAgICAgICAgICAgICAgLy8gaGlkZSBwcm9ncmVzcyBiYXIuCisgICAgICAgICAgICAgICAgICAgIC5zZXRQcm9ncmVzcygwLCAwLCBmYWxzZSk7CisKKyAgICAgICAgICAgICAgICBub3RpZmljYXRpb25NYW5hZ2VyLm5vdGlmeShub3RpZmljYXRpb25LZXksIG5vdGlmaWNhdGlvbi5idWlsZCgpKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBrZXlUb0xpc3RlbmFibGVGdXR1cmUucmVtb3ZlKGRvd25sb2FkUmVxdWVzdC5ncm91cE5hbWUoKSk7CisKKyAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gb3RoZXIgb24tZ29pbmcgZm9yZWdyb3VuZCBkb3dubG9hZCwgc2h1dGRvd24gdGhlCisgICAgICAgICAgICAgIC8vIEZvcmVncm91bmREb3dubG9hZFNlcnZpY2UKKyAgICAgICAgICAgICAgaWYgKGtleVRvTGlzdGVuYWJsZUZ1dHVyZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICBOb3RpZmljYXRpb25VdGlsLnN0b3BGb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlKAorICAgICAgICAgICAgICAgICAgICBjb250ZXh0LCBmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbC5nZXQoKSk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICBpZiAoZG93bmxvYWRSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkub25GYWlsdXJlKHQpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLmdldCgpLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoZG93bmxvYWRSZXF1ZXN0Lmdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgIH0pOworICAgICAgfQorICAgIH07CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgY2FuY2VsRm9yZWdyb3VuZERvd25sb2FkKFN0cmluZyBkb3dubG9hZEtleSkgeworICAgIExvZ1V0aWwuZCgiJXM6IENhbmNlbEZvcmVncm91bmREb3dubG9hZCBmb3Iga2V5ID0gJXMiLCBUQUcsIGRvd25sb2FkS2V5KTsKKyAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLmV4ZWN1dGUoCisgICAgICAgICgpIC0+IHsKKyAgICAgICAgICBpZiAoa2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmNvbnRhaW5zS2V5KGRvd25sb2FkS2V5KSkgeworICAgICAgICAgICAga2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmdldChkb3dubG9hZEtleSkuY2FuY2VsKHRydWUpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvLyBkb3dubG9hZEtleSBpcyBub3QgYSBmaWxlIGdyb3VwLCBhdHRlbXB0IGNhbmNlbCB3aXRoIGludGVybmFsIE1ERCBMaXRlIGluc3RhbmNlIGluCisgICAgICAgICAgICAvLyBjYXNlIGl0J3MgYSBzaW5nbGUgZmlsZSB1cmkgKGNhbmNlbCBjYWxsIGlzIGEgbm9vcCBpZiBpbnRlcm5hbCBNREQgTGl0ZSBkb2Vzbid0IGtub3cKKyAgICAgICAgICAgIC8vIGFib3V0IGl0KS4KKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLmNhbmNlbEZvcmVncm91bmREb3dubG9hZChkb3dubG9hZEtleSk7CisgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBzY2hlZHVsZVBlcmlvZGljVGFza3MoKSB7CisgICAgc2NoZWR1bGVQZXJpb2RpY1Rhc2tzSW50ZXJuYWwoT3B0aW9uYWwuYWJzZW50KCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHNjaGVkdWxlUGVyaW9kaWNCYWNrZ3JvdW5kVGFza3MoKSB7CisgICAgcmV0dXJuIGZ1dHVyZVNlcmlhbGl6ZXIuc3VibWl0KAorICAgICAgICBwcm9wYWdhdGVDYWxsYWJsZSgKKyAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgc2NoZWR1bGVQZXJpb2RpY1Rhc2tzSW50ZXJuYWwoLyogY29uc3RyYWludE92ZXJyaWRlc01hcCA9ICovIE9wdGlvbmFsLmFic2VudCgpKTsKKyAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9KSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gc2NoZWR1bGVQZXJpb2RpY0JhY2tncm91bmRUYXNrcygKKyAgICAgIE9wdGlvbmFsPE1hcDxTdHJpbmcsIENvbnN0cmFpbnRPdmVycmlkZXM+PiBjb25zdHJhaW50T3ZlcnJpZGVzTWFwKSB7CisgICAgcmV0dXJuIGZ1dHVyZVNlcmlhbGl6ZXIuc3VibWl0KAorICAgICAgICBwcm9wYWdhdGVDYWxsYWJsZSgKKyAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgc2NoZWR1bGVQZXJpb2RpY1Rhc2tzSW50ZXJuYWwoY29uc3RyYWludE92ZXJyaWRlc01hcCk7CisgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgfSksCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHNjaGVkdWxlUGVyaW9kaWNUYXNrc0ludGVybmFsKAorICAgICAgT3B0aW9uYWw8TWFwPFN0cmluZywgQ29uc3RyYWludE92ZXJyaWRlcz4+IGNvbnN0cmFpbnRPdmVycmlkZXNNYXApIHsKKyAgICBpZiAoIXRhc2tTY2hlZHVsZXJPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICIlczogQ2FsbGVkIHNjaGVkdWxlUGVyaW9kaWNUYXNrc0ludGVybmFsIHdoZW4gdGFza1NjaGVkdWxlciBpcyBub3QgcHJvdmlkZWQuIiwgVEFHKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBUYXNrU2NoZWR1bGVyIHRhc2tTY2hlZHVsZXIgPSB0YXNrU2NoZWR1bGVyT3B0aW9uYWwuZ2V0KCk7CisKKyAgICAvLyBTY2hlZHVsZSB0YXNrIHRoYXQgcnVucyBvbiBjaGFyZ2luZyB3aXRob3V0IGFueSBuZXR3b3JrLCBldmVyeSA2IGhvdXJzLgorICAgIHRhc2tTY2hlZHVsZXIuc2NoZWR1bGVQZXJpb2RpY1Rhc2soCisgICAgICAgIFRhc2tTY2hlZHVsZXIuQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSywKKyAgICAgICAgZmxhZ3MuY2hhcmdpbmdHY21UYXNrUGVyaW9kKCksCisgICAgICAgIE5ldHdvcmtTdGF0ZS5ORVRXT1JLX1NUQVRFX0FOWSwKKyAgICAgICAgZ2V0Q29uc3RyYWludE92ZXJyaWRlcyhjb25zdHJhaW50T3ZlcnJpZGVzTWFwLCBUYXNrU2NoZWR1bGVyLkNIQVJHSU5HX1BFUklPRElDX1RBU0spKTsKKworICAgIC8vIFNjaGVkdWxlIG1haW50ZW5hbmNlIHRhc2sgdGhhdCBydW5zIG9uIGNoYXJnaW5nLCBvbmNlIGV2ZXJ5IGRheS4KKyAgICAvLyBUaGlzIHRhc2sgc2hvdWxkIHJ1biBldmVuIGlmIG1kZCBpcyBkaXNhYmxlZCwgdG8gaGFuZGxlIGNsZWFudXAuCisgICAgdGFza1NjaGVkdWxlci5zY2hlZHVsZVBlcmlvZGljVGFzaygKKyAgICAgICAgVGFza1NjaGVkdWxlci5NQUlOVEVOQU5DRV9QRVJJT0RJQ19UQVNLLAorICAgICAgICBmbGFncy5tYWludGVuYW5jZUdjbVRhc2tQZXJpb2QoKSwKKyAgICAgICAgTmV0d29ya1N0YXRlLk5FVFdPUktfU1RBVEVfQU5ZLAorICAgICAgICBnZXRDb25zdHJhaW50T3ZlcnJpZGVzKGNvbnN0cmFpbnRPdmVycmlkZXNNYXAsIFRhc2tTY2hlZHVsZXIuTUFJTlRFTkFOQ0VfUEVSSU9ESUNfVEFTSykpOworCisgICAgLy8gU2NoZWR1bGUgdGFzayB0aGF0IHJ1bnMgb24gY2VsbHVsYXIrY2hhcmdpbmcsIGV2ZXJ5IDYgaG91cnMuCisgICAgdGFza1NjaGVkdWxlci5zY2hlZHVsZVBlcmlvZGljVGFzaygKKyAgICAgICAgVGFza1NjaGVkdWxlci5DRUxMVUxBUl9DSEFSR0lOR19QRVJJT0RJQ19UQVNLLAorICAgICAgICBmbGFncy5jZWxsdWxhckNoYXJnaW5nR2NtVGFza1BlcmlvZCgpLAorICAgICAgICBOZXR3b3JrU3RhdGUuTkVUV09SS19TVEFURV9DT05ORUNURUQsCisgICAgICAgIGdldENvbnN0cmFpbnRPdmVycmlkZXMoCisgICAgICAgICAgICBjb25zdHJhaW50T3ZlcnJpZGVzTWFwLCBUYXNrU2NoZWR1bGVyLkNFTExVTEFSX0NIQVJHSU5HX1BFUklPRElDX1RBU0spKTsKKworICAgIC8vIFNjaGVkdWxlIHRhc2sgdGhhdCBydW5zIG9uIHdpZmkrY2hhcmdpbmcsIGV2ZXJ5IDYgaG91cnMuCisgICAgdGFza1NjaGVkdWxlci5zY2hlZHVsZVBlcmlvZGljVGFzaygKKyAgICAgICAgVGFza1NjaGVkdWxlci5XSUZJX0NIQVJHSU5HX1BFUklPRElDX1RBU0ssCisgICAgICAgIGZsYWdzLndpZmlDaGFyZ2luZ0djbVRhc2tQZXJpb2QoKSwKKyAgICAgICAgTmV0d29ya1N0YXRlLk5FVFdPUktfU1RBVEVfVU5NRVRFUkVELAorICAgICAgICBnZXRDb25zdHJhaW50T3ZlcnJpZGVzKGNvbnN0cmFpbnRPdmVycmlkZXNNYXAsIFRhc2tTY2hlZHVsZXIuV0lGSV9DSEFSR0lOR19QRVJJT0RJQ19UQVNLKSk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBPcHRpb25hbDxDb25zdHJhaW50T3ZlcnJpZGVzPiBnZXRDb25zdHJhaW50T3ZlcnJpZGVzKAorICAgICAgT3B0aW9uYWw8TWFwPFN0cmluZywgQ29uc3RyYWludE92ZXJyaWRlcz4+IGNvbnN0cmFpbnRPdmVycmlkZXNNYXAsCisgICAgICBTdHJpbmcgbWFpbnRlbmFuY2VQZXJpb2RpY1Rhc2spIHsKKyAgICByZXR1cm4gY29uc3RyYWludE92ZXJyaWRlc01hcC5pc1ByZXNlbnQoKQorICAgICAgICA/IE9wdGlvbmFsLmZyb21OdWxsYWJsZShjb25zdHJhaW50T3ZlcnJpZGVzTWFwLmdldCgpLmdldChtYWludGVuYW5jZVBlcmlvZGljVGFzaykpCisgICAgICAgIDogT3B0aW9uYWwuYWJzZW50KCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gaGFuZGxlVGFzayhTdHJpbmcgdGFnKSB7CisgICAgLy8gQWxsIHdvcmsgZG9uZSBoZXJlIHRoYXQgdG91Y2hlcyBtZXRhZGF0YSAoTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikgc2hvdWxkIGJlIHNlcmlhbGl6ZWQKKyAgICAvLyB0aHJvdWdoIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IuCisgICAgc3dpdGNoICh0YWcpIHsKKyAgICAgIGNhc2UgVGFza1NjaGVkdWxlci5NQUlOVEVOQU5DRV9QRVJJT0RJQ19UQVNLOgorICAgICAgICByZXR1cm4gZnV0dXJlU2VyaWFsaXplci5zdWJtaXRBc3luYygKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXI6Om1haW50ZW5hbmNlLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKworICAgICAgY2FzZSBUYXNrU2NoZWR1bGVyLkNIQVJHSU5HX1BFUklPRElDX1RBU0s6CisgICAgICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVmcmVzaEZpbGVHcm91cHNGdXR1cmUgPSByZWZyZXNoRmlsZUdyb3VwcygpOworICAgICAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIHJlZnJlc2hGaWxlR3JvdXBzRnV0dXJlLAorICAgICAgICAgICAgcHJvcGFnYXRlQXN5bmNGdW5jdGlvbigKKyAgICAgICAgICAgICAgICB2IC0+IG1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIudmVyaWZ5QWxsUGVuZGluZ0dyb3VwcyhjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpKSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworCisgICAgICBjYXNlIFRhc2tTY2hlZHVsZXIuQ0VMTFVMQVJfQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSzoKKyAgICAgICAgcmV0dXJuIHJlZnJlc2hBbmREb3dubG9hZChmYWxzZSAvKm9uV2lmaSovKTsKKworICAgICAgY2FzZSBUYXNrU2NoZWR1bGVyLldJRklfQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSzoKKyAgICAgICAgcmV0dXJuIHJlZnJlc2hBbmREb3dubG9hZCh0cnVlIC8qb25XaWZpKi8pOworCisgICAgICBkZWZhdWx0OgorICAgICAgICBMb2dVdGlsLmQoIiVzOiBnY20gdGFzayBkb2Vzbid0IGJlbG9uZyB0byBNREQiLCBUQUcpOworICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIHRhc2sgdGFnIHNlbnQgdG8gTURELmhhbmRsZVRhc2soKSAiICsgdGFnKSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlZnJlc2hBbmREb3dubG9hZChib29sZWFuIG9uV2lmaSkgeworICAgIC8vIFdlIHdpbGwgZG8gMiBwYXNzZXMgdG8gc3VwcG9ydCAyLXN0ZXAgZG93bmxvYWRzLiBJbiBlYWNoIHN0ZXAsIHdlIHdpbGwgcmVmcmVzaCBhbmQgdGhlbgorICAgIC8vIGRvd25sb2FkLgorICAgIHJldHVybiBGbHVlbnRGdXR1cmUuZnJvbShyZWZyZXNoRmlsZUdyb3VwcygpKQorICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICB2IC0+CisgICAgICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5kb3dubG9hZEFsbFBlbmRpbmdHcm91cHMoCisgICAgICAgICAgICAgICAgICAgIG9uV2lmaSwgY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yKSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYyh2IC0+IHJlZnJlc2hGaWxlR3JvdXBzKCksIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIHYgLT4KKyAgICAgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmRvd25sb2FkQWxsUGVuZGluZ0dyb3VwcygKKyAgICAgICAgICAgICAgICAgICAgb25XaWZpLCBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpLAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVmcmVzaEZpbGVHcm91cHMoKSB7CisgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PiByZWZyZXNoRnV0dXJlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgIGZvciAoRmlsZUdyb3VwUG9wdWxhdG9yIGZpbGVHcm91cFBvcHVsYXRvciA6IGZpbGVHcm91cFBvcHVsYXRvckxpc3QpIHsKKyAgICAgIHJlZnJlc2hGdXR1cmVzLmFkZChmaWxlR3JvdXBQb3B1bGF0b3IucmVmcmVzaEZpbGVHcm91cHModGhpcykpOworICAgIH0KKworICAgIHJldHVybiBGdXR1cmVzLndoZW5BbGxDb21wbGV0ZShyZWZyZXNoRnV0dXJlcykuY2FsbCgoKSAtPiBudWxsLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBtYWludGVuYW5jZSgpIHsKKyAgICByZXR1cm4gaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLk1BSU5URU5BTkNFX1BFUklPRElDX1RBU0spOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNsZWFyKCkgeworICAgIHJldHVybiBmdXR1cmVTZXJpYWxpemVyLnN1Ym1pdEFzeW5jKAorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyOjpjbGVhciwgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvLyBpbmNvbXBhdGlibGUgYXJndW1lbnQgZm9yIHBhcmFtZXRlciBtc2cgb2YgZS4KKyAgLy8gaW5jb21wYXRpYmxlIHR5cGVzIGluIHJldHVybi4KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgZ2V0RGVidWdJbmZvQXNTdHJpbmcoKSB7CisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBQcmludFdyaXRlciB3cml0ZXIgPSBuZXcgUHJpbnRXcml0ZXIob3V0KTsKKyAgICB0cnkgeworICAgICAgLy8gT2theSB0byBibG9jayBoZXJlIGJlY2F1c2UgdGhpcyBtZXRob2QgaXMgZm9yIGRlYnVnZ2luZyBvbmx5LgorICAgICAgbW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5kdW1wKHdyaXRlcikuZ2V0KERVTVBfREVCVUdfSU5GT19USU1FT1VULCBUaW1lVW5pdC5TRUNPTkRTKTsKKyAgICAgIHdyaXRlci5wcmludGxuKCI9PT09IE1PQlNUT1JFX0RFQlVHX0lORk8gPT09PSIpOworICAgICAgd3JpdGVyLnByaW50KGZpbGVTdG9yYWdlLmdldERlYnVnSW5mbygpKTsKKyAgICB9IGNhdGNoIChFeGVjdXRpb25FeGNlcHRpb24gfCBUaW1lb3V0RXhjZXB0aW9uIGUpIHsKKyAgICAgIFN0cmluZyBlcnJTdHJpbmcgPSBTdHJpbmcuZm9ybWF0KCIlczogQ291bGRuJ3QgZ2V0IGRlYnVnIGluZm86ICVzIiwgVEFHLCBlKTsKKyAgICAgIExvZ1V0aWwuZShlcnJTdHJpbmcpOworICAgICAgcmV0dXJuIGVyclN0cmluZzsKKyAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBzZWUgPGludGVybmFsPgorICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKKyAgICAgIFN0cmluZyBlcnJTdHJpbmcgPSBTdHJpbmcuZm9ybWF0KCIlczogQ291bGRuJ3QgZ2V0IGRlYnVnIGluZm86ICVzIiwgVEFHLCBlKTsKKyAgICAgIExvZ1V0aWwuZShlcnJTdHJpbmcpOworICAgICAgcmV0dXJuIGVyclN0cmluZzsKKyAgICB9CisgICAgd3JpdGVyLmZsdXNoKCk7CisgICAgcmV0dXJuIG91dC50b1N0cmluZygpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlcG9ydFVzYWdlKFVzYWdlRXZlbnQgdXNhZ2VFdmVudCkgeworICAgIGV2ZW50TG9nZ2VyLmxvZ01kZFVzYWdlRXZlbnQoY3JlYXRlRmlsZUdyb3VwRGV0YWlscyh1c2FnZUV2ZW50LmNsaWVudEZpbGVHcm91cCgpKSwgbnVsbCk7CisKKyAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvUmVtb3ZlRmlsZUdyb3VwUmVxdWVzdC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9SZW1vdmVGaWxlR3JvdXBSZXF1ZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzA3NWY1ZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvUmVtb3ZlRmlsZUdyb3VwUmVxdWVzdC5qYXZhCkBAIC0wLDAgKzEsNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgYW5kcm9pZC5hY2NvdW50cy5BY2NvdW50OworaW1wb3J0IGNvbS5nb29nbGUuYXV0by52YWx1ZS5BdXRvVmFsdWU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLmNvbmN1cnJlbnQuSW1tdXRhYmxlOworCisvKiogUmVxdWVzdCB0byByZW1vdmUgZmlsZSBncm91cCBmcm9tIE1ERC4gKi8KK0BBdXRvVmFsdWUKK0BJbW11dGFibGUKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBSZW1vdmVGaWxlR3JvdXBSZXF1ZXN0IHsKKyAgUmVtb3ZlRmlsZUdyb3VwUmVxdWVzdCgpIHt9CisKKyAgcHVibGljIGFic3RyYWN0IFN0cmluZyBncm91cE5hbWUoKTsKKworICBwdWJsaWMgYWJzdHJhY3QgT3B0aW9uYWw8QWNjb3VudD4gYWNjb3VudE9wdGlvbmFsKCk7CisKKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPFN0cmluZz4gdmFyaWFudElkT3B0aW9uYWwoKTsKKworICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBwZW5kaW5nT25seSgpOworCisgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgeworICAgIHJldHVybiBuZXcgQXV0b1ZhbHVlX1JlbW92ZUZpbGVHcm91cFJlcXVlc3QuQnVpbGRlcigpLnNldFBlbmRpbmdPbmx5KGZhbHNlKTsKKyAgfQorCisgIC8qKiBCdWlsZGVyIGZvciB7QGxpbmsgUmVtb3ZlRmlsZUdyb3VwUmVxdWVzdH0uICovCisgIEBBdXRvVmFsdWUuQnVpbGRlcgorICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEJ1aWxkZXIgeworICAgIEJ1aWxkZXIoKSB7fQorCisgICAgLyoqIFNldHMgdGhlIG5hbWUgb2YgdGhlIGZpbGUgZ3JvdXAsIHdoaWNoIGlzIHJlcXVpcmVkLiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldEdyb3VwTmFtZShTdHJpbmcgZ3JvdXBOYW1lKTsKKworICAgIC8qKiBTZXRzIHRoZSBhY2NvdW50IHRoYXQgaXMgYXNzb2NpYXRlZCB0byB0aGUgZmlsZSBncm91cCwgd2hpY2ggaXMgb3B0aW9uYWwuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0QWNjb3VudE9wdGlvbmFsKE9wdGlvbmFsPEFjY291bnQ+IGFjY291bnRPcHRpb25hbCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB2YXJpYW50IGlkIHRoYXQgaXMgYXNzb2NpYXRlZCB0byB0aGUgZmlsZSBncm91cC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgcGFyYW1ldGVyIGlzIG9ubHkgcmVxdWlyZWQgdG8gcmVtb3ZlIGEgZ3JvdXAgdGhhdCB3YXMgYWRkZWQgdG8gTUREIHdpdGggYSB2YXJpYW50SWQKKyAgICAgKiBzcGVjaWZpZWQgKHNlZSB7QGxpbmsgQWRkRmlsZUdyb3VwUmVxdWVzdC5CdWlsZGVyI3NldFZhcmlhbnRJZE9wdGlvbmFsfSkuCisgICAgICoKKyAgICAgKiA8cD5JZiBhIHZhcmlhbnRJZCB3YXMgc3BlY2lmaWVkIHdoZW4gYWRkaW5nIHRoZSBncm91cCB0byBNREQgYW5kIGlzIG5vdCBpbmNsdWRlZCBoZXJlLCB0aGUKKyAgICAgKiByZXF1ZXN0IHdpbGwgcmVzdWx0IGluIGEgbm8tb3AuCisgICAgICoKKyAgICAgKiA8cD5TaW1pbGFybHksIGlmIGEgdmFyaWFudElkIHdhcyA8ZW0+bm90PC9lbT4gc3BlY2lmaWVkIHdoZW4gYWRkaW5nIHRoZSBncm91cCB0byBNREQgYW5kCisgICAgICogPGVtPmlzPC9lbT4gaW5jbHVkZWQgaGVyZSwgdGhlIHJlcXVlc3Qgd2lsbCBhbHNvIHJlc3VsdCBpbiBhIG5vLW9wLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldFZhcmlhbnRJZE9wdGlvbmFsKE9wdGlvbmFsPFN0cmluZz4gdmFyaWFudElkT3B0aW9uYWwpOworCisgICAgLyoqCisgICAgICogV2hlbiB0cnVlLCBvbmx5IHJlbW92ZSB0aGUgcGVuZGluZyB2ZXJzaW9uIG9mIHRoZSBmaWxlIGdyb3VwLCBsZWF2aW5nIHRoZSBhY3RpdmUgZG93bmxvYWRlZAorICAgICAqIHZlcnNpb24gdW50b3VjaGVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldFBlbmRpbmdPbmx5KGJvb2xlYW4gcGVuZGluZ09ubHkpOworCisgICAgcHVibGljIGFic3RyYWN0IFJlbW92ZUZpbGVHcm91cFJlcXVlc3QgYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9SZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0LmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1JlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMDZjMjNkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9SZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0LmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBhbmRyb2lkLmFjY291bnRzLkFjY291bnQ7CitpbXBvcnQgY29tLmdvb2dsZS5hdXRvLnZhbHVlLkF1dG9WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLmNvbmN1cnJlbnQuSW1tdXRhYmxlOworCisvKioKKyAqIFJlcXVlc3QgdG8gcmVtb3ZlIGZpbGUgZ3JvdXBzIGZyb20gTUREIHRoYXQgbWF0Y2ggZ2l2ZW4gZmlsdGVycy4KKyAqCisgKiA8cD5XaXRoIHRoZSBleGNlcHRpb24gb2YgYWNjb3VudCBmaWx0ZXJpbmcgKHNlZSBiZWxvdyksIG9ubHkgdGhlIGZpbHRlcnMgcHJvdmlkZWQgd2lsbCBiZSBhcHBsaWVkCisgKiB0byBmaWxlIGdyb3VwcyBpbiBNREQuIFRoYXQgaXMsIGEgZmlsZSBncm91cHMgd2lsbCBiZSByZW1vdmVkIGlmIGFuZCBvbmx5IGlmIGl0IG1hdGNoZXMgYWxsCisgKiA8ZW0+cHJvdmlkZWQ8L2VtPiBmaWx0ZXJzLiBTZWUgZWFjaCBmaWx0ZXIgc2V0dGVyIGRlc2NyaXB0aW9uIGZvciBtb3JlIGRldGFpbHMgb24gaG93IGZpbHRlcmluZworICogd2lsbCBiZSBwZXJmb3JtZWQuCisgKgorICogPHA+Tk9URTogQWNjb3VudCBmaWx0ZXJpbmcgaXMgYSBjb25zaWRlcmVkIHNwZWNpYWwgY2FzZSBhcyBmaWx0ZXJpbmcgaXMgcGVyZm9ybWVkIDxiPmJvdGg8L2I+CisgKiB3aGVuIGFjY291bnQgaXMgcHJvdmlkZWQgYW5kIHdoZW4gaXQgaXMgYWJzZW50LiBzZWUge0BsaW5rIEJ1aWxkZXIjc2V0QWNjb3VudE9wdGlvbmFsfSBmb3IgbW9yZQorICogZGV0YWlscyBvbiBhY2NvdW50IGZpbHRlcmluZy4KKyAqLworQEF1dG9WYWx1ZQorQEltbXV0YWJsZQorcHVibGljIGFic3RyYWN0IGNsYXNzIFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QgeworICBSZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0KCkge30KKworICBwdWJsaWMgYWJzdHJhY3QgT3B0aW9uYWw8QWNjb3VudD4gYWNjb3VudE9wdGlvbmFsKCk7CisKKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ldyBBdXRvVmFsdWVfUmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5CdWlsZGVyKCk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3R9LiAqLworICBAQXV0b1ZhbHVlLkJ1aWxkZXIKKyAgcHVibGljIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBCdWlsZGVyIHsKKyAgICBCdWlsZGVyKCkge30KKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHtAbGluayBBY2NvdW50fSB0aGF0IG11c3QgbWF0Y2ggZmlsdGVyZWQge0BsaW5rIERhdGFGaWxlR3JvdXB9cy4KKyAgICAgKgorICAgICAqIDxwPlNpbWlsYXIgdG8gb3RoZXIgTUREIEFQSXMsIGZpbGUgZ3JvdXBzIHRoYXQgYXJlIDxlbT5hY2NvdW50LWRlcGVuZGVudDwvZW0+IG11c3QgaGF2ZSB0aGF0CisgICAgICogYWNjb3VudCBwcm92aWRlZCBpbiBvcmRlciB0byBwZXJmb3JtIGEgcmVxdWVzdGVkIG9wZXJhdGlvbjsgZmlsZSBncm91cHMgdGhhdCBhcmUKKyAgICAgKiA8ZW0+YWNjb3VudC1pbmRlcGVuZGVudDwvZW0+IG11c3QgaGF2ZSBubyBhY2NvdW50IHByb3ZpZGVkIGluIG9yZGVyIHRvIHBlcmZvcm0gYSByZXF1ZXN0ZWQKKyAgICAgKiBvcGVyYXRpb24uCisgICAgICoKKyAgICAgKiA8cD5BY2NvdW50IGZpbHRlcmluZyB3b3JrcyB0aGUgc2FtZSB3YXk6IGlmIGFuIGFjY291bnQgaXMgcHJvdmlkZWQsIG9ubHkKKyAgICAgKiA8ZW0+YWNjb3VudC1kZXBlbmRlbnQ8L2VtPiBmaWxlIGdyb3VwcyBtYXRjaGluZyB0aGF0IGFjY291bnQgYXJlIGNvbnNpZGVyZWQgZm9yIHJlbW92YWw7IGlmCisgICAgICogYW4gYWNjb3VudCBpcyA8Yj5ub3Q8L2I+IHByb3ZpZGVkLCBvbmx5IDxlbT5hY2NvdW50LWluZGVwZW5kZW50PC9lbT4gZmlsZSBncm91cHMgYXJlCisgICAgICogY29uc2lkZXJlZCBmb3IgcmVtb3ZhbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRBY2NvdW50T3B0aW9uYWwoT3B0aW9uYWw8QWNjb3VudD4gYWNjb3VudE9wdGlvbmFsKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBSZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0IGJ1aWxkKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvUmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVzcG9uc2UuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvUmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVzcG9uc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNTRkYjc4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9SZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXNwb25zZS5qYXZhCkBAIC0wLDAgKzEsNDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgY29tLmdvb2dsZS5hdXRvLnZhbHVlLkF1dG9WYWx1ZTsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLmNvbmN1cnJlbnQuSW1tdXRhYmxlOworCisvKiogUmVzcG9uc2Ugb2YgTUREJ3Mge0BsaW5rIE1vYmlsZURhdGFEb3dubG9hZCNyZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJ9IEFQSS4gKi8KK0BBdXRvVmFsdWUKK0BJbW11dGFibGUKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBSZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXNwb25zZSB7CisgIFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlc3BvbnNlKCkge30KKworICBwdWJsaWMgYWJzdHJhY3QgaW50IHJlbW92ZWRGaWxlR3JvdXBzQ291bnQoKTsKKworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEF1dG9WYWx1ZV9SZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXJSZXNwb25zZS5CdWlsZGVyKCk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlc3BvbnNlfS4gKi8KKyAgQEF1dG9WYWx1ZS5CdWlsZGVyCisgIHB1YmxpYyBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgQnVpbGRlciB7CisgICAgQnVpbGRlcigpIHt9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBudW1iZXIgb2YgZmlsZSBncm91cHMgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQgYnkge0BsaW5rCisgICAgICogTW9iaWxlRGF0YURvd25sb2FkI3JlbW92ZUZpbGVHcm91cHNCeUZpbHRlcn0uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0UmVtb3ZlZEZpbGVHcm91cHNDb3VudChpbnQgcmVtb3ZlZEZpbGVHcm91cHNDb3VudCk7CisKKyAgICBwdWJsaWMgYWJzdHJhY3QgUmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVzcG9uc2UgYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9TaWxlbnRGZWVkYmFjay5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9TaWxlbnRGZWVkYmFjay5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiYzVjYzYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1NpbGVudEZlZWRiYWNrLmphdmEKQEAgLTAsMCArMSwyNiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmVycm9ycHJvbmUuYW5ub3RhdGlvbnMuRm9ybWF0TWV0aG9kOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5Gb3JtYXRTdHJpbmc7CisKKy8qKiBSZXNwb25zaWJsZSB0byBzZW5kIFNpbGVudCBGZWViYWNrcyBmb3IgTURELiAqLworcHVibGljIGludGVyZmFjZSBTaWxlbnRGZWVkYmFjayB7CisgIC8qKiBBc3luY2hyb25vdXNseSBzZW5kcyBzaWxlbnQgZmVlZGJhY2sgd2l0aCBnaXZlbiB0aHJvd2FibGUuICovCisgIEBGb3JtYXRNZXRob2QKKyAgdm9pZCBzZW5kKFRocm93YWJsZSB0aHJvd2FibGUsIEBGb3JtYXRTdHJpbmcgU3RyaW5nIGRlc2NyaXB0aW9uLCBPYmplY3QuLi4gYXJncyk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1NpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1NpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTRiNmE3YwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvU2luZ2xlRmlsZURvd25sb2FkTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZDsKKworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworCisvKioKKyAqIExpc3RlbmVyIGZvciB7QGxpbmsgTW9iaWxlRGF0YURvd25sb2FkI2Rvd25sb2FkRmlsZX0gdG8gcmVzcG9uZCB0byBkb3dubG9hZCBldmVudHMuCisgKgorICogPHA+U3VwcG9ydHMgcmVnaXN0ZXJpbmcgZm9yIGRvd25sb2FkIHByb2dyZXNzIHVwZGF0ZS4gQ2FsbGJhY2tzIHdpbGwgYmUgZXhlY3V0ZWQKKyAqIG9uIEBNZGRDb250cm9sRXhlY3V0b3IuIElmIHlvdSBuZWVkIHRvIGRvIGhlYXZ5IHdvcmssIHBsZWFzZSBvZmZsb2FkIHRvIGEgYmFja2dyb3VuZCB0YXNrLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFNpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyIHsKKyAgLyoqCisgICAqIFdpbGwgYmUgdHJpZ2dlcmVkIHBlcmlvZGljYWxseSB3aXRoIHRoZSBjdXJyZW50IGRvd25sb2FkZWQgc2l6ZSBvZiB0aGUgYmVpbmcgZG93bmxvYWRlZCBmaWxlLgorICAgKiBUaGlzIGNvdWxkIGJlIHVzZWQgdG8gc2hvdyBwcm9ncmVzc2JhciB0byB1c2Vycy4KKyAgICovCisgIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKTsKKworICAvKioKKyAgICogVGhpcyB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSBkb3dubG9hZCBpcyBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LiBNREQgd2lsbCBrZWVwIHRoZSBGb3JlZ3JvdW5kCisgICAqIERvd25sb2FkIFNlcnZpY2UgYWxpdmUgc28gdGhhdCB0aGUgb25Db21wbGV0ZSBjYW4gZmluaXNoIHdpdGhvdXQgYmVpbmcga2lsbGVkIGJ5IEFuZHJvaWQuCisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IG9uQ29tcGxldGUoKTsKKworICAvKiogVGhpcyB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSBkb3dubG9hZCBmYWlsZWQuICovCisgIHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KTsKKworICAvKioKKyAgICogQ2FsbGJhY2sgdHJpZ2dlcmVkIHdoZW4gYWxsIGRvd25sb2FkcyBhcmUgaW4gYSBzdGF0ZSB3YWl0aW5nIGZvciBjb25uZWN0aXZpdHksIGFuZCBubyBkb3dubG9hZAorICAgKiBwcm9ncmVzcyBpcyBoYXBwZW5pbmcgdW50aWwgY29ubmVjdGl2aXR5IHJlc3VtZXMuCisgICAqLworICB2b2lkIG9uUGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1NpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvU2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUyMWRmMmIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1NpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QuamF2YQpAQCAtMCwwICsxLDE2MCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC51dGlsLlBhaXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZENvbnN0cmFpbnRzOworaW1wb3J0IGNvbS5nb29nbGUuYXV0by52YWx1ZS5BdXRvVmFsdWU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CisKKy8qKgorICogUmVxdWVzdCB0byBkb3dubG9hZCBhIHNpbmdsZSBmaWxlLgorICoKKyAqIDxwPlRoaXMgZGlmZmVycyBmcm9tIHtAbGluayBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3R9IGluIHR3byBtYWluIHdheXM6CisgKgorICogPHA+MSkgT25seSBhIHNpbmdsZSBmaWxlIGlzIGRvd25sb2FkZWQgcmF0aGVyIHRoYW4gYSBncm91cCBvZiBmaWxlcy4KKyAqCisgKiA8cD4yKSBNREQgZG9lcyBOT1QgbWFuYWdlIHRoZSBmaWxlIGFmdGVyIGRvd25sb2FkLiBUaGUgY2FsbGVyIHNwZWNpZmllcyB0aGF0IGRlc3RpbmF0aW9uIG9mIHRoZQorICogZG93bmxvYWQgYW5kIGlzIHJlc3BvbnNpYmxlIGZvciBtYW5hZ2luZyB0aGUgZmlsZSBhZnRlciBkb3dubG9hZC4KKyAqLworQEF1dG9WYWx1ZQorcHVibGljIGFic3RyYWN0IGNsYXNzIFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QgeworCisgIC8vIERlZmF1bHQgdmFsdWUgZm9yIFRyYWZmaWMgVGFnIGlmIG5vdCBzZXQgYnkgY2xpZW50cy4KKyAgLy8gTUREIHdpbGwgbm90IHRhZyB0aGUgdHJhZmZpYyBpZiB0aGUgVHJhZmZpY1RhZyBpcyBub3Qgc2V0IHRvIGEgdmFsaWQgdmFsdWUgKD4wKS4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOU1BFQ0lGSUVEX1RSQUZGSUNfVEFHID0gLTE7CisKKyAgU2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCgpIHt9CisKKyAgLy8gVGhlIERlc3RpbmF0aW9uIEZpbGUgVXJpIHRvIGRvd25sb2FkIHRoZSBmaWxlIGF0LgorICBwdWJsaWMgYWJzdHJhY3QgVXJpIGRlc3RpbmF0aW9uRmlsZVVyaSgpOworCisgIC8vIFRoZSB1cmwgdG8gZG93bmxvYWQgdGhlIGZpbGUgZnJvbS4KKyAgcHVibGljIGFic3RyYWN0IFN0cmluZyB1cmxUb0Rvd25sb2FkKCk7CisKKyAgLy8gQ29uZGl0aW9ucyB1bmRlciB3aGljaCB0aGlzIGZpbGUgc2hvdWxkIGJlIGRvd25sb2FkZWQuCisgIHB1YmxpYyBhYnN0cmFjdCBEb3dubG9hZENvbnN0cmFpbnRzIGRvd25sb2FkQ29uc3RyYWludHMoKTsKKworICAvKiogSWYgcHJlc2VudCwgd2lsbCByZWNlaXZlIGRvd25sb2FkIHByb2dyZXNzIHVwZGF0ZS4gKi8KKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPFNpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyPiBsaXN0ZW5lck9wdGlvbmFsKCk7CisKKyAgLy8gVHJhZmZpYyB0YWcgdXNlZCBmb3IgdGhpcyByZXF1ZXN0LgorICAvLyBJZiBub3Qgc2V0LCBpdCB3aWxsIHRha2UgdGhlIGRlZmF1bHQgdmFsdWUgb2YgVU5TUEVDSUZJRURfVFJBRkZJQ19UQUcgYW5kIE1ERCB3aWxsIG5vdCB0YWcgdGhlCisgIC8vIHRyYWZmaWMuCisgIHB1YmxpYyBhYnN0cmFjdCBpbnQgdHJhZmZpY1RhZygpOworCisgIC8vIFRoZSBleHRyYSBIVFRQIGhlYWRlcnMgZm9yIHRoaXMgcmVxdWVzdC4KKyAgcHVibGljIGFic3RyYWN0IEltbXV0YWJsZUxpc3Q8UGFpcjxTdHJpbmcsIFN0cmluZz4+IGV4dHJhSHR0cEhlYWRlcnMoKTsKKworICAvLyBUaGUgc2l6ZSBvZiB0aGUgYmVpbmcgZG93bmxvYWRlZCBmaWxlIGluIGJ5dGVzLgorICAvLyBUaGlzIGlzIHVzZWQgdG8gZGlzcGxheSB0aGUgcHJvZ3Jlc3NiYXIuCisgIC8vIElmIG5vdCBzcGVjaWZpZWQsIGFuIGluZGV0ZXJtaW5hdGUgcHJvZ3Jlc3NiYXIgd2lsbCBiZSBkaXNwbGF5ZWQuCisgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLmFuZHJvaWQuY29tL3JlZmVyZW5jZS9hbmRyb2lkL2FwcC9Ob3RpZmljYXRpb24uQnVpbGRlci5odG1sI3NldFByb2dyZXNzKGludCwlMjBpbnQsJTIwYm9vbGVhbikKKyAgcHVibGljIGFic3RyYWN0IGludCBmaWxlU2l6ZUJ5dGVzKCk7CisKKyAgLy8gVXNlZCBvbmx5IGJ5IEZvcmVncm91bmQgZG93bmxvYWQuCisgIC8vIFRoZSBDb250ZW50IFRpdGxlIG9mIHRoZSBhc3NvY2lhdGVkIE5vdGlmaWNhdGlvbiBmb3IgdGhpcyBkb3dubG9hZC4KKyAgcHVibGljIGFic3RyYWN0IFN0cmluZyBub3RpZmljYXRpb25Db250ZW50VGl0bGUoKTsKKworICAvLyBVc2VkIG9ubHkgYnkgRm9yZWdyb3VuZCBkb3dubG9hZC4KKyAgLy8gSWYgUHJlc2VudCwgdGhlIENvbnRlbnQgVGV4dCAoZGVzY3JpcHRpb24pIG9mIHRoZSBhc3NvY2lhdGVkIE5vdGlmaWNhdGlvbiBmb3IgdGhpcyBkb3dubG9hZC4KKyAgLy8gT3RoZXJ3aXNlLCB0aGUgQ29udGVudCBUZXh0IHdpbGwgYmUgdGhlIHVybCB0byBkb3dubG9hZC4KKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPFN0cmluZz4gbm90aWZpY2F0aW9uQ29udGVudFRleHRPcHRpb25hbCgpOworCisgIC8vIFdoZXRoZXIgdG8gc2hvdyB0aGUgZG93bmxvYWRlZCBub3RpZmljYXRpb24uIElmIGZhbHNlLCBNREQgd2lsbCBhdXRvbWF0aWNhbGx5IHJlbW92ZSB0aGlzCisgIC8vIG5vdGlmaWNhdGlvbiB3aGVuIHRoZSBkb3dubG9hZCBmaW5pc2hlZC4KKyAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gc2hvd0Rvd25sb2FkZWROb3RpZmljYXRpb24oKTsKKworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEF1dG9WYWx1ZV9TaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0LkJ1aWxkZXIoKQorICAgICAgICAuc2V0VHJhZmZpY1RhZyhVTlNQRUNJRklFRF9UUkFGRklDX1RBRykKKyAgICAgICAgLnNldEV4dHJhSHR0cEhlYWRlcnMoSW1tdXRhYmxlTGlzdC5vZigpKQorICAgICAgICAuc2V0RmlsZVNpemVCeXRlcygwKQorICAgICAgICAuc2V0U2hvd0Rvd25sb2FkZWROb3RpZmljYXRpb24odHJ1ZSkKKyAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5OT05FKTsKKyAgfQorCisgIC8qKiBCdWlsZGVyIGZvciB7QGxpbmsgRG93bmxvYWRSZXF1ZXN0fS4gKi8KKyAgQEF1dG9WYWx1ZS5CdWlsZGVyCisgIHB1YmxpYyBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgQnVpbGRlciB7CisgICAgQnVpbGRlcigpIHt9CisKKyAgICAvKiogU2V0cyB0aGUgZGVzdGluYXRpb24gZmlsZSB1cmkuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0RGVzdGluYXRpb25GaWxlVXJpKFVyaSBmaWxlVXJpKTsKKworICAgIC8qKiBTZXRzIHRoZSB1cmwgdG8gZG93bmxvYWQuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0VXJsVG9Eb3dubG9hZChTdHJpbmcgdXJsVG9Eb3dubG9hZCk7CisKKyAgICAvKiogU2V0cyB0aGUgRG93bG9hZENvbnN0cmFpbnRzLiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cyBkb3dubG9hZENvbnN0cmFpbnRzKTsKKworICAgIC8qKiBTZXRzIHRoZSBvcHRpb25hbCBkb3dubG9hZCBsaXN0ZW5lci4gSWYgcHJlc2VudCwgd2lsbCByZWNlaXZlIGRvd25sb2FkIHByb2dyZXNzIHVwZGF0ZS4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRMaXN0ZW5lck9wdGlvbmFsKAorICAgICAgICBPcHRpb25hbDxTaW5nbGVGaWxlRG93bmxvYWRMaXN0ZW5lcj4gbGlzdGVuZXJPcHRpb25hbCk7CisKKyAgICAvKiogU2V0cyB0aGUgdHJhZmZpYyB0YWcgZm9yIHRoaXMgcmVxdWVzdC4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRUcmFmZmljVGFnKGludCB0cmFmZmljVGFnKTsKKworICAgIC8qKiBTZXRzIHRoZSBleHRyYSBIVFRQIGhlYWRlcnMgZm9yIHRoaXMgcmVxdWVzdC4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRFeHRyYUh0dHBIZWFkZXJzKAorICAgICAgICBJbW11dGFibGVMaXN0PFBhaXI8U3RyaW5nLCBTdHJpbmc+PiBleHRyYUh0dHBIZWFkZXJzKTsKKworICAgIC8qKgorICAgICAqIFRoZSBzaXplIG9mIHRoZSBiZWluZyBkb3dubG9hZGVkIGZpbGUgaW4gYnl0ZXMuIFRoaXMgaXMgdXNlZCB0byBkaXNwbGF5IHRoZSBwcm9ncmVzc2Jhci4gSWYKKyAgICAgKiBub3Qgc3BlY2lmaWVkLCBhIGluZGV0ZXJtaW5hdGUgcHJvZ3Jlc3NiYXIgd2lsbCBiZSBkaXNwbGF5ZWQuCisgICAgICogaHR0cHM6Ly9kZXZlbG9wZXIuYW5kcm9pZC5jb20vcmVmZXJlbmNlL2FuZHJvaWQvYXBwL05vdGlmaWNhdGlvbi5CdWlsZGVyLmh0bWwjc2V0UHJvZ3Jlc3MoaW50LCUyMGludCwlMjBib29sZWFuKQorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldEZpbGVTaXplQnl0ZXMoaW50IGZpbGVTaXplQnl0ZXMpOworCisgICAgLyoqIFNldHMgdGhlIE5vdGlmaWNhdGlvbiBDb250ZW50IFRpbGUgd2hpY2ggd2lsbCBiZSB1c2VkIGZvciBmb3JlZ3JvdW5kIGRvd25sb2FkICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0Tm90aWZpY2F0aW9uQ29udGVudFRpdGxlKFN0cmluZyBub3RpZmljYXRpb25Db250ZW50VGl0bGUpOworCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgTm90aWZpY2F0aW9uIENvbnRleHQgVGV4dCB3aGljaCB3aWxsIGJlIHVzZWQgZm9yIGZvcmVncm91bmQgZG93bmxvYWRzLgorICAgICAqCisgICAgICogPHA+SWYgbm90IHNldCwgdGhlIHVybCB0byBkb3dubG9hZCB3aWxsIGJlIHVzZWQgaW5zdGVhZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXROb3RpZmljYXRpb25Db250ZW50VGV4dE9wdGlvbmFsKAorICAgICAgICBPcHRpb25hbDxTdHJpbmc+IG5vdGlmaWNhdGlvbkNvbnRlbnRUZXh0T3B0aW9uYWwpOworCisgICAgLyoqCisgICAgICogU2V0cyB0byBzaG93IERvd25sb2FkZWQgTm90aWZpY2F0aW9uIGFmdGVyIHRoZSBkb3dubG9hZCBmaW5pc2hlZCBzdWNjZXNzZnVsbHkuIFRoaXMgaXMgb25seQorICAgICAqIGJlIHVzZWQgZm9yIGZvcmVncm91bmQgZG93bmxvYWQuIERlZmF1bHQgdmFsdWUgaXMgdG8gc2hvdyB0aGUgZG93bmxvYWRlZCBub3RpZmljYXRpb24uCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0U2hvd0Rvd25sb2FkZWROb3RpZmljYXRpb24oYm9vbGVhbiBzaG93RG93bmxvYWRlZE5vdGlmaWNhdGlvbik7CisKKyAgICAvKiogQnVpbGRzIHtAbGluayBTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0fS4gKi8KKyAgICBwdWJsaWMgZmluYWwgU2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCBidWlsZCgpIHsKKyAgICAgIC8vIElmIG5vdGlmaWNhdGlvbiBjb250ZW50IHRpdGxlIGlzIG5vdCBwcm92aWRlZCwgdXNlIHVybFRvRG93bmxvYWQgYXMgYSBmYWxsYmFjaworICAgICAgaWYgKCFub3RpZmljYXRpb25Db250ZW50VGl0bGUoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICBzZXROb3RpZmljYXRpb25Db250ZW50VGl0bGUodXJsVG9Eb3dubG9hZCgpKTsKKyAgICAgIH0KKyAgICAgIC8vIFVzZSBBdXRvVmFsdWUncyBnZW5lcmF0ZWQgYnVpbGQgdG8gZmluaXNoIGJ1aWxkaW5nLgorICAgICAgcmV0dXJuIGF1dG9CdWlsZCgpOworICAgIH0KKworICAgIC8vIHByaXZhdGUgZ2V0dGVyIGdlbmVyYXRlZCBieSBBdXRvVmFsdWUgZm9yIGFjY2VzcyBpbiBidWlsZCgpLgorICAgIGFic3RyYWN0IFN0cmluZyB1cmxUb0Rvd25sb2FkKCk7CisKKyAgICAvLyBwcml2YXRlIGdldHRlciBnZW5lcmF0ZWQgYnkgQXV0b1ZhbHVlIGZvciBhY2Nlc3MgaW4gYnVpbGQoKS4KKyAgICBhYnN0cmFjdCBPcHRpb25hbDxTdHJpbmc+IG5vdGlmaWNhdGlvbkNvbnRlbnRUaXRsZSgpOworCisgICAgLy8gcHJpdmF0ZSBidWlsZCBtZXRob2QgdG8gYmUgZ2VuZXJhdGVkIGJ5IEF1dG9WYWx1ZS4KKyAgICBhYnN0cmFjdCBTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0IGF1dG9CdWlsZCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1Rhc2tTY2hlZHVsZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvVGFza1NjaGVkdWxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMwNmMyMmIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1Rhc2tTY2hlZHVsZXIuamF2YQpAQCAtMCwwICsxLDE1MSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmF1dG8udmFsdWUuQXV0b1ZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CisKKy8qKiBJbnRlcmZhY2UgZm9yIHRhc2sgc2NoZWR1bGluZyAqLworcHVibGljIGludGVyZmFjZSBUYXNrU2NoZWR1bGVyIHsKKworICAvKioKKyAgICogVGFnIGZvciBkYWlseSBtZGQgbWFpbnRlbmFuY2UgdGFzaywgdGhhdCAqc2hvdWxkKiBiZSBydW4gb25jZSBhbmQgb25seSBvbmNlIGV2ZXJ5IDI0IGhvdXJzLgorICAgKgorICAgKiA8cD5CeSBkZWZhdWx0LCB0aGlzIHRhc2sgcnVucyBvbiBjaGFyZ2luZy4KKyAgICovCisgIFN0cmluZyBNQUlOVEVOQU5DRV9QRVJJT0RJQ19UQVNLID0gIk1ERC5NQUlOVEVOQU5DRS5QRVJJT0RJQy5HQ00uVEFTSyI7CisKKyAgLyoqCisgICAqIFRhZyBmb3IgbWRkIHRhc2sgdGhhdCBkb2Vzbid0IHJlcXVpcmUgYW55IG5ldHdvcmsuIFRoaXMgaXMgdXNlZCB0byBwZXJmb3JtIHNvbWUgcm91dGluZQorICAgKiBvcGVyYXRpb24gdGhhdCBkbyBub3QgcmVxdWlyZSBuZXR3b3JrLCBpbiBjYXNlIGEgZGV2aWNlIGRvZXNuJ3QgY29ubmVjdCB0byBhbnkgbmV0d29yayBmb3IgYQorICAgKiBsb25nIHRpbWUuCisgICAqCisgICAqIDxwPkJ5IGRlZmF1bHQsIHRoaXMgdGFzayBydW5zIG9uIGNoYXJnaW5nIG9uY2UgZXZlcnkgNiBob3Vycy4KKyAgICovCisgIFN0cmluZyBDSEFSR0lOR19QRVJJT0RJQ19UQVNLID0gIk1ERC5DSEFSR0lORy5QRVJJT0RJQy5UQVNLIjsKKworICAvKioKKyAgICogVGFnIGZvciBtZGQgdGFzayB0aGF0IHJ1bnMgb24gY2VsbHVsYXIgbmV0d29yay4gVGhpcyBpcyB1c2VkIHRvIHByaW1hcmlseSBkb3dubG9hZCBmaWxlIGdyb3VwcworICAgKiB0aGF0IGNhbiBiZSBkb3dubG9hZCBvbiBjZWxsdWxhciBuZXR3b3JrLgorICAgKgorICAgKiA8cD5CeSBkZWZhdWx0LCB0aGlzIHRhc2sgcnVucyBvbiBjaGFyZ2luZyBvbmNlIGV2ZXJ5IDYgaG91cnMuIFRoaXMgdGFzayBjYW4gYmUgc2tpcHBlZCBpZgorICAgKiBub3RoaW5nIGlzIGRvd25sb2FkZWQgb24gY2VsbHVsYXIuCisgICAqLworICBTdHJpbmcgQ0VMTFVMQVJfQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSyA9ICJNREQuQ0VMTFVMQVIuQ0hBUkdJTkcuUEVSSU9ESUMuVEFTSyI7CisKKyAgLyoqCisgICAqIFRhZyBmb3IgbWRkIHRhc2sgdGhhdCBydW5zIG9uIHdpZmkgbmV0d29yay4gVGhpcyBpcyB1c2VkIHRvIHByaW1hcmlseSBkb3dubG9hZCBmaWxlIGdyb3VwcyB0aGF0CisgICAqIGNhbiBiZSBkb3dubG9hZCBvbmx5IG9uIHdpZmkgbmV0d29yay4KKyAgICoKKyAgICogPHA+QnkgZGVmYXVsdCwgdGhpcyB0YXNrIHJ1bnMgb24gY2hhcmdpbmcgb25jZSBldmVyeSA2IGhvdXJzLiBUaGlzIHRhc2sgY2FuIGJlIHNraXBwZWQgaWYKKyAgICogbm90aGluZyBpcyByZXN0cmljdGVkIHRvIHdpZmkuCisgICAqLworICBTdHJpbmcgV0lGSV9DSEFSR0lOR19QRVJJT0RJQ19UQVNLID0gIk1ERC5XSUZJLkNIQVJHSU5HLlBFUklPRElDLlRBU0siOworCisgIC8qKiBSZXF1aXJlZCBuZXR3b3JrIHN0YXRlIG9mIHRoZSBkZXZpY2Ugd2hlbiB0byBydW4gdGhlIHRhc2suICovCisgIGVudW0gTmV0d29ya1N0YXRlIHsKKyAgICAvLyBNZXRlcmVkIG9yIHVubWV0ZXJlZCBuZXR3b3JrIGF2YWlsYWJsZS4KKyAgICBORVRXT1JLX1NUQVRFX0NPTk5FQ1RFRCwKKworICAgIC8vIFVubWV0ZXJlZCBuZXR3b3JrIGF2YWlsYWJsZS4KKyAgICBORVRXT1JLX1NUQVRFX1VOTUVURVJFRCwKKworICAgIC8vIE5ldHdvcmsgbm90IHJlcXVpcmVkLgorICAgIE5FVFdPUktfU1RBVEVfQU5ZLAorICB9CisKKyAgLyoqIENvbnN0cmFpbnRPdmVycmlkZXMgdG8gYWxsb3cgY2xpZW50cyB0byBvdmVycmlkZSBiYWNrZ3JvdW5kIHRhc2sgY29uc3RyYWludHMuICovCisgIEBBdXRvVmFsdWUKKyAgYWJzdHJhY3QgY2xhc3MgQ29uc3RyYWludE92ZXJyaWRlcyB7CisgICAgQ29uc3RyYWludE92ZXJyaWRlcygpIHt9CisKKyAgICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiByZXF1aXJlc0RldmljZUlkbGUoKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHJlcXVpcmVzQ2hhcmdpbmcoKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHJlcXVpcmVzQmF0dGVyeU5vdExvdygpOworCisgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgICAvLyBTZXR0aW5nIGRlZmF1bHQgdmFsdWVzLgorICAgICAgcmV0dXJuIG5ldyBBdXRvVmFsdWVfVGFza1NjaGVkdWxlcl9Db25zdHJhaW50T3ZlcnJpZGVzLkJ1aWxkZXIoKQorICAgICAgICAgIC5zZXRSZXF1aXJlc0RldmljZUlkbGUodHJ1ZSkKKyAgICAgICAgICAuc2V0UmVxdWlyZXNDaGFyZ2luZyh0cnVlKQorICAgICAgICAgIC5zZXRSZXF1aXJlc0JhdHRlcnlOb3RMb3coZmFsc2UpOworICAgIH0KKworICAgIC8qKiBCdWlsZGVyIGZvciB7QGxpbmsgQ29uc3RyYWludE92ZXJyaWRlc30uICovCisgICAgQEF1dG9WYWx1ZS5CdWlsZGVyCisgICAgcHVibGljIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBCdWlsZGVyIHsKKworICAgICAgQnVpbGRlcigpIHt9CisKKyAgICAgIC8qKgorICAgICAgICogU2V0cyB3aGV0aGVyIGRldmljZSBzaG91bGQgYmUgaWRsZSBmb3IgdGhlIE1ERCB0YXNrIHRvIHJ1bi4gVGhlIGRlZmF1bHQgdmFsdWUgaXMge0Bjb2RlCisgICAgICAgKiB0cnVlfS4KKyAgICAgICAqCisgICAgICAgKiBAcGFyYW0gcmVxdWlyZXNEZXZpY2VJZGxlIHtAY29kZSB0cnVlfSBpZiBkZXZpY2UgbXVzdCBiZSBpZGxlIGZvciB0aGUgd29yayB0byBydW4KKyAgICAgICAqLworICAgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0UmVxdWlyZXNEZXZpY2VJZGxlKGJvb2xlYW4gcmVxdWlyZXNEZXZpY2VJZGxlKTsKKworICAgICAgLyoqCisgICAgICAgKiBTZXRzIHdoZXRoZXIgZGV2aWNlIHNob3VsZCBiZSBjaGFyZ2luZyBmb3IgdGhlIE1ERCB0YXNrIHRvIHJ1bi4gVGhlIGRlZmF1bHQgdmFsdWUgaXMge0Bjb2RlCisgICAgICAgKiB0cnVlfS4KKyAgICAgICAqCisgICAgICAgKiBAcGFyYW0gcmVxdWlyZXNDaGFyZ2luZyB7QGNvZGUgdHJ1ZX0gaWYgZGV2aWNlIG11c3QgYmUgY2hhcmdpbmcgZm9yIHRoZSB3b3JrIHRvIHJ1bgorICAgICAgICovCisgICAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRSZXF1aXJlc0NoYXJnaW5nKGJvb2xlYW4gcmVxdWlyZXNDaGFyZ2luZyk7CisKKyAgICAgIC8qKgorICAgICAgICogU2V0cyB3aGV0aGVyIGRldmljZSBiYXR0ZXJ5IHNob3VsZCBiZSBhdCBhbiBhY2NlcHRhYmxlIGxldmVsIGZvciB0aGUgTUREIHRhc2sgdG8gcnVuLiBUaGUKKyAgICAgICAqIGRlZmF1bHQgdmFsdWUgaXMge0Bjb2RlIGZhbHNlfS4KKyAgICAgICAqCisgICAgICAgKiBAcGFyYW0gcmVxdWlyZXNCYXR0ZXJ5Tm90TG93IHtAY29kZSB0cnVlfSBpZiB0aGUgYmF0dGVyeSBzaG91bGQgYmUgYXQgYW4gYWNjZXB0YWJsZSBsZXZlbAorICAgICAgICogICAgIGZvciB0aGUgd29yayB0byBydW4KKyAgICAgICAqLworICAgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0UmVxdWlyZXNCYXR0ZXJ5Tm90TG93KGJvb2xlYW4gcmVxdWlyZXNCYXR0ZXJ5Tm90TG93KTsKKworICAgICAgcHVibGljIGFic3RyYWN0IENvbnN0cmFpbnRPdmVycmlkZXMgYnVpbGQoKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogU2NoZWR1bGUgYSBwZXJpb2RpYyB1c2luZyBvbmUgb2YgR0NNLCBGSkQgb3IgV29yayBNYW5hZ2VyLiBJZiB5b3UgbmVlZCB0byBvdmVycmlkZSBpZGxlIGFuZC9vcgorICAgKiBjaGFyZ2luZyByZXF1aXJlbWVudHMsIGNhbGwgdGhlIG1ldGhvZCB0aGF0IHRha2VzIGluIHRoZSBjb25zdHJhaW50T3ZlcnJpZGVzIGluc3RlYWQuCisgICAqCisgICAqIEBwYXJhbSB0YWcgdGFnIG9mIHRoZSBzY2hlZHVsZWQgdGFzay4KKyAgICogQHBhcmFtIHBlcmlvZCBwZXJpb2Qgd2l0aCB3aGljaCB0aGUgc2NoZWR1bGVkIHRhc2sgc2hvdWxkIGJlIHJ1bi4KKyAgICogQHBhcmFtIG5ldHdvcmtTdGF0ZSBuZXR3b3JrIHN0YXRlIHdoZW4gdG8gcnVuIHRoZSB0YXNrLgorICAgKi8KKyAgdm9pZCBzY2hlZHVsZVBlcmlvZGljVGFzayhTdHJpbmcgdGFnLCBsb25nIHBlcmlvZCwgTmV0d29ya1N0YXRlIG5ldHdvcmtTdGF0ZSk7CisKKyAgLyoqCisgICAqIFNjaGVkdWxlIGEgcGVyaW9kaWMgdXNpbmcgV29yayBNYW5hZ2VyLgorICAgKgorICAgKiBAcGFyYW0gdGFnIHRhZyBvZiB0aGUgc2NoZWR1bGVkIHRhc2suCisgICAqIEBwYXJhbSBwZXJpb2QgcGVyaW9kIHdpdGggd2hpY2ggdGhlIHNjaGVkdWxlZCB0YXNrIHNob3VsZCBiZSBydW4uCisgICAqIEBwYXJhbSBuZXR3b3JrU3RhdGUgbmV0d29yayBzdGF0ZSB3aGVuIHRvIHJ1biB0aGUgdGFzay4KKyAgICogQHBhcmFtIGNvbnN0cmFpbnRPdmVycmlkZXMgYWxsb3cgb3ZlcnJpZGluZyB0aGUgY2hhcmdpbmcgYW5kIGlkbGUgcmVxdWlyZW1lbnRzLgorICAgKi8KKyAgZGVmYXVsdCB2b2lkIHNjaGVkdWxlUGVyaW9kaWNUYXNrKAorICAgICAgU3RyaW5nIHRhZywKKyAgICAgIGxvbmcgcGVyaW9kLAorICAgICAgTmV0d29ya1N0YXRlIG5ldHdvcmtTdGF0ZSwKKyAgICAgIE9wdGlvbmFsPENvbnN0cmFpbnRPdmVycmlkZXM+IGNvbnN0cmFpbnRPdmVycmlkZXMpIHsKKyAgICAvLyBEZWZhdWx0IGltcGxlbWVudGF0aW9uIHdpbGwgbm90IG92ZXJyaWRlIGFueSBjb25zdHJhaW50cy4gV2l0aG91dCB0aGlzLCB3ZSB3aWxsIGhhdmUgdG8KKyAgICAvLyB1cGRhdGUgYWxsIGNsaWVudHMuCisgICAgc2NoZWR1bGVQZXJpb2RpY1Rhc2sodGFnLCBwZXJpb2QsIG5ldHdvcmtTdGF0ZSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvVGltZVNvdXJjZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9UaW1lU291cmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDYzMjM4MgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvVGltZVNvdXJjZS5qYXZhCkBAIC0wLDAgKzEsMjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCisvKioKKyAqIEludGVyZmFjZSB0aHJvdWdoIHdoaWNoIHRoZSBTeXN0ZW1DbG9jayBjYW4gYmUgcmVhZC4KKyAqCisgKiA8cD5UaGlzIGludGVyZmFjZSBpcyBhbmFsb2dvdXMgdG8ge0Bjb2RlIGNvbS5nb29nbGUuY29tbW9uLnRpbWUuVGltZVNvdXJjZSNub3cjdG9FcG9jaE1pbGxpfQorICogd2l0aG91dCB0aGUgZGVwZW5kZW5jeSBvbiBKYXZhOC4KKyAqLworcHVibGljIGludGVyZmFjZSBUaW1lU291cmNlIHsKKyAgLyoqIFJldHVybnMgdGhlIGN1cnJlbnQgc3lzdGVtIHRpbWUgaW4gbWlsbGlzZWNvbmRzIHNpbmNlIEphbnVhcnkgMSwgMTk3MCAwMDowMDowMCBVVEMuICovCisgIGxvbmcgY3VycmVudFRpbWVNaWxsaXMoKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvVXNhZ2VFdmVudC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Vc2FnZUV2ZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGVjNmE2MAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvVXNhZ2VFdmVudC5qYXZhCkBAIC0wLDAgKzEsNDggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgY29tLmdvb2dsZS5hdXRvLnZhbHVlLkF1dG9WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5DbGllbnRDb25maWdQcm90by5DbGllbnRGaWxlR3JvdXA7CisKKy8qKgorICogUmVwcmVzZW50cyBlcnJvcnMgd2l0aCBvciB1c2FnZSBvZiBhIGZpbGUgZ3JvdXAuIFRoaXMgaW5mb3JtYXRpb24gd2lsbCBiZSByZXBvcnRlZCB0byBNREQgd2hpY2gKKyAqIHdpbGwgbG9nIGl0IHRvIGNsZWFyY3V0LgorICovCitAQXV0b1ZhbHVlCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgVXNhZ2VFdmVudCB7CisgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZXZlbnRDb2RlKCk7CisKKyAgcHVibGljIGFic3RyYWN0IGxvbmcgYXBwVmVyc2lvbigpOworCisgIHB1YmxpYyBhYnN0cmFjdCBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwKCk7CisKKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIGJ1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ldyBBdXRvVmFsdWVfVXNhZ2VFdmVudC5CdWlsZGVyKCk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3IgVXNhZ2VFdmVudC4gKi8KKyAgQEF1dG9WYWx1ZS5CdWlsZGVyCisgIHB1YmxpYyBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgQnVpbGRlciB7CisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0RXZlbnRDb2RlKGludCBldmVudENvZGUpOworCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0QXBwVmVyc2lvbihsb25nIGFwcFZlcnNpb24pOworCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0Q2xpZW50RmlsZUdyb3VwKENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXApOworCisgICAgcHVibGljIGFic3RyYWN0IFVzYWdlRXZlbnQgYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hY2NvdW50L0FjY291bnRNYW5hZ2VyQWNjb3VudFNvdXJjZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hY2NvdW50L0FjY291bnRNYW5hZ2VyQWNjb3VudFNvdXJjZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIzMGY1Y2IKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2FjY291bnQvQWNjb3VudE1hbmFnZXJBY2NvdW50U291cmNlLmphdmEKQEAgLTAsMCArMSw0NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuYWNjb3VudDsKKworaW1wb3J0IGFuZHJvaWQuYWNjb3VudHMuQWNjb3VudDsKK2ltcG9ydCBhbmRyb2lkLmFjY291bnRzLkFjY291bnRNYW5hZ2VyOworaW1wb3J0IGFuZHJvaWQuYW5ub3RhdGlvbi5UYXJnZXRBcGk7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZC5WRVJTSU9OX0NPREVTOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkFjY291bnRTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworCisvKiogQW4gTUREIEFjY291bnRTb3VyY2UgYmFja2VkIGJ5IEFjY291bnRNYW5hZ2VyIHdpdGggdHlwZSAiY29tLmdvb2dsZSIuICovCitwdWJsaWMgZmluYWwgY2xhc3MgQWNjb3VudE1hbmFnZXJBY2NvdW50U291cmNlIGltcGxlbWVudHMgQWNjb3VudFNvdXJjZSB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBHT09HTEVfQUNDT1VOVF9UWVBFID0gImNvbS5nb29nbGUiOworCisgIHByaXZhdGUgZmluYWwgU3RyaW5nIHBhY2thZ2VOYW1lOworICBwcml2YXRlIGZpbmFsIEFjY291bnRNYW5hZ2VyIGFjY291bnRNYW5hZ2VyOworCisgIHB1YmxpYyBBY2NvdW50TWFuYWdlckFjY291bnRTb3VyY2UoQ29udGV4dCBjb250ZXh0KSB7CisgICAgdGhpcy5wYWNrYWdlTmFtZSA9IGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKTsKKyAgICB0aGlzLmFjY291bnRNYW5hZ2VyID0gQWNjb3VudE1hbmFnZXIuZ2V0KGNvbnRleHQpOworICB9CisKKyAgQFRhcmdldEFwaShWRVJTSU9OX0NPREVTLkpFTExZX0JFQU5fTVIyKQorICBAT3ZlcnJpZGUKKyAgcHVibGljIEltbXV0YWJsZUxpc3Q8QWNjb3VudD4gZ2V0QWxsQWNjb3VudHMoKSB7CisgICAgQWNjb3VudFtdIGFjY291bnRzID0KKyAgICAgICAgYWNjb3VudE1hbmFnZXIuZ2V0QWNjb3VudHNCeVR5cGVGb3JQYWNrYWdlKEdPT0dMRV9BQ0NPVU5UX1RZUEUsIHBhY2thZ2VOYW1lKTsKKyAgICByZXR1cm4gSW1tdXRhYmxlTGlzdC5jb3B5T2YoYWNjb3VudHMpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2FjY291bnQvQWNjb3VudFV0aWwuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYWNjb3VudC9BY2NvdW50VXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxMjIyNmUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2FjY291bnQvQWNjb3VudFV0aWwuamF2YQpAQCAtMCwwICsxLDc2IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5hY2NvdW50OworCitpbXBvcnQgYW5kcm9pZC5hY2NvdW50cy5BY2NvdW50OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1kZENvbnN0YW50czsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5OdWxsYWJsZTsKKworLyoqIFV0aWxzIHRvIGhlbHAgd2l0aCBhY2NvdW50IG1hbmlwdWxhdGlvbi4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBY2NvdW50VXRpbCB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiQWNjb3VudFV0aWwiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUNDT1VOVF9ERUxJTUlURVIgPSAiOiI7CisKKyAgcHJpdmF0ZSBBY2NvdW50VXRpbCgpIHt9CisKKyAgLyoqCisgICAqIENyZWF0ZXMge0BsaW5rIEFjY291bnR9IGZyb20gbmFtZSBhbmQgdHlwZSBhZnRlciB2YWxpZGF0aW9uLgorICAgKgorICAgKiBAcmV0dXJuIFRoZSBhY2NvdW50IGluc3RhbmNlIHdpdGggdGhlIGdpdmVuIG5hbWUgYW5kIHR5cGUuIFJldHVybnMgbnVsbCBpZiB0aGVyZSBpcyBhbnkgZXJyb3IuCisgICAqLworICBATnVsbGFibGUKKyAgcHVibGljIHN0YXRpYyBBY2NvdW50IGNyZWF0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHR5cGUpIHsKKyAgICBpZiAoIXZhbGlkYXRlKG5hbWUpIHx8ICF2YWxpZGF0ZSh0eXBlKSkgeworICAgICAgTG9nVXRpbC5lKCIlczogVW5hYmxlIHRvIGNyZWF0ZSBBY2NvdW50IHdpdGggbmFtZSA9ICclcycsIHR5cGUgPSAnJXMnIiwgVEFHLCBuYW1lLCB0eXBlKTsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICByZXR1cm4gbmV3IEFjY291bnQobmFtZSwgdHlwZSk7CisgIH0KKworICAvKiogU2VyaWFsaXplcyBhbiB7QGxpbmsgQWNjb3VudH0gaW50byBhIHN0cmluZy4gKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgc2VyaWFsaXplKEFjY291bnQgYWNjb3VudCkgeworICAgIHJldHVybiBhY2NvdW50LnR5cGUgKyBBQ0NPVU5UX0RFTElNSVRFUiArIGFjY291bnQubmFtZTsKKyAgfQorCisgIC8qKgorICAgKiBEZXNlcmlhbGl6ZXMgYSBzdHJpbmcgaW50byBhbiB7QGxpbmsgQWNjb3VudH0uCisgICAqCisgICAqIEByZXR1cm4gVGhlIGFjY291bnQgcGFyc2VkIGZyb20gc3RyaW5nLiBSZXR1cm5zIG51bGwgaWYgdGhlcmUgaXMgYW55IGVycm9yIGR1cmluZyBwYXJzZS4KKyAgICovCisgIEBOdWxsYWJsZQorICBwdWJsaWMgc3RhdGljIEFjY291bnQgZGVzZXJpYWxpemUoU3RyaW5nIGFjY291bnRTdHIpIHsKKyAgICBpbnQgc3BsaXRJbmRleCA9IGFjY291bnRTdHIuaW5kZXhPZihBQ0NPVU5UX0RFTElNSVRFUik7CisgICAgaWYgKHNwbGl0SW5kZXggPCAwKSB7CisgICAgICBMb2dVdGlsLmUoIiVzOiBVbmFibGUgdG8gcGFyc2UgQWNjb3VudCB3aXRoIHN0cmluZyA9ICclcyciLCBUQUcsIGFjY291bnRTdHIpOworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIFN0cmluZyB0eXBlID0gYWNjb3VudFN0ci5zdWJzdHJpbmcoMCwgc3BsaXRJbmRleCk7CisgICAgU3RyaW5nIG5hbWUgPSBhY2NvdW50U3RyLnN1YnN0cmluZyhzcGxpdEluZGV4ICsgMSk7CisgICAgcmV0dXJuIGNyZWF0ZShuYW1lLCB0eXBlKTsKKyAgfQorCisgIC8qKgorICAgKiBWYWxpZGF0ZXMgd2hldGhlciB0aGUgZmllbGQgaXMgdmFsaWQuIFJldHVybnMgZmFsc2UgaWYgdGhlIGZpZWxkIGlzIGVtcHR5IG9yIGNvbnRhaW5zIGRlbGltaXRlcgorICAgKiBvciBjb250YWlucyBzcGxpdCBjaGFyLgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiB2YWxpZGF0ZShTdHJpbmcgZmllbGQpIHsKKyAgICByZXR1cm4gZmllbGQgIT0gbnVsbAorICAgICAgICAmJiAhZmllbGQuaXNFbXB0eSgpCisgICAgICAgICYmICFmaWVsZC5jb250YWlucyhBQ0NPVU5UX0RFTElNSVRFUikKKyAgICAgICAgJiYgIWZpZWxkLmNvbnRhaW5zKE1kZENvbnN0YW50cy5TUExJVF9DSEFSKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hY2NvdW50L0JVSUxEIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hY2NvdW50L0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNkOWJkNjEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2FjY291bnQvQlVJTEQKQEAgLTAsMCArMSw0MCBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkFjY291bnRVdGlsIiwKKyAgICBzcmNzID0gWyJBY2NvdW50VXRpbC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpNZGRDb25zdGFudHMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiQWNjb3VudE1hbmFnZXJBY2NvdW50U291cmNlIiwKKyAgICBzcmNzID0gWyJBY2NvdW50TWFuYWdlckFjY291bnRTb3VyY2UuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6QWNjb3VudFNvdXJjZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjliYzNkMzIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zL0JVSUxECkBAIC0wLDAgKzEsMzAgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsKKyAgICAgICAgIi8vdmlzaWJpbGl0eTpwdWJsaWMiLAorICAgIF0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJhbm5vdGF0aW9ucyIsCisgICAgc3JjcyA9IGdsb2IoWyIqLmphdmEiXSksCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX2RhZ2dlciIsCisgICAgICAgICJAamF2YXhfaW5qZWN0IiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hbm5vdGF0aW9ucy9Gb3JlZ3JvdW5kU2VydmljZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hbm5vdGF0aW9ucy9Gb3JlZ3JvdW5kU2VydmljZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVmODE3ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zL0ZvcmVncm91bmRTZXJ2aWNlLmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuYW5ub3RhdGlvbnM7CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CitpbXBvcnQgamF2YXguaW5qZWN0LlF1YWxpZmllcjsKKworLyoqIEEgQ2xhc3MgcmVmZXJlbmNlIHRvIHRoZSBGb3JlZ3JvdW5kU2VydmljZSB0aGF0IHNob3VsZCBiZSB1c2VkIGZvciBNREQgRm9yZWdyb3VuZCBkb3dubG9hZHMuICovCitAVGFyZ2V0KHtFbGVtZW50VHlwZS5QQVJBTUVURVIsIEVsZW1lbnRUeXBlLk1FVEhPRCwgRWxlbWVudFR5cGUuRklFTER9KQorQFF1YWxpZmllcgorcHVibGljIEBpbnRlcmZhY2UgRm9yZWdyb3VuZFNlcnZpY2Uge30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMvSW5zdGFuY2VJZC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hbm5vdGF0aW9ucy9JbnN0YW5jZUlkLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjUzMzNlMwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMvSW5zdGFuY2VJZC5qYXZhCkBAIC0wLDAgKzEsMjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmFubm90YXRpb25zOworCitpbXBvcnQgamF2YXguaW5qZWN0LlF1YWxpZmllcjsKKworLyoqIFF1YWxpZmllciBmb3IgdGhlIEluc3RhbmNlSWQgKi8KK0BRdWFsaWZpZXIKK3B1YmxpYyBAaW50ZXJmYWNlIEluc3RhbmNlSWQge30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMvTWRkQ29udHJvbEV4ZWN1dG9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zL01kZENvbnRyb2xFeGVjdXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZmNjZhNDgKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zL01kZENvbnRyb2xFeGVjdXRvci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmFubm90YXRpb25zOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworaW1wb3J0IGphdmF4LmluamVjdC5RdWFsaWZpZXI7CisKKy8qKiBBbiBleGVjdXRvciBvbiB3aGljaCBNREQgcnVucyBjb250cm9sIGV4ZWN1dGlvbiBmbG93IHdoaWNoIHdpbGwgdG91Y2ggSS9PLiAqLworQFRhcmdldCh7RWxlbWVudFR5cGUuUEFSQU1FVEVSLCBFbGVtZW50VHlwZS5NRVRIT0QsIEVsZW1lbnRUeXBlLkZJRUxEfSkKK0BRdWFsaWZpZXIKK3B1YmxpYyBAaW50ZXJmYWNlIE1kZENvbnRyb2xFeGVjdXRvciB7fQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hbm5vdGF0aW9ucy9NZGREb3dubG9hZEV4ZWN1dG9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zL01kZERvd25sb2FkRXhlY3V0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMTY3NmJiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hbm5vdGF0aW9ucy9NZGREb3dubG9hZEV4ZWN1dG9yLmphdmEKQEAgLTAsMCArMSwyOSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuYW5ub3RhdGlvbnM7CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CitpbXBvcnQgamF2YXguaW5qZWN0LlF1YWxpZmllcjsKKworLyoqCisgKiBBbiBleGVjdXRvciBvbiB3aGljaCBNREQgcnVucyBkb3dubG9hZGluZyB0YXNrcyB3aGljaCB3aWxsIHRvdWNoIEkvTy4gVGhpcyBzaG91bGQgYmUgYm91bmQKKyAqIHRvIEBCbG9ja2luZ0V4ZWN1dG9yIG9yIGEgbmV3IHRocmVhZCBwb29sIGJlY2F1c2UgaXQgYmxvY2tzIGluc2lkZSA8aW50ZXJuYWw+LiBNb3JlIGRldGFpbCBpbgorICogPGludGVybmFsPgorICovCitAVGFyZ2V0KHtFbGVtZW50VHlwZS5QQVJBTUVURVIsIEVsZW1lbnRUeXBlLk1FVEhPRCwgRWxlbWVudFR5cGUuRklFTER9KQorQFF1YWxpZmllcgorcHVibGljIEBpbnRlcmZhY2UgTWRkRG93bmxvYWRFeGVjdXRvciB7fQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hbm5vdGF0aW9ucy9NZGRXb3JrZXJGYWN0b3J5LmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zL01kZFdvcmtlckZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZTdjMDA5Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hbm5vdGF0aW9ucy9NZGRXb3JrZXJGYWN0b3J5LmphdmEKQEAgLTAsMCArMSwyNSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuYW5ub3RhdGlvbnM7CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CitpbXBvcnQgamF2YXguaW5qZWN0LlF1YWxpZmllcjsKKworLyoqIEFubm90YXRpb24gZm9yIGN1c3RvbSBNZGRXb3JrZXJGYWN0b3J5IHRoYXQgY2FuIGNyZWF0ZSBNZGQgV29ya2VyLiAqLworQFRhcmdldCh7RWxlbWVudFR5cGUuUEFSQU1FVEVSLCBFbGVtZW50VHlwZS5NRVRIT0QsIEVsZW1lbnRUeXBlLkZJRUxEfSkKK0BRdWFsaWZpZXIKK3B1YmxpYyBAaW50ZXJmYWNlIE1kZFdvcmtlckZhY3Rvcnkge30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMvTWRpTG9jYXRpb25NYW5hZ2VyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zL01kaUxvY2F0aW9uTWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0MmRjM2QKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zL01kaUxvY2F0aW9uTWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmFubm90YXRpb25zOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworaW1wb3J0IGphdmF4LmluamVjdC5RdWFsaWZpZXI7CisKKy8qKiBMb2NhdGlvbk1hbmFnZXIgcHJvdmlkZWQgdG8gTWRpIGxpYnJhcnkgKi8KK0BUYXJnZXQoe0VsZW1lbnRUeXBlLlBBUkFNRVRFUiwgRWxlbWVudFR5cGUuTUVUSE9ELCBFbGVtZW50VHlwZS5GSUVMRH0pCitAUXVhbGlmaWVyCitwdWJsaWMgQGludGVyZmFjZSBNZGlMb2NhdGlvbk1hbmFnZXIge30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMvU29ja2V0VHJhZmZpY1RhZy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hbm5vdGF0aW9ucy9Tb2NrZXRUcmFmZmljVGFnLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTA1ZmVjMAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMvU29ja2V0VHJhZmZpY1RhZy5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmFubm90YXRpb25zOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworaW1wb3J0IGphdmF4LmluamVjdC5RdWFsaWZpZXI7CisKKy8qKiBVc2VkIHRvIHRhZyB0cmFmZmljIHRocm91Z2ggYSBTb2NrZXQuICovCitAVGFyZ2V0KHtFbGVtZW50VHlwZS5QQVJBTUVURVIsIEVsZW1lbnRUeXBlLk1FVEhPRCwgRWxlbWVudFR5cGUuRklFTER9KQorQFF1YWxpZmllcgorcHVibGljIEBpbnRlcmZhY2UgU29ja2V0VHJhZmZpY1RhZyB7fQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kZWx0YS9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZGVsdGEvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTA1NTZlMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZGVsdGEvQlVJTEQKQEAgLTAsMCArMSwyOSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkRlbHRhRGVjb2RlciIsCisgICAgc3JjcyA9IFsiRGVsdGFEZWNvZGVyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZGVsdGEvRGVsdGFEZWNvZGVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2RlbHRhL0RlbHRhRGVjb2Rlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIyNDc5ZTMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2RlbHRhL0RlbHRhRGVjb2Rlci5qYXZhCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRlbHRhOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGVsdGFGaWxlLkRpZmZEZWNvZGVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogRGVsdGEgZGVjb2RlciBJbnRlcmZhY2UuCisgKgorICogPHA+QSBkZWx0YSBkZWNvZGVyIGlzIHRvIGdlbmVyYXRlIGZ1bGwgY29udGVudCB3aXRoIGEgbXVjaCBzbWFsbGVyIGRlbHRhIGNvbnRlbnQgcHJvdmlkaW5nIGEgYmFzZQorICogY29udGVudC4KKyAqLworcHVibGljIGludGVyZmFjZSBEZWx0YURlY29kZXIgeworCisgIC8qKiBUaHJvd3Mgd2hlbiBkZWx0YSBkZWNvZGUgZmFpbHMuICovCisgIGNsYXNzIERlbHRhRGVjb2RlRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworICAgIHB1YmxpYyBEZWx0YURlY29kZUV4Y2VwdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgIHN1cGVyKGNhdXNlKTsKKyAgICB9CisKKyAgICBwdWJsaWMgRGVsdGFEZWNvZGVFeGNlcHRpb24oU3RyaW5nIG1zZykgeworICAgICAgc3VwZXIobXNnKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogRGVjb2RlIGZpbGUgZnJvbSBiYXNlIGZpbGUgYW5kIGRlbHRhIGZpbGUgYW5kIHdyaXRlcyB0byB0aGUgdGFyZ2V0IHVyaS4KKyAgICoKKyAgICogQHBhcmFtIGJhc2VVcmkgVGhlIGlucHV0IGJhc2UgZmlsZSBVUkkKKyAgICogQHBhcmFtIGRlbHRhVXJpIFRoZSBpbnB1dCBkZWx0YSBmaWxlIFVSSQorICAgKiBAcGFyYW0gdGFyZ2V0VXJpIFRoZSB0YXJnZXQgZGVjb2RlZCBvdXRwdXQgZmlsZSBVUkkKKyAgICogQHRocm93cyBEZWx0YURlY29kZUV4Y2VwdGlvbgorICAgKi8KKyAgdm9pZCBkZWNvZGUoVXJpIGJhc2VVcmksIFVyaSBkZWx0YVVyaSwgVXJpIHRhcmdldFVyaSkgdGhyb3dzIERlbHRhRGVjb2RlRXhjZXB0aW9uOworCisgIC8qKiBHZXQgdGhlIHN1cHBvcnRlZCBkZWx0YSBkZWNvZGVyIG5hbWUuICovCisgIERpZmZEZWNvZGVyIGdldERlY29kZXJOYW1lKCk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzgzMWMyZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9CVUlMRApAQCAtMCwwICsxLDUwIEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9saWJyYXJ5IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbCisgICAgICAgICIvL3Zpc2liaWxpdHk6cHVibGljIiwKKyAgICBdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiRmlsZURvd25sb2FkZXIiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJDaGVja0NvbnRlbnRDaGFuZ2VSZXF1ZXN0LmphdmEiLAorICAgICAgICAiQ2hlY2tDb250ZW50Q2hhbmdlUmVzcG9uc2UuamF2YSIsCisgICAgICAgICJEb3dubG9hZENvbnN0cmFpbnRzLmphdmEiLAorICAgICAgICAiRG93bmxvYWRSZXF1ZXN0LmphdmEiLAorICAgICAgICAiRmlsZURvd25sb2FkZXIuamF2YSIsCisgICAgICAgICJJbmxpbmVEb3dubG9hZFBhcmFtcy5qYXZhIiwKKyAgICAgICAgIk11bHRpU2NoZW1lRmlsZURvd25sb2FkZXIuamF2YSIsCisgICAgICAgICJPQXV0aFRva2VuUHJvdmlkZXIuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGaWxlU291cmNlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpNZGRDb25zdGFudHMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICJAYW5kcm9pZHhfYW5ub3RhdGlvbl9hbm5vdGF0aW9uIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2F1dG9fdmFsdWUiLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkNvbnN0YW50cyIsCisgICAgc3JjcyA9IFsiQ29uc3RhbnRzLmphdmEiXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9DaGVja0NvbnRlbnRDaGFuZ2VSZXF1ZXN0LmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvQ2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiYTYyMGEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvQ2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdC5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXI7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmF1dG8udmFsdWUuQXV0b1ZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CisKKy8qKiBSZXF1ZXN0IGZvciBjaGVja2luZyBjb250ZW50IGNoYW5nZS4gKi8KK0BBdXRvVmFsdWUKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDaGVja0NvbnRlbnRDaGFuZ2VSZXF1ZXN0IHsKKworICBDaGVja0NvbnRlbnRDaGFuZ2VSZXF1ZXN0KCkge30KKworICAvKiogVGhlIHRhcmdldCB1cmwuICovCisgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgdXJsKCk7CisKKyAgLyoqCisgICAqIFRoZSBvcHRpb25hbCBjYWNoZWQgRVRhZyBzdG9yZWQgb24gZGV2aWNlLCB3aGljaCB3YXMgcHJldmlvdXNseSBmZXRjaGVkIGZyb20gdGhlIHVybC4gV2hlbiB0aGUKKyAgICogdmFsdWUgaXMge0BsaWtlIE9wdGlvbmFsI2Fic2VudCgpfSwgaXQgbWVhbnMgZWl0aGVyIGl0IGlzIHRoZSBmaXJzdCBmZXRjaCwgb3IgdGhlIHVybCBkb2VzIG5vdAorICAgKiByZXNwb25kIHdpdGggRVRhZyBpbiB0aGUgbGFzdCBmZXRjaC4KKyAgICovCisgIHB1YmxpYyBhYnN0cmFjdCBPcHRpb25hbDxTdHJpbmc+IGNhY2hlZEVUYWdPcHRpb25hbCgpOworCisgIHB1YmxpYyBzdGF0aWMgQ2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdC5CdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ldyBBdXRvVmFsdWVfQ2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdC5CdWlsZGVyKCk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIENoZWNrQ29udGVudENoYW5nZVJlcXVlc3R9ICovCisgIEBBdXRvVmFsdWUuQnVpbGRlcgorICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEJ1aWxkZXIgeworCisgICAgQnVpbGRlcigpIHt9CisKKyAgICAvKiogU2V0cyB0aGUgdXJsLiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldFVybChTdHJpbmcgdXJsKTsKKworICAgIC8qKiBTZXRzIHRoZSBjYWNoZWQgRVRhZy4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRDYWNoZWRFVGFnT3B0aW9uYWwoT3B0aW9uYWw8U3RyaW5nPiBjYWNoZWRFVGFnT3B0aW9uYWwpOworCisgICAgcHVibGljIGFic3RyYWN0IENoZWNrQ29udGVudENoYW5nZVJlcXVlc3QgYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL0NoZWNrQ29udGVudENoYW5nZVJlc3BvbnNlLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvQ2hlY2tDb250ZW50Q2hhbmdlUmVzcG9uc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMzUwNmU4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL0NoZWNrQ29udGVudENoYW5nZVJlc3BvbnNlLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlcjsKKworaW1wb3J0IGNvbS5nb29nbGUuYXV0by52YWx1ZS5BdXRvVmFsdWU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKKworLyoqIFJlc3BvbnNlIGZvciBjaGVja2luZyBjb250ZW50IGNoYW5nZS4gKi8KK0BBdXRvVmFsdWUKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBDaGVja0NvbnRlbnRDaGFuZ2VSZXNwb25zZSB7CisKKyAgQ2hlY2tDb250ZW50Q2hhbmdlUmVzcG9uc2UoKSB7fQorCisgIC8qKiBXaGV0aGVyIG9yIG5vdCB0aGUgY29udGVudCBpcyBjaGFuZ2VkLiAqLworICBwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBjb250ZW50Q2hhbmdlZCgpOworCisgIC8qKgorICAgKiBUaGUgb3B0aW9uYWwgZnJlc2ggRVRhZyB0aGF0IGlzIGJlaW5nIGZldGNoZWQgZnJvbSB0aGUgdXJsLiBXaGVuIHRoZSB2YWx1ZSBldXF1YWxzIHtAbGluaworICAgKiBPcHRpb25hbCNhYnNlbnQoKX0sIGl0IG1lYW5zIHRoYXQgdGhlIHRhcmdldCB1cmwgZG9lcyBub3Qgc3VwcG9ydCBFVGFnLgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPFN0cmluZz4gZnJlc2hFVGFnT3B0aW9uYWwoKTsKKworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEF1dG9WYWx1ZV9DaGVja0NvbnRlbnRDaGFuZ2VSZXNwb25zZS5CdWlsZGVyKCk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIENoZWNrQ29udGVudENoYW5nZVJlc3BvbnNlfS4gKi8KKyAgQEF1dG9WYWx1ZS5CdWlsZGVyCisgIHB1YmxpYyBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgQnVpbGRlciB7CisKKyAgICBCdWlsZGVyKCkge30KKworICAgIC8qKiBTZXRzIHdoZXRoZXIgdGhlIGNvbnRlbnQgaXMgY2hhbmdlZCwgd2hpY2ggaXMgcmVxdWlyZWQuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0Q29udGVudENoYW5nZWQoYm9vbGVhbiBjb250ZW50Q2hhbmdlZCk7CisKKyAgICAvKiogU2V0cyB0aGUgZnJlc2ggRVRhZy4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRGcmVzaEVUYWdPcHRpb25hbChPcHRpb25hbDxTdHJpbmc+IGZyZXNoRVRhZ09wdGlvbmFsKTsKKworICAgIHB1YmxpYyBhYnN0cmFjdCBDaGVja0NvbnRlbnRDaGFuZ2VSZXNwb25zZSBidWlsZCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvQ29uc3RhbnRzLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvQ29uc3RhbnRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGFjZjJhNgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9Db25zdGFudHMuamF2YQpAQCAtMCwwICsxLDM4IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyOworCisvKiogTmV0d29yayByZWxhdGVkIGNvbnN0YW50cy4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDb25zdGFudHMgeworCisgIHByaXZhdGUgQ29uc3RhbnRzKCkge30KKworICAvKiogVGhlIEhUVFAge0Bjb2RlIEhFQUR9IHJlcXVlc3QgbWV0aG9kIG5hbWUuICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEhFQURfUkVRVUVTVF9NRVRIT0QgPSAiSEVBRCI7CisKKyAgLyoqIFRoZSBIVFRQIHtAY29kZSBFVGFnfSBoZWFkZXIgZmllbGQgbmFtZS4gVGhpcyBpcyB1c2VkIHRvIGRldGVjdCBjb250ZW50IGNoYW5nZS4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVRBR19IRUFERVIgPSAiRVRhZyI7CisKKyAgLyoqCisgICAqIFRoZSBIVFRQIHtAY29kZSBJZi1Ob25lLU1hdGNofSBoZWFkZXIgZmllbGQgbmFtZS4gVGhpcyBpcyB1c2VkIHRvIHNlbmQgRVRhZyB0byBzZXJ2ZXIgdG8gZGV0ZWN0CisgICAqIGNvbnRlbnQgY2hhbmdlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUZfTk9ORV9NQVRDSF9IRUFERVIgPSAiSWYtTm9uZS1NYXRjaCI7CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9SRVNQT05TRV9PSyA9IDIwMDsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSFRUUF9SRVNQT05TRV9OT1RfTU9ESUZJRUQgPSAzMDQ7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEhUVFBfUkVTUE9OU0VfTk9UX0ZPVU5EID0gNDA0OworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL0Rvd25sb2FkQ29uc3RyYWludHMuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9Eb3dubG9hZENvbnN0cmFpbnRzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY0ODljOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9Eb3dubG9hZENvbnN0cmFpbnRzLmphdmEKQEAgLTAsMCArMSwxMTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXI7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmF1dG8udmFsdWUuQXV0b1ZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlU2V0OworaW1wb3J0IGphdmEudXRpbC5FbnVtU2V0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CisKKy8qKiBQb3NzaWJsZSBjb25zdHJhaW50cyB0aGF0IGEgZG93bmxvYWQgcmVxdWVzdCByZXF1aXJlcy4gKi8KK0BBdXRvVmFsdWUKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBEb3dubG9hZENvbnN0cmFpbnRzIHsKKworICBEb3dubG9hZENvbnN0cmFpbnRzKCkge30KKworICAvKioKKyAgICogU3BlY2lhbCB2YWx1ZSBvZiB7QGNvZGUgRG93bmxvYWRDb25zdHJhaW50c30uIElmIHRoaXMgdmFsdWUgaXMgc3BlY2lmaWVkLCBubyBjb25zdHJhaW50IGNoZWNrcworICAgKiBhcmUgcGVyZm9ybWVkLCBldmVuIGlmIG5vIG5ldHdvcmsgaXMgcHJlc2VudCBhdCBhbGwhCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIERvd25sb2FkQ29uc3RyYWludHMgTk9ORSA9CisgICAgICBEb3dubG9hZENvbnN0cmFpbnRzLmJ1aWxkZXIoKQorICAgICAgICAgIC5zZXRSZXF1aXJlZE5ldHdvcmtUeXBlcyhFbnVtU2V0Lm5vbmVPZihOZXR3b3JrVHlwZS5jbGFzcykpCisgICAgICAgICAgLnNldFJlcXVpcmVVbm1ldGVyZWROZXR3b3JrKGZhbHNlKQorICAgICAgICAgIC5idWlsZCgpOworCisgIC8qKgorICAgKiBDb21tb24gdmFsdWUgdG8gaW5kaWNhdGUgdGhhdCB0aGUgYWN0aXZlIG5ldHdvcmsgbXVzdCBiZSB1bm1ldGVyZWQuIFRoaXMgdmFsdWUgcGVybWl0cyBhbnkKKyAgICogbmV0d29yayB0eXBlIGFzIGxvbmcgYXMgaXQgZG9lc24ndCBpbmRpY2F0ZSBpdCBpcyBtZXRlcmVkIGluIHNvbWUgd2F5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb3dubG9hZENvbnN0cmFpbnRzIE5FVFdPUktfVU5NRVRFUkVEID0KKyAgICAgIERvd25sb2FkQ29uc3RyYWludHMuYnVpbGRlcigpCisgICAgICAgICAgLnNldFJlcXVpcmVkTmV0d29ya1R5cGVzKEVudW1TZXQub2YoTmV0d29ya1R5cGUuQU5ZKSkKKyAgICAgICAgICAuc2V0UmVxdWlyZVVubWV0ZXJlZE5ldHdvcmsodHJ1ZSkKKyAgICAgICAgICAuYnVpbGQoKTsKKworICAvKioKKyAgICogQ29tbW9uIHZhbHVlIHRvIGluZGljYXRlIHRoYXQgdGhlIHJlcXVpcmVkIG5ldHdvcmsgbXVzdCBzaW1wbHkgYmUgY29ubmVjdGVkIGluIHNvbWUgd2F5LCBhbmQKKyAgICogb3RoZXJ3aXNlIGRvZXNuJ3QgaGF2ZSBhbnkgcmVzdHJpY3Rpb25zLiBBbnkgbmV0d29yayB0eXBlIGlzIGFsbG93ZWQuCisgICAqCisgICAqIDxwPlRoaXMgaXMgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIGRvd25sb2FkIHJlcXVlc3RzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBEb3dubG9hZENvbnN0cmFpbnRzIE5FVFdPUktfQ09OTkVDVEVEID0KKyAgICAgIERvd25sb2FkQ29uc3RyYWludHMuYnVpbGRlcigpCisgICAgICAgICAgLnNldFJlcXVpcmVkTmV0d29ya1R5cGVzKEVudW1TZXQub2YoTmV0d29ya1R5cGUuQU5ZKSkKKyAgICAgICAgICAuc2V0UmVxdWlyZVVubWV0ZXJlZE5ldHdvcmsoZmFsc2UpCisgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgLyoqCisgICAqIFRoZSB0eXBlIG9mIG5ldHdvcmsgdGhhdCBpcyByZXF1aXJlZC4gVGhpcyBpcyBhIHN1YnNldCBvZiB0aGUgbmV0d29yayB0eXBlcyBlbnVtZXJhdGVkIGJ5CisgICAqIHtAbGluayBhbmRyb2lkLm5ldC5Db25uZWN0aXZpdHlNYW5hZ2VyfS4KKyAgICovCisgIHB1YmxpYyBlbnVtIE5ldHdvcmtUeXBlIHsKKyAgICAvKiogU3BlY2lhbCBuZXR3b3JrIHR5cGUgdG8gYWxsb3cgYW55IHR5cGUgb2YgbmV0d29yaywgZXZlbiBpZiBpdCBub3Qgb25lIG9mIHRoZSBrbm93biB0eXBlcy4gKi8KKyAgICBBTlksCisgICAgLyoqIEVxdWl2YWxlbnQgdG8ge0BsaW5rIGFuZHJvaWQubmV0Lk5ldHdvcmtDYXBhYmlsaXRpZXMjVFJBTlNQT1JUX0JMVUVUT09USH0gKi8KKyAgICBCTFVFVE9PVEgsCisgICAgLyoqIEVxdWl2YWxlbnQgdG8ge0BsaW5rIGFuZHJvaWQubmV0Lk5ldHdvcmtDYXBhYmlsaXRpZXMjVFJBTlNQT1JUX0VUSEVSTkVUfSAqLworICAgIEVUSEVSTkVULAorICAgIC8qKiBFcXVpdmFsZW50IHRvIHtAbGluayBhbmRyb2lkLm5ldC5OZXR3b3JrQ2FwYWJpbGl0aWVzI1RSQU5TUE9SVF9DRUxMVUxBUn0gKi8KKyAgICBDRUxMVUxBUiwKKyAgICAvKiogRXF1aXZhbGVudCB0byB7QGxpbmsgYW5kcm9pZC5uZXQuTmV0d29ya0NhcGFiaWxpdGllcyNUUkFOU1BPUlRfV0lGSX0gKi8KKyAgICBXSUZJLAorICB9CisKKyAgLyoqCisgICAqIFdoZXRoZXIgdGhlIGNvbm5lY3Rpb24gbXVzdCBiZSB1bm1ldGVyZWQgdG8gcGFzcyBjb25uZWN0aXZpdHkgY2hlY2tzLiBTZWUge0BsaW5rCisgICAqIGFuZHJvaWR4LmNvcmUubmV0LkNvbm5lY3Rpdml0eU1hbmFnZXJDb21wYXQjaXNBY3RpdmVOZXR3b3JrTWV0ZXJlZH0gZm9yIG1vcmUgZGV0YWlscyBvbiB0aGlzCisgICAqIHZhcmlhYmxlLgorICAgKgorICAgKiA8cD5GYWxzZSBieSBkZWZhdWx0LgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IGJvb2xlYW4gcmVxdWlyZVVubWV0ZXJlZE5ldHdvcmsoKTsKKworICAvKioKKyAgICogVGhlIHR5cGVzIG9mIG5ldHdvcmtzIHRoYXQgYXJlIGFsbG93ZWQgZm9yIHRoZSByZXF1ZXN0IHRvIHBhc3MgY29ubmVjdGl2aXR5IGNoZWNrcy4gVGhlCisgICAqIGN1cnJlbnRseSBhY3RpdmUgbmV0d29yayB0eXBlIG11c3QgYmUgb25lIG9mIHRoZSB2YWx1ZXMgaW4gdGhpcyBzZXQuIFRoaXMgc2V0IG1heSBub3QgYmUgZW1wdHkuCisgICAqLworICBwdWJsaWMgYWJzdHJhY3QgSW1tdXRhYmxlU2V0PE5ldHdvcmtUeXBlPiByZXF1aXJlZE5ldHdvcmtUeXBlcygpOworCisgIC8qKiBDcmVhdGVzIGEge0Bjb2RlIERvd25sb2FkQ29uc3RyYWludHMuQnVpbGRlcn0gaW5zdGFuY2UuICovCisgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBidWlsZGVyKCkgeworICAgIHJldHVybiBuZXcgQXV0b1ZhbHVlX0Rvd25sb2FkQ29uc3RyYWludHMuQnVpbGRlcigpLnNldFJlcXVpcmVVbm1ldGVyZWROZXR3b3JrKGZhbHNlKTsKKyAgfQorCisgIC8qKiBDb252ZXJ0cyB0aGlzIGluc3RhbmNlIHRvIGEgYnVpbGRlciBmb3IgbW9kaWZpY2F0aW9ucy4gKi8KKyAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgdG9CdWlsZGVyKCk7CisKKyAgLyoqIEJ1aWxkZXIgZm9yIGNyZWF0aW5nIGluc3RhbmNlcyBvZiB7QGxpbmsgRG93bmxvYWRDb25zdHJhaW50c30uICovCisgIEBBdXRvVmFsdWUuQnVpbGRlcgorICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEJ1aWxkZXIgeworICAgIEJ1aWxkZXIoKSB7fQorCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0UmVxdWlyZWROZXR3b3JrVHlwZXMoU2V0PE5ldHdvcmtUeXBlPiBuZXR3b3JrVHlwZXMpOworCisgICAgYWJzdHJhY3QgSW1tdXRhYmxlU2V0LkJ1aWxkZXI8TmV0d29ya1R5cGU+IHJlcXVpcmVkTmV0d29ya1R5cGVzQnVpbGRlcigpOworCisgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgYWRkUmVxdWlyZWROZXR3b3JrVHlwZShOZXR3b3JrVHlwZSBuZXR3b3JrVHlwZSkgeworICAgICAgcmVxdWlyZWROZXR3b3JrVHlwZXNCdWlsZGVyKCkuYWRkKG5ldHdvcmtUeXBlKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldFJlcXVpcmVVbm1ldGVyZWROZXR3b3JrKGJvb2xlYW4gcmVxdWlyZVVubWV0ZXJlZE5ldHdvcmspOworCisgICAgcHVibGljIGFic3RyYWN0IERvd25sb2FkQ29uc3RyYWludHMgYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL0Rvd25sb2FkUmVxdWVzdC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL0Rvd25sb2FkUmVxdWVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU5MzhlZmQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvRG93bmxvYWRSZXF1ZXN0LmphdmEKQEAgLTAsMCArMSwxNDIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXI7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWRkQ29uc3RhbnRzLklOTElORV9GSUxFX1VSTF9TQ0hFTUU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLmJhc2UuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50OworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGNvbS5nb29nbGUuYXV0by52YWx1ZS5BdXRvVmFsdWU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5jb25jdXJyZW50LkltbXV0YWJsZTsKKworLyoqIFJlcXVlc3QgdG8gZG93bmxvYWQgYSBmaWxlLiAqLworQEltbXV0YWJsZQorQEF1dG9WYWx1ZQorcHVibGljIGFic3RyYWN0IGNsYXNzIERvd25sb2FkUmVxdWVzdCB7CisKKyAgLy8gRGVmYXVsdCB2YWx1ZSBmb3IgVHJhZmZpYyBUYWcgaWYgbm90IHNldCBieSBjbGllbnRzLgorICAvLyBNREQgd2lsbCBub3QgdGFnIHRoZSB0cmFmZmljIGlmIHRoZSBUcmFmZmljVGFnIGlzIG5vdCBzZXQgdG8gYSB2YWxpZCB2YWx1ZSAoPjApLgorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVU5TUEVDSUZJRURfVFJBRkZJQ19UQUcgPSAtMTsKKworICBEb3dubG9hZFJlcXVlc3QoKSB7fQorCisgIC8qKiBUaGUgRmlsZSBVcmkgdG8gZG93bmxvYWQgdGhlIGZpbGUgYXQuICovCisgIHB1YmxpYyBhYnN0cmFjdCBVcmkgZmlsZVVyaSgpOworCisgIC8qKiBUaGUgdXJsIHRvIGRvd25sb2FkIHRoZSBmaWxlIGZyb20uICovCisgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgdXJsVG9Eb3dubG9hZCgpOworCisgIC8qKgorICAgKiBDb25kaXRpb25zIHVuZGVyIHdoaWNoIHRoaXMgZmlsZSBzaG91bGQgYmUgZG93bmxvYWRlZC4KKyAgICoKKyAgICogPHA+VGhlc2UgY29uZGl0aW9ucyByZWxhdGUgdG8gdGhlIHR5cGUgb2YgbmV0d29yayB0aGF0IHNob3VsZCBiZSB1c2VkIHdoZW4gZG93bmxvYWRpbmcgYW5kIG11c3QKKyAgICogYmUgcHJvdmlkZWQgd2hlbiBwZXJmb3JtaW5nIGEgbmV0d29yayBkb3dubG9hZC4KKyAgICoKKyAgICogPHA+V2hlbiBwZXJmb3JtaW5nIGluLW1lbW9yeSBkb3dubG9hZHMgKHVzaW5nIHRoZSAiaW5saW5lZmlsZSIgdXJsIHNjaGVtZSksIHRoaXMgd2lsbCBub3QgYmUKKyAgICogdXNlZC4KKyAgICovCisgIHB1YmxpYyBhYnN0cmFjdCBEb3dubG9hZENvbnN0cmFpbnRzIGRvd25sb2FkQ29uc3RyYWludHMoKTsKKworICAvKioKKyAgICogVHJhZmZpYyB0YWcgdXNlZCBmb3IgdGhpcyByZXF1ZXN0LgorICAgKgorICAgKiA8cD5JZiBub3Qgc2V0LCBpdCB3aWxsIHRha2UgdGhlIGRlZmF1bHQgdmFsdWUgb2YgVU5TUEVDSUZJRURfVFJBRkZJQ19UQUcgYW5kIE1ERCB3aWxsIG5vdCB0YWcKKyAgICogdGhlIHRyYWZmaWMuCisgICAqLworICBwdWJsaWMgYWJzdHJhY3QgaW50IHRyYWZmaWNUYWcoKTsKKworICAvKiogVGhlIGV4dHJhIEhUVFAgaGVhZGVycyBmb3IgdGhpcyByZXF1ZXN0LiAqLworICBwdWJsaWMgYWJzdHJhY3QgSW1tdXRhYmxlTGlzdDxQYWlyPFN0cmluZywgU3RyaW5nPj4gZXh0cmFIdHRwSGVhZGVycygpOworCisgIC8qKgorICAgKiBQYXJhbWV0ZXJzIGZvciBpbmxpbmUgZmlsZSBkb3dubG9hZHMuCisgICAqCisgICAqIDxwPkFuIGluc3RhbmNlIG9mIHtAbGluayBJbmxpbmVEb3dubG9hZFBhcmFtc30gbXVzdCBiZSBpbmNsdWRlZCBpbiB0aGUgcmVxdWVzdCB0byBzdXBwb3J0CisgICAqIGluLW1lbW9yeSBkb3dubG9hZHMgKHNlZSA8aW50ZXJuYWw+IGZvciBtb3JlIGluZm8gb24gdGhlICJpbmxpbmVmaWxlIiB1cmwgc2NoZW1lKS4KKyAgICoKKyAgICogPHA+SW1wbGVtZW50YXRpb25zIG9mIHtAbGluayBGaWxlRG93bmxvYWRlcn0gdGhhdCBzdXBwb3J0IGRvd25sb2FkaW5nIGZyb20gYW4gaW5saW5lIGZpbGUKKyAgICogc2hvdWxkIGVuc3VyZSB0aGF0IDEpIHRoZSAiaW5saW5lZmlsZSIgdXJsIHNjaGVtZSBpcyB1c2VkIGFuZCAyKSBhbiB7QGxpbmsKKyAgICogSW5saW5lRG93bmxvYWRQYXJhbXN9IGlzIHByb3ZpZGVkLgorICAgKi8KKyAgcHVibGljIGFic3RyYWN0IE9wdGlvbmFsPElubGluZURvd25sb2FkUGFyYW1zPiBpbmxpbmVEb3dubG9hZFBhcmFtc09wdGlvbmFsKCk7CisKKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ldyBBdXRvVmFsdWVfRG93bmxvYWRSZXF1ZXN0LkJ1aWxkZXIoKQorICAgICAgICAuc2V0VHJhZmZpY1RhZyhVTlNQRUNJRklFRF9UUkFGRklDX1RBRykKKyAgICAgICAgLnNldEV4dHJhSHR0cEhlYWRlcnMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgfQorCisgIC8qKiBCdWlsZGVyIGZvciB7QGxpbmsgRG93bmxvYWRSZXF1ZXN0fS4gKi8KKyAgQEF1dG9WYWx1ZS5CdWlsZGVyCisgIHB1YmxpYyBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgQnVpbGRlciB7CisgICAgQnVpbGRlcigpIHt9CisKKyAgICAvKiogU2V0cyB0aGUgb24tZGV2aWNlIGRlc3RpbmF0aW9uIHVyaSBvZiB0aGUgZmlsZS4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRGaWxlVXJpKFVyaSBmaWxlVXJpKTsKKworICAgIC8qKiBTZXRzIHRoZSB1cmwgZnJvbSB3aGVyZSBmaWxlIGNvbnRlbnQgc2hvdWxkIGJlIGRvd25sb2FkZWQuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0VXJsVG9Eb3dubG9hZChTdHJpbmcgdXJsVG9Eb3dubG9hZCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBuZXR3b3JrIGNvbnN0cmFpbnRzIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHRoZSBkb3dubG9hZC4KKyAgICAgKgorICAgICAqIDxwPk9ubHkgcmVxdWlyZWQgd2hlbiBwZXJmb3JtaW5nIG5ldHdvcmsgZG93bmxvYWRzLiBJZiBwZXJmb3JtaW5nIGFuIGluLW1lbW9yeSBkb3dubG9hZCwgdGhpcworICAgICAqIGlzIG5vdCByZXF1aXJlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMgZG93bmxvYWRDb25zdHJhaW50cyk7CisKKyAgICAvKiogU2V0cyB0aGUgdHJhZmZpYyB0YWcgZm9yIHRoaXMgcmVxdWVzdC4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRUcmFmZmljVGFnKGludCB0cmFmZmljVGFnKTsKKworICAgIC8qKiBTZXRzIHRoZSBleHRyYSBIVFRQIGhlYWRlcnMgZm9yIHRoaXMgcmVxdWVzdC4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRFeHRyYUh0dHBIZWFkZXJzKAorICAgICAgICBJbW11dGFibGVMaXN0PFBhaXI8U3RyaW5nLCBTdHJpbmc+PiBleHRyYUh0dHBIZWFkZXJzKTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHBhcmFtZXRlcnMgZm9yIGFuIGlubGluZSBmaWxlIGRvd25sb2FkLgorICAgICAqCisgICAgICogPHA+T25seSByZXF1aXJlZCB3aGVuIHBlcmZvcm1pbmcgYW4gaW4tbWVtb3J5IGRvd25sb2FkICh1c2luZyBhbiAiaW5saW5lZmlsZSIgdXJsIHNjaGVtZSkuIElmCisgICAgICogcGVyZm9ybWluZyBhIG5ldHdvcmsgZG93bmxvYWQsIHRoaXMgaXMgbm90IHJlcXVpcmVkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldElubGluZURvd25sb2FkUGFyYW1zT3B0aW9uYWwoCisgICAgICAgIElubGluZURvd25sb2FkUGFyYW1zIGlubGluZURvd25sb2FkUGFyYW1zKTsKKworICAgIC8qKiBCdWlsZHMgYSB7QGxpbmsgRG93bmxvYWRSZXF1ZXN0fSBhbmQgY2hlY2tzIGZvciBjb3JyZWN0IGRhdGEuICovCisgICAgcHVibGljIGZpbmFsIERvd25sb2FkUmVxdWVzdCBidWlsZCgpIHsKKyAgICAgIC8vIEVuc3VyZSB0aGF0IGlubGluZWZpbGU6IHJlcXVlc3RzIGluY2x1ZGUgSW5saW5lRG93bmxvYWRQYXJhbXMKKyAgICAgIGlmICh1cmxUb0Rvd25sb2FkKCkuc3RhcnRzV2l0aChJTkxJTkVfRklMRV9VUkxfU0NIRU1FKSkgeworICAgICAgICBjaGVja0FyZ3VtZW50KAorICAgICAgICAgICAgaW5saW5lRG93bmxvYWRQYXJhbXNPcHRpb25hbCgpLmlzUHJlc2VudCgpLAorICAgICAgICAgICAgIklubGluZURvd25sb2FkUGFyYW1zIG11c3QgYmUgc2V0IHdoZW4gdXNpbmcgaW5saW5lZmlsZTogc2NoZW1lIik7CisKKyAgICAgICAgLy8gaW5saW5lIGZpbGUgcmVxdWVzdCBkb2Vzbid0IHJlcXVpcmUgZG93bmxvYWQgY29uc3RyYWludHMsIHNvIHNldCB0byBOT05FLgorICAgICAgICBzZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMuTk9ORSk7CisgICAgICB9CisKKyAgICAgIHJldHVybiBhdXRvQnVpbGQoKTsKKyAgICB9CisKKyAgICAvKiogVGVsbHMgQXV0b1ZhbHVlIHRvIGdlbmVyYXRlIGFuIGF1dG9tYXRlZCBidWlsZGVyIHVzZWQgaW4ge0BsaW5rICNidWlsZH0gKi8KKyAgICBhYnN0cmFjdCBEb3dubG9hZFJlcXVlc3QgYXV0b0J1aWxkKCk7CisKKyAgICBhYnN0cmFjdCBTdHJpbmcgdXJsVG9Eb3dubG9hZCgpOworCisgICAgYWJzdHJhY3QgT3B0aW9uYWw8SW5saW5lRG93bmxvYWRQYXJhbXM+IGlubGluZURvd25sb2FkUGFyYW1zT3B0aW9uYWwoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL0ZpbGVEb3dubG9hZGVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvRmlsZURvd25sb2FkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMDk2YWM1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL0ZpbGVEb3dubG9hZGVyLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlcjsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DaGVja1JldHVyblZhbHVlOworCisvKioKKyAqIFJlc3BvbnNpYmxlIGZvciBkb3dubG9hZGluZyBmaWxlcyBpbiBNREQuCisgKgorICogPHA+SW1wbGVtZW50IHRoaXMgaW50ZXJmYWNlIHRvIHJlcGxhY2UgdGhlIE1ERCBuZXR3b3JraW5nIHN0YWNrLgorICovCitwdWJsaWMgaW50ZXJmYWNlIEZpbGVEb3dubG9hZGVyIHsKKyAgLyoqCisgICAqIFN0YXJ0IGRvd25sb2FkaW5nIHRoZSBmaWxlLiBUaGUgZG93bmxvYWQgcmVzdWx0IGlzIHByb3ZpZGVkIGFzeW5jaHJvbm91c2x5IGFzIGEge0BsaW5rCisgICAqIExpc3RlbmFibGVGdXR1cmV9IHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgZG93bmxvYWQgaXMgY29tcGxldGUuCisgICAqCisgICAqIDxwPlRoZSBkb3dubG9hZCBjYW4gYmUgY2FuY2VsbGVkIGJ5IGNhbGxpbmcge0BsaW5rIExpc3RlbmFibGVGdXR1cmUjY2FuY2VsfSBvbiB0aGUgZnV0dXJlCisgICAqIGluc3RhbmNlIHJldHVybmVkIGJ5IHRoaXMgbWV0aG9kLiBDYW5jZWxsYXRpb24gaXMgYmVzdC1lZmZvcnQgYW5kIGRvZXMgbm90IGd1YXJhbnRlZSB0aGF0IHRoZQorICAgKiBkb3dubG9hZCB3aWxsIHN0b3AgaW1tZWRpYXRlbHksIGFzIGl0IGlzIGltcG9zc2libGUgdG8gc3RvcCBhIHRocmVhZCB0aGF0IGlzIGluIHRoZSBtaWRkbGUgb2YKKyAgICogcmVhZGluZyBieXRlcyBvZmYgdGhlIG5ldHdvcmsuCisgICAqCisgICAqIEBwYXJhbSBkb3dubG9hZFJlcXVlc3QgdGhlIGRvd25sb2FkIHJlcXVlc3QuCisgICAqIEByZXR1cm4gLSBBIExpc3RlbmFibGVGdXR1cmUgcmVwcmVzZW50aW5nIHRoZSBkb3dubG9hZCBzdGF0ZSBvZiB0aGUgZmlsZS4gVGhlIExpc3RlbmFibGVGdXR1cmUKKyAgICogICAgIGZhaWxzIHdpdGgge0BsaW5rIERvd25sb2FkRXhjZXB0aW9ufSBpZiBkb3dubG9hZGluZyBmYWlscy4KKyAgICovCisgIEBDaGVja1JldHVyblZhbHVlCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gc3RhcnREb3dubG9hZGluZyhEb3dubG9hZFJlcXVlc3QgZG93bmxvYWRSZXF1ZXN0KTsKKworICAvKioKKyAgICogQ2hlY2tzIGlmIHRoZSBjb250ZW50IG9mIHVybCBpcyBjaGFuZ2VkLiBUaGUgTGlzdGVuYWJsZUZ1dHVyZSB0aHJvd3Mge0BsaW5rIERvd25sb2FkRXhjZXB0aW9ufQorICAgKiB3aGVuIGl0IGZhaWxzLgorICAgKi8KKyAgQENoZWNrUmV0dXJuVmFsdWUKKyAgZGVmYXVsdCBMaXN0ZW5hYmxlRnV0dXJlPENoZWNrQ29udGVudENoYW5nZVJlc3BvbnNlPiBpc0NvbnRlbnRDaGFuZ2VkKAorICAgICAgQ2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdCBjaGVja0NvbnRlbnRDaGFuZ2VSZXF1ZXN0KSB7CisgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm90IGltcGxlbWVudGVkIikpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvSW5saW5lRG93bmxvYWRQYXJhbXMuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9JbmxpbmVEb3dubG9hZFBhcmFtcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2ZGIxY2YKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvSW5saW5lRG93bmxvYWRQYXJhbXMuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmlsZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmF1dG8udmFsdWUuQXV0b1ZhbHVlOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uY29uY3VycmVudC5JbW11dGFibGU7CisKKy8qKiBQYXJhbWV0ZXJzIGZvciBkb3dubG9hZGluZyBpbmxpbmUgKGluLW1lbW9yeSBhbmQgVVJJKSBmaWxlcy4gKi8KK0BJbW11dGFibGUKK0BBdXRvVmFsdWUKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBJbmxpbmVEb3dubG9hZFBhcmFtcyB7CisgIElubGluZURvd25sb2FkUGFyYW1zKCkge30KKworICAvKiogVGhlIGRhdGEgdGhhdCBzaG91bGQgYmUgY29waWVkIHRvIE1ERCBpbnRlcm5hbCBzdG9yYWdlLiAqLworICBwdWJsaWMgYWJzdHJhY3QgRmlsZVNvdXJjZSBpbmxpbmVGaWxlQ29udGVudCgpOworCisgIC8qKiBDcmVhdGVzIGEgQnVpbGRlciBmb3Ige0BsaW5rIElubGluZURvd25sb2FkUGFyYW1zfSAqLworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEF1dG9WYWx1ZV9JbmxpbmVEb3dubG9hZFBhcmFtcy5CdWlsZGVyKCk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIElubGluZURvd25sb2FkUGFyYW1zfSAqLworICBAQXV0b1ZhbHVlLkJ1aWxkZXIKKyAgcHVibGljIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBCdWlsZGVyIHsKKyAgICBCdWlsZGVyKCkge30KKworICAgIC8qKiBTZXRzIHRoZSBpbi1tZW1vcnkgZGF0YSB0aGF0IHNob3VsZCBiZSBjb3BpZWQgdG8gTUREIGludGVybmFsIHN0b3JhZ2UuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0SW5saW5lRmlsZUNvbnRlbnQoRmlsZVNvdXJjZSBpbmxpbmVGaWxlQ29udGVudCk7CisKKyAgICAvKiogQnVpbGRzIGEge0BsaW5rIElubGluZURvd25sb2FkUGFyYW1zfS4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgSW5saW5lRG93bmxvYWRQYXJhbXMgYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL011bHRpU2NoZW1lRmlsZURvd25sb2FkZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9NdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzBiODJhMwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9NdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyLmphdmEKQEAgLTAsMCArMSwxMzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXI7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZHguYW5ub3RhdGlvbi5WaXNpYmxlRm9yVGVzdGluZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbi5Eb3dubG9hZFJlc3VsdENvZGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuUHJlY29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZU1hcDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmVycm9ycHJvbmUuYW5ub3RhdGlvbnMuQ2hlY2tSZXR1cm5WYWx1ZTsKK2ltcG9ydCBqYXZhLm5ldC5NYWxmb3JtZWRVUkxFeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLk1hcDsKKworLyoqCisgKiBBIGNvbXBvc2l0ZSB7QGxpbmsgRmlsZURvd25sb2FkZXJ9IHRoYXQgZGVsZWdhdGVzIHRvIHNwZWNpZmljIHJlZ2lzdGVyZWQgRmlsZURvd25sb2FkZXJzIGJhc2VkIG9uCisgKiBVUkwgc2NoZW1lLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlciBpbXBsZW1lbnRzIEZpbGVEb3dubG9hZGVyIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJNdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyIjsKKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIE11bHRpU2NoZW1lRmlsZURvd25sb2FkZXJ9LiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgeworICAgIHByaXZhdGUgZmluYWwgTWFwPFN0cmluZywgRmlsZURvd25sb2FkZXI+IHNjaGVtZVRvRG93bmxvYWRlciA9IG5ldyBIYXNoTWFwPD4oKTsKKworICAgIC8qKiBBc3NvY2lhdGVzIGEgdXJsIHNjaGVtZSAoZS5nLiAiaHR0cCIpIHdpdGggYSBzcGVjaWZpYyB7QGxpbmsgRmlsZURvd25sb2FkZXJ9IGRlbGVnYXRlLiAqLworICAgIHB1YmxpYyBNdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyLkJ1aWxkZXIgYWRkU2NoZW1lKFN0cmluZyBzY2hlbWUsIEZpbGVEb3dubG9hZGVyIGRvd25sb2FkZXIpIHsKKyAgICAgIHNjaGVtZVRvRG93bmxvYWRlci5wdXQoCisgICAgICAgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwoc2NoZW1lKSwgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwoZG93bmxvYWRlcikpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIE11bHRpU2NoZW1lRmlsZURvd25sb2FkZXIgYnVpbGQoKSB7CisgICAgICByZXR1cm4gbmV3IE11bHRpU2NoZW1lRmlsZURvd25sb2FkZXIodGhpcyk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBmaW5hbCBJbW11dGFibGVNYXA8U3RyaW5nLCBGaWxlRG93bmxvYWRlcj4gc2NoZW1lVG9Eb3dubG9hZGVyOworCisgIC8qKiBSZXR1cm5zIGEgQnVpbGRlciBmb3Ige0BsaW5rIE11bHRpU2NoZW1lRmlsZURvd25sb2FkZXJ9LiAqLworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgYnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEJ1aWxkZXIoKTsKKyAgfQorCisgIHByaXZhdGUgTXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlcihCdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICB0aGlzLnNjaGVtZVRvRG93bmxvYWRlciA9IEltbXV0YWJsZU1hcC5jb3B5T2YoYnVpbGRlci5zY2hlbWVUb0Rvd25sb2FkZXIpOworICB9CisKKyAgQE92ZXJyaWRlCisgIEBDaGVja1JldHVyblZhbHVlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHN0YXJ0RG93bmxvYWRpbmcoRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCkgeworICAgIEZpbGVEb3dubG9hZGVyIGRlbGVnYXRlOworICAgIHRyeSB7CisgICAgICBkZWxlZ2F0ZSA9IGdldERlbGVnYXRlKGRvd25sb2FkUmVxdWVzdC51cmxUb0Rvd25sb2FkKCkpOworICAgIH0gY2F0Y2ggKERvd25sb2FkRXhjZXB0aW9uIGUpIHsKKyAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZShlKTsKKyAgICB9CisgICAgcmV0dXJuIGRlbGVnYXRlLnN0YXJ0RG93bmxvYWRpbmcoZG93bmxvYWRSZXF1ZXN0KTsKKyAgfQorCisgIEBPdmVycmlkZQorICBAQ2hlY2tSZXR1cm5WYWx1ZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxDaGVja0NvbnRlbnRDaGFuZ2VSZXNwb25zZT4gaXNDb250ZW50Q2hhbmdlZCgKKyAgICAgIENoZWNrQ29udGVudENoYW5nZVJlcXVlc3QgY2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdCkgeworICAgIEZpbGVEb3dubG9hZGVyIGRlbGVnYXRlOworICAgIHRyeSB7CisgICAgICBkZWxlZ2F0ZSA9IGdldERlbGVnYXRlKGNoZWNrQ29udGVudENoYW5nZVJlcXVlc3QudXJsKCkpOworICAgIH0gY2F0Y2ggKERvd25sb2FkRXhjZXB0aW9uIGUpIHsKKyAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZShlKTsKKyAgICB9CisgICAgcmV0dXJuIGRlbGVnYXRlLmlzQ29udGVudENoYW5nZWQoY2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdCk7CisgIH0KKworICAvKiogRXh0cmFjdCB0aGUgc2NoZW1lIG9mIGEgdXJsIHN0cmluZy4gKi8KKyAgQFZpc2libGVGb3JUZXN0aW5nCisgIHN0YXRpYyBTdHJpbmcgZ2V0U2NoZW1lKFN0cmluZyB1cmwpIHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24geworICAgIFVyaSBwYXJzZWQgPSBVcmkucGFyc2UodXJsKTsKKyAgICBpZiAocGFyc2VkID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVUkxFeGNlcHRpb24oIkNvdWxkIG5vdCBwYXJzZSBVUkwuIik7CisgICAgfQorICAgIFN0cmluZyBzY2hlbWUgPSBwYXJzZWQuZ2V0U2NoZW1lKCk7CisgICAgaWYgKHNjaGVtZSA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVVJMRXhjZXB0aW9uKCJVUkwgY29udGFpbmVkIG5vIHNjaGVtZS4iKTsKKyAgICB9CisgICAgcmV0dXJuIHNjaGVtZTsKKyAgfQorCisgIC8qKgorICAgKiBMb29rdXAgdGhlIGRlbGVnYXRlIEZpbGVEb3dubG9hZGVyIHRoYXQgY2FuIGhhbmRsZSBhIHVybCwgYmFzZWQgb24gdGhlIHVybCdzIHNjaGVtZS4KKyAgICoKKyAgICogQHRocm93cyBEb3dubG9hZEV4Y2VwdGlvbiBJZiBhbiBhcHByb3ByaWF0ZSBkZWxlZ2F0ZSBGaWxlRG93bmxvYWRlciBjb3VsZCBub3QgYmUgZm91bmQuCisgICAqLworICBGaWxlRG93bmxvYWRlciBnZXREZWxlZ2F0ZShTdHJpbmcgdXJsKSB0aHJvd3MgRG93bmxvYWRFeGNlcHRpb24geworICAgIFN0cmluZyBzY2hlbWU7CisgICAgdHJ5IHsKKyAgICAgIHNjaGVtZSA9IGdldFNjaGVtZSh1cmwpOworICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiBlKSB7CisgICAgICBMb2dVdGlsLmUoIiVzOiBUaGUgZG93bmxvYWQgdXJsIGlzIG1hbGZvcm1lZCwgdXJsID0gJXMiLCBUQUcsIHVybCk7CisgICAgICB0aHJvdyBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5NQUxGT1JNRURfRE9XTkxPQURfVVJMKQorICAgICAgICAgIC5zZXRDYXVzZShlKQorICAgICAgICAgIC5idWlsZCgpOworICAgIH0KKworICAgIEZpbGVEb3dubG9hZGVyIGRvd25sb2FkZXIgPSBzY2hlbWVUb0Rvd25sb2FkZXIuZ2V0KHNjaGVtZSk7CisgICAgaWYgKGRvd25sb2FkZXIgPT0gbnVsbCkgeworICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICIlczogTm8gcmVnaXN0ZXJlZCBkb3dubG9hZGVyIHN1cHBvcnRzIHRoZSBkb3dubG9hZCB1cmwgc2NoZW1lLCBzY2hlbWUgPSAlcyIsCisgICAgICAgICAgVEFHLCBzY2hlbWUpOworICAgICAgdGhyb3cgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuVU5TVVBQT1JURURfRE9XTkxPQURfVVJMX1NDSEVNRSkKKyAgICAgICAgICAuYnVpbGQoKTsKKyAgICB9CisgICAgcmV0dXJuIGRvd25sb2FkZXI7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9PQXV0aFRva2VuUHJvdmlkZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9PQXV0aFRva2VuUHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Y2VhMzhiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL09BdXRoVG9rZW5Qcm92aWRlci5qYXZhCkBAIC0wLDAgKzEsMjkgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXI7CisKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworCisvKioKKyAqIFByb3ZpZGVyIGludGVyZmFjZSBmb3Igc3VwcGx5aW5nIE9BdXRoIHRva2VucyBmb3IgYSByZXF1ZXN0LiBUaGUgdG9rZW5zIGdlbmVyYXRlZCBieSB0aGlzIG1ldGhvZAorICogYXJlIGFkZGVkIHRvIHJlcXVlc3RzIGFzIGh0dHAgaGVhZGVycy4gRm9yIG1vcmUgZGV0YWlscywgc2VlIHRoZSBvZmZpY2lhbCBzcGVjIGZvciB0aGlzCisgKiBhdXRob3JpemF0aW9uIG1lY2hhbmlzbTogaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzY3NTAjcGFnZS01CisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgT0F1dGhUb2tlblByb3ZpZGVyIHsKKyAgLyoqIFByb3ZpZGVzIGFuIE9BdXRoIGJlYXJlciB0b2tlbiBmb3IgdGhlIGdpdmVuIFVSTC4gKi8KKyAgQE51bGxhYmxlCisgIFN0cmluZyBwcm92aWRlT0F1dGhUb2tlbihTdHJpbmcgdXJsKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9pbmxpbmUvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvaW5saW5lL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEwOWRkNjUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvaW5saW5lL0JVSUxECkBAIC0wLDAgKzEsMzcgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsKKyAgICAgICAgIi8vdmlzaWJpbGl0eTpwdWJsaWMiLAorICAgIF0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJJbmxpbmVGaWxlRG93bmxvYWRlciIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIklubGluZUZpbGVEb3dubG9hZGVyLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpEb3dubG9hZEV4Y2VwdGlvbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlcjpGaWxlRG93bmxvYWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnN0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TWRkQ29uc3RhbnRzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ1V0aWwiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvaW5saW5lL0lubGluZUZpbGVEb3dubG9hZGVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvaW5saW5lL0lubGluZUZpbGVEb3dubG9hZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGYzZDQ3MgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9pbmxpbmUvSW5saW5lRmlsZURvd25sb2FkZXIuamF2YQpAQCAtMCwwICsxLDExMCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5pbmxpbmU7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWRkQ29uc3RhbnRzLklOTElORV9GSUxFX1VSTF9TQ0hFTUU7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbi5Eb3dubG9hZFJlc3VsdENvZGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLklubGluZURvd25sb2FkUGFyYW1zOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuUmVhZFN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuV3JpdGVTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmlvLkJ5dGVTdHJlYW1zOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKKworLyoqCisgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgRmlsZURvd25sb2FkZXJ9IHRoYXQgc3VwcG9ydHMgY29weWluZyBpbi1tZW1vcnkgZGF0YSB0byBkaXNrLgorICoKKyAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gb25seSBzdXBwb3J0cyBjb3B5aW5nIGZvciAiaW5saW5lZmlsZToiIHVybCBzY2hlbWVzLiBGb3IgbW9yZSBkZXRhaWxzIHNlZQorICogPGludGVybmFsPi4KKyAqCisgKiA8cD5OT1RFOiBjb3B5aW5nIGluLW1lbW9yeSBkYXRhIGNhbiBiZSB0aG91Z2h0IG9mIGFzICJpbmxpbmUgZmlsZSBkb3dubG9hZGluZywiIGhlbmNlIHRoZSBuYW1pbmcKKyAqIG9mIHRoaXMgY2xhc3MuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJbmxpbmVGaWxlRG93bmxvYWRlciBpbXBsZW1lbnRzIEZpbGVEb3dubG9hZGVyIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJJbmxpbmVGaWxlRG93bmxvYWRlciI7CisKKyAgcHJpdmF0ZSBmaW5hbCBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIGZpbmFsIEV4ZWN1dG9yIGRvd25sb2FkRXhlY3V0b3I7CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCBJbmxpbmVGaWxlRG93bmxvYWRlciBpbnN0YW5jZS4KKyAgICoKKyAgICogQHBhcmFtIGZpbGVTdG9yYWdlIGEgZmlsZSBzdG9yYWdlIGluc3RhbmNlIHVzZWQgdG8gcGVyZm9ybSBJL08KKyAgICogQHBhcmFtIGRvd25sb2FkRXhlY3V0b3IgZXhlY3V0b3IgdGhhdCB3aWxsIHBlcmZyb20gdGhlIGRvd25sb2FkLiBUaGlzIHNob3VsZCBiZQorICAgKiAgICAgdGhlIEBNZGREb3dubG9hZEV4ZWN1dG9yCisgICAqLworICBwdWJsaWMgSW5saW5lRmlsZURvd25sb2FkZXIoU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZSwgRXhlY3V0b3IgZG93bmxvYWRFeGVjdXRvcikgeworICAgIHRoaXMuZmlsZVN0b3JhZ2UgPSBmaWxlU3RvcmFnZTsKKyAgICB0aGlzLmRvd25sb2FkRXhlY3V0b3IgPSBkb3dubG9hZEV4ZWN1dG9yOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHN0YXJ0RG93bmxvYWRpbmcoRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCkgeworICAgIGlmICghZG93bmxvYWRSZXF1ZXN0LnVybFRvRG93bmxvYWQoKS5zdGFydHNXaXRoKElOTElORV9GSUxFX1VSTF9TQ0hFTUUpKSB7CisgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgIiVzOiBJbnZhbGlkIHVybCBnaXZlbiwgZXhwZWN0ZWQgdG8gc3RhcnQgd2l0aCAnaW5saW5lZmlsZTonLCBidXQgd2FzICVzIiwKKyAgICAgICAgICBUQUcsIGRvd25sb2FkUmVxdWVzdC51cmxUb0Rvd25sb2FkKCkpOworICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5JTlZBTElEX0lOTElORV9GSUxFX1VSTF9TQ0hFTUUpCisgICAgICAgICAgICAgIC5zZXRNZXNzYWdlKCJJbmxpbmVGaWxlRG93bmxvYWRlciBvbmx5IHN1cHBvcnRzIGNvcHlpbmcgaW5saW5lZmlsZTogc2NoZW1lIikKKyAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgIH0KKyAgICAvLyBEb3dubG9hZFJlcXVlc3QgcmVxdWlyZXMgSW5saW5lRG93bmxvYWRQYXJhbXMgdG8gYmUgcHJlc2VudCB3aGVuIGJ1aWxkaW5nIGEgcmVxdWVzdCB3aXRoCisgICAgLy8gaW5saW5lZmlsZSBzY2hlbWUsIHNvIHdlIGNhbiBhY2Nlc3MgaXQgZGlyZWN0bHkgaGVyZS4KKyAgICBJbmxpbmVEb3dubG9hZFBhcmFtcyBpbmxpbmVEb3dubG9hZFBhcmFtcyA9CisgICAgICAgIGRvd25sb2FkUmVxdWVzdC5pbmxpbmVEb3dubG9hZFBhcmFtc09wdGlvbmFsKCkuZ2V0KCk7CisKKyAgICByZXR1cm4gRnV0dXJlcy5zdWJtaXRBc3luYygKKyAgICAgICAgKCkgLT4geworICAgICAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaW5saW5lRmlsZVN0cmVhbSA9IGdldElucHV0U3RyZWFtKGlubGluZURvd25sb2FkUGFyYW1zKTsKKyAgICAgICAgICAgICAgT3V0cHV0U3RyZWFtIGRlc3RpbmF0aW9uU3RyZWFtID0KKyAgICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLm9wZW4oZG93bmxvYWRSZXF1ZXN0LmZpbGVVcmkoKSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICAgICAgICBCeXRlU3RyZWFtcy5jb3B5KGlubGluZUZpbGVTdHJlYW0sIGRlc3RpbmF0aW9uU3RyZWFtKTsKKyAgICAgICAgICAgIGRlc3RpbmF0aW9uU3RyZWFtLmZsdXNoKCk7CisgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgTG9nVXRpbC5lKGUsICIlczogVW5hYmxlIHRvIGNvcHkgZmlsZSBjb250ZW50LiIsIFRBRyk7CisgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRDYXVzZShlKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5JTkxJTkVfRklMRV9JT19FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgIH0sCisgICAgICAgIGRvd25sb2FkRXhlY3V0b3IpOworICB9CisKKyAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShJbmxpbmVEb3dubG9hZFBhcmFtcyBwYXJhbXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3dpdGNoIChwYXJhbXMuaW5saW5lRmlsZUNvbnRlbnQoKS5nZXRLaW5kKCkpIHsKKyAgICAgIGNhc2UgVVJJOgorICAgICAgICByZXR1cm4gZmlsZVN0b3JhZ2Uub3BlbihwYXJhbXMuaW5saW5lRmlsZUNvbnRlbnQoKS51cmkoKSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSk7CisgICAgICBjYXNlIEJZVEVTVFJJTkc6CisgICAgICAgIHJldHVybiBwYXJhbXMuaW5saW5lRmlsZUNvbnRlbnQoKS5ieXRlU3RyaW5nKCkubmV3SW5wdXQoKTsKKyAgICB9CisgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigidW5yZWFjaGFibGUiKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40Nzc0MTI3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvQlVJTEQKQEAgLTAsMCArMSw2OSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk9mZnJvYWQyRmlsZURvd25sb2FkZXIiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJPZmZyb2FkMkZpbGVEb3dubG9hZGVyLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpFeGNlcHRpb25IYW5kbGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpEb3dubG9hZEV4Y2VwdGlvbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlcjpGaWxlRG93bmxvYWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvaW50ZWdyYXRpb24vZG93bmxvYWRlcjpkb3dubG9hZGVyMiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nOmNvbmN1cnJlbnQiLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGRvd25sb2FkZXIiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkV4Y2VwdGlvbkhhbmRsZXIiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJFeGNlcHRpb25IYW5kbGVyLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpEb3dubG9hZEV4Y2VwdGlvbiIsCisgICAgICAgICJAZG93bmxvYWRlciIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiVHJhZmZpY1N0YXRzU29ja2V0RmFjdG9yeSIsCisgICAgc3JjcyA9IFsiVHJhZmZpY1N0YXRzU29ja2V0RmFjdG9yeS5qYXZhIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIlRocm90dGxpbmdFeGVjdXRvciIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlRocm90dGxpbmdFeGVjdXRvci5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvRXhjZXB0aW9uSGFuZGxlci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvRXhjZXB0aW9uSGFuZGxlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc1OWM4MDUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9FeGNlcHRpb25IYW5kbGVyLmphdmEKQEAgLTAsMCArMSwxNTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZDsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLlJlcXVlc3RFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb24uRG93bmxvYWRSZXN1bHRDb2RlOworCisvKioKKyAqIEhhbmRsZXMgbWFwcGluZyBleGNlcHRpb25zIGZyb20gRG93bmxvYWRlcjIgaW50byB0aGUgZXF1aXZhbGVudCBNREQge0BsaW5rIERvd25sb2FkRXhjZXB0aW9ufS4KKyAqCisgKiA8cD5Db21tb24gZXhjZXB0aW9ucyBhcmUgcGFyc2VkIGFuZCBoYW5kbGVkIGJ5IGRlZmF1bHQsIGJ1dCB0aGUgdW5kZXJseWluZyBuZXR3b3JrIHN0YWNrIG1heQorICogaW5jbHVkZSBzcGVjaWFsIEV4Y2VwdGlvbnMgYW5kL29yIGVycm9yIGNvZGVzIHRoYXQgbmVlZCB0byBiZSBwYXJzZWQuIElmIHRoaXMgaXMgdGhlIGNhc2UsIGEKKyAqIHtAbGluayBOZXR3b3JrU3RhY2tFeGNlcHRpb25IYW5kbGVyfSBjYW4gYmUgcHJvdmlkZWQgdG8gcGVyZm9ybSB0aGlzIHBhcnNpbmcuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBFeGNlcHRpb25IYW5kbGVyIHsKKyAgLyoqCisgICAqIFRoZSBtYXhpbXVtIGFtb3VudCBvZiBhdHRlbXB0cyB3ZSByZWN1cnNlIGJlZm9yZSBzdG9wcGluZyBpbiB7QGxpbmsKKyAgICogI21hcEV4Y2VwdGlvblRvRG93bmxvYWRSZXN1bHRDb2RlfS4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBFWENFUFRJT05fVE9fQ09ERV9SRUNVUlNJT05fTElNSVQgPSA1OworCisgIC8qKiBUaGUgaGFuZGxlciBvZiB1bmRlcmx5aW5nIG5ldHdvcmsgc3RhY2sgZmFpbHVyZXMuICovCisgIHByaXZhdGUgZmluYWwgTmV0d29ya1N0YWNrRXhjZXB0aW9uSGFuZGxlciBpbnRlcm5hbEV4Y2VwdGlvbkhhbmRsZXI7CisKKyAgcHJpdmF0ZSBFeGNlcHRpb25IYW5kbGVyKE5ldHdvcmtTdGFja0V4Y2VwdGlvbkhhbmRsZXIgaW50ZXJuYWxFeGNlcHRpb25IYW5kbGVyKSB7CisgICAgdGhpcy5pbnRlcm5hbEV4Y2VwdGlvbkhhbmRsZXIgPSBpbnRlcm5hbEV4Y2VwdGlvbkhhbmRsZXI7CisgIH0KKworICAvKiogQ29udmVuaWVuY2UgbWV0aG9kIHRvIHJldHVybiBhIG5ldyBFeGNlcHRpb25IYW5kbGVyIHdpdGggZGVmYXVsdCBoYW5kbGluZy4gKi8KKyAgcHVibGljIHN0YXRpYyBFeGNlcHRpb25IYW5kbGVyIHdpdGhEZWZhdWx0SGFuZGxpbmcoKSB7CisgICAgcmV0dXJuIG5ldyBFeGNlcHRpb25IYW5kbGVyKG5ldyBOZXR3b3JrU3RhY2tFeGNlcHRpb25IYW5kbGVyKCkge30pOworICB9CisKKyAgLyoqIFJldHVybiBhIG5ldyBpbnN0YW5jZSB3aXRoIHNwZWNpZmljIGhhbmRsaW5nIGZvciBhIG5ldHdvcmsgc3RhY2suICovCisgIHB1YmxpYyBzdGF0aWMgRXhjZXB0aW9uSGFuZGxlciB3aXRoTmV0d29ya1N0YWNrSGFuZGxpbmcoCisgICAgICBOZXR3b3JrU3RhY2tFeGNlcHRpb25IYW5kbGVyIGludGVybmFsRXhjZXB0aW9uSGFuZGxlcikgeworICAgIHJldHVybiBuZXcgRXhjZXB0aW9uSGFuZGxlcihpbnRlcm5hbEV4Y2VwdGlvbkhhbmRsZXIpOworICB9CisKKyAgLyoqCisgICAqIE1hcCBnaXZlbiBmYWlsdXJlIHRvIGEge0BsaW5rIERvd25sb2FkRXhjZXB0aW9ufS4KKyAgICoKKyAgICogPHA+Rm9yIG1vc3QgY2FzZXMsIHRoaXMgbWV0aG9kIGRvZXMgbm90IG5lZWQgdG8gYmUgb3ZlcnJpZGRlbi4KKyAgICoKKyAgICogPHA+PGVtPk5PVEU6PC9lbT4gSWYgdGhlIGdpdmVuIHRocm93YWJsZSBpcyBhbHJlYWR5IGEge0BsaW5rIERvd25sb2FkRXhjZXB0aW9ufSwgaXQgaXMgcmV0dXJuZWQKKyAgICogaW1tZWRpYXRlbHkuIEluIHRoaXMgY2FzZSwgdGhlIGdpdmVuIG1lc3NhZ2Ugd2lsbCA8Yj5ub3Q8L2I+IGJlIHVzZWQgKHRoZSBtZXNzYWdlIGZyb20gdGhlCisgICAqIGdpdmVuIHRocm93YWJsZSB3aWxsIGJlIHVzZWQgaW5zdGVhZCkuCisgICAqCisgICAqIEBwYXJhbSBtZXNzYWdlIHRvcC1sZXZlbCBtZXNzYWdlIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHRoZSByZXR1cm5lZCB7QGxpbmsgRG93bmxvYWRFeGNlcHRpb259CisgICAqIEBwYXJhbSB0aHJvd2FibGUgZ2VuZXJpYyB0aHJvd2FibGUgdGhhdCBzaG91bGQgYmUgbWFwcGVkIHRvIHtAbGluayBEb3dubG9hZEV4Y2VwdGlvbn0KKyAgICogQHJldHVybiB7QGxpbmsgRG93bmxvYWRFeGNlcHRpb259IHRoYXQgd3JhcHMgYXJvdW5kIGdpdmVuIHRocm93YWJsZSB3aXRoIGFwcHJvcHJpYXRlIHtAbGluaworICAgKiAgICAgRG93bmxvYWRSZXN1bHRDb2RlfQorICAgKi8KKyAgcHVibGljIERvd25sb2FkRXhjZXB0aW9uIG1hcFRvRG93bmxvYWRFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSB0aHJvd2FibGUpIHsKKyAgICBpZiAodGhyb3dhYmxlIGluc3RhbmNlb2YgRG93bmxvYWRFeGNlcHRpb24pIHsKKyAgICAgIC8vIEV4Y2VwdGlvbiBpcyBhbHJlYWR5IGFuIE1ERCBEb3dubG9hZEV4Y2VwdGlvbiAtLSByZXR1cm4gaXQuCisgICAgICByZXR1cm4gKERvd25sb2FkRXhjZXB0aW9uKSB0aHJvd2FibGU7CisgICAgfQorCisgICAgRG93bmxvYWRSZXN1bHRDb2RlIGNvZGUgPSBtYXBFeGNlcHRpb25Ub0Rvd25sb2FkUmVzdWx0Q29kZSh0aHJvd2FibGUsIC8qIGl0ZXJhdGlvbiA9ICovIDApOworCisgICAgcmV0dXJuIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAuc2V0TWVzc2FnZShtZXNzYWdlKQorICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKGNvZGUpCisgICAgICAgIC5zZXRDYXVzZSh0aHJvd2FibGUpCisgICAgICAgIC5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIE1hcCBleGNlcHRpb24gdG8ge0BsaW5rIERvd25sb2FkUmVzdWx0Q29kZX0uCisgICAqCisgICAqIEBwYXJhbSB0aHJvd2FibGUgdGhlIGV4Y2VwdGlvbiB0byBtYXAgdG8gYSB7QGxpbmsgRG93bmxvYWRSZXN1bHRDb2RlfQorICAgKi8KKyAgcHJpdmF0ZSBEb3dubG9hZFJlc3VsdENvZGUgbWFwRXhjZXB0aW9uVG9Eb3dubG9hZFJlc3VsdENvZGUoVGhyb3dhYmxlIHRocm93YWJsZSwgaW50IGl0ZXJhdGlvbikgeworICAgIC8vIENoZWNrIHJlY3Vyc2lvbiBsaW1pdCBhbmQgcmV0dXJuIHVua25vd24gZXJyb3IgaWYgaXQgaXMgaGl0LgorICAgIGlmIChpdGVyYXRpb24gPj0gRVhDRVBUSU9OX1RPX0NPREVfUkVDVVJTSU9OX0xJTUlUKSB7CisgICAgICByZXR1cm4gRG93bmxvYWRSZXN1bHRDb2RlLlVOS05PV05fRVJST1I7CisgICAgfQorCisgICAgRG93bmxvYWRSZXN1bHRDb2RlIG5ldHdvcmtTdGFja01hcHBlclJlc3VsdCA9CisgICAgICAgIGludGVybmFsRXhjZXB0aW9uSGFuZGxlci5tYXBGcm9tTmV0d29ya1N0YWNrRXhjZXB0aW9uKHRocm93YWJsZSk7CisgICAgaWYgKCFuZXR3b3JrU3RhY2tNYXBwZXJSZXN1bHQuZXF1YWxzKERvd25sb2FkUmVzdWx0Q29kZS5VTktOT1dOX0VSUk9SKSkgeworICAgICAgLy8gbmV0d29yayBzdGFjayBtYXBwZXIgcmV0dXJuZWQga25vd24gcmVzdWx0IGNvZGUgLS0gcmV0dXJuIGl0IGluc3RlYWQgb2YgcGVyZm9ybWluZyBjb21tb24KKyAgICAgIC8vIG1hcHBpbmcuCisgICAgICByZXR1cm4gbmV0d29ya1N0YWNrTWFwcGVyUmVzdWx0OworICAgIH0KKworICAgIGlmICh0aHJvd2FibGUgaW5zdGFuY2VvZiBEb3dubG9hZEV4Y2VwdGlvbikgeworICAgICAgLy8gZXhjZXB0aW9uIGluIHRoZSBjaGFpbiBpcyBhbHJlYWR5IGFuIE1ERCBEb3dubG9hZEV4Y2VwdGlvbiAtLSB1c2UgaXRzIGNvZGUKKyAgICAgIHJldHVybiAoKERvd25sb2FkRXhjZXB0aW9uKSB0aHJvd2FibGUpLmdldERvd25sb2FkUmVzdWx0Q29kZSgpOworICAgIH0KKworICAgIGlmICh0aHJvd2FibGUgaW5zdGFuY2VvZiBSZXF1ZXN0RXhjZXB0aW9uKSB7CisgICAgICAvLyBDaGVjayBlcnJvciBkZXRhaWxzIGZvciBodHRwIHN0YXR1cyBjb2RlIGVycm9yLgorICAgICAgaWYgKCgoUmVxdWVzdEV4Y2VwdGlvbikgdGhyb3dhYmxlKS5nZXRFcnJvckRldGFpbHMoKS5nZXRIdHRwU3RhdHVzQ29kZSgpICE9IC0xKSB7CisgICAgICAgIC8vIGVycm9yIGNvZGUgaGFzIGFuIGFzc29jaWF0ZWQgaHR0cCBzdGF0dXMgY29kZSwgbWFyayBpdCBhcyBIVFRQX0VSUk9SCisgICAgICAgIHJldHVybiBEb3dubG9hZFJlc3VsdENvZGUuQU5EUk9JRF9ET1dOTE9BREVSX0hUVFBfRVJST1I7CisgICAgICB9CisgICAgfQorCisgICAgaWYgKHRocm93YWJsZS5nZXRDYXVzZSgpICE9IG51bGwpIHsKKyAgICAgIC8vIEV4Y2VwdGlvbiBoYXMgYW4gdW5kZXJseWluZyBjYXVzZSAtLSBhdHRlbXB0IG1hcHBpbmcgb24gdGhhdCBjYXVzZS4KKyAgICAgIHJldHVybiBtYXBFeGNlcHRpb25Ub0Rvd25sb2FkUmVzdWx0Q29kZSh0aHJvd2FibGUuZ2V0Q2F1c2UoKSwgaXRlcmF0aW9uICsgMSk7CisgICAgfQorCisgICAgaWYgKHRocm93YWJsZSBpbnN0YW5jZW9mIGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkRXhjZXB0aW9uKSB7CisgICAgICAvLyBJZiBEb3dubG9hZEV4Y2VwdGlvbiBpcyBub3Qgd3JhcHBpbmcgYW55dGhpbmcsIHdlIGNhbid0IGRldGVybWluZSB0aGUgZXJyb3IgZnVydGhlciAtLSBtYXJrCisgICAgICAvLyBpdCBhcyBhIGdlbmVyYWwgRG93bmxvYWRlcjIgZXJyb3IuCisgICAgICByZXR1cm4gRG93bmxvYWRSZXN1bHRDb2RlLkFORFJPSURfRE9XTkxPQURFUjJfRVJST1I7CisgICAgfQorCisgICAgLy8gV2UgY291bGRuJ3QgcGFyc2UgYW55IGNvbW1vbiBlcnJvcnMsIHJldHVybiBhbiB1bmtub3duIGVycm9yCisgICAgcmV0dXJuIERvd25sb2FkUmVzdWx0Q29kZS5VTktOT1dOX0VSUk9SOworICB9CisKKyAgLyoqCisgICAqIEludGVyZmFjZSB0byBoYW5kbGUgcGFyc2luZyBleGNlcHRpb25zIGZyb20gYW4gdW5kZXJseWluZyBuZXR3b3JrIHN0YWNrLgorICAgKgorICAgKiA8cD5JZiBhbiB1bmRlcmx5aW5nIG5ldHdvcmsgc3RhY2sgaXMgdXNlZCB3aGljaCBjYW4gdGhyb3cgc3BlY2lhbCBleGNlcHRpb25zIG9yIGhhcyBhbiBlcnJvcgorICAgKiBjb2RlIG1hcCwgY29uc2lkZXIgaW1wbGVtZW50aW5nIHRoaXMgdG8gcHJvdmlkZSBiZXR0ZXIgaGFuZGxpbmcgb2YgZXhjZXB0aW9ucy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgaW50ZXJmYWNlIE5ldHdvcmtTdGFja0V4Y2VwdGlvbkhhbmRsZXIgeworICAgIC8qKgorICAgICAqIE1hcCBDdXN0b20gRXhjZXB0aW9uIHRvIHtAbGluayBEb3dubG9hZFJlc3VsdENvZGV9LgorICAgICAqCisgICAgICogPHA+VW5kZXJseWluZyBuZXR3b3JrIHN0YWNrcyBtYXkgaGF2ZSBzcGVjaWZpYyBleGNlcHRpb25zIHRoYXQgY2FuIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZQorICAgICAqIGJlc3QgRG93bmxvYWRSZXN1bHRDb2RlLiBUaGlzIG1ldGhvZCBzaG91bGQgYmUgb3ZlcnJpZGRlbiB0byBjaGVjayBmb3Igc3VjaCBleGNlcHRpb25zLgorICAgICAqCisgICAgICogPHA+SWYgYSBrbm93biB7QGxpbmsgRG93bmxvYWRSZXN1bHRDb2RlfSBpcyByZXR1cm5lZCAoaS5lIG5vdCBVTktOT1dOX0VSUk9SKSwgaXQgd2lsbCBiZQorICAgICAqIHVzZWQuCisgICAgICoKKyAgICAgKiA8cD5CeSBkZWZhdWx0LCBhbiBVTktOT1dOX0VSUk9SIGlzIHJldHVybmVkLgorICAgICAqLworICAgIGRlZmF1bHQgRG93bmxvYWRSZXN1bHRDb2RlIG1hcEZyb21OZXR3b3JrU3RhY2tFeGNlcHRpb24oVGhyb3dhYmxlIHRocm93YWJsZSkgeworICAgICAgcmV0dXJuIERvd25sb2FkUmVzdWx0Q29kZS5VTktOT1dOX0VSUk9SOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvT2Zmcm9hZDJGaWxlRG93bmxvYWRlci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvT2Zmcm9hZDJGaWxlRG93bmxvYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY4MjA0NWYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9PZmZyb2FkMkZpbGVEb3dubG9hZGVyLmphdmEKQEAgLTAsMCArMSwyMTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZDsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5Eb3dubG9hZENvbnN0cmFpbnRzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHMuTmV0d29ya1R5cGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmRvd25sb2FkZXIuRG93bmxvYWREZXN0aW5hdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmRvd25sb2FkZXIuRG93bmxvYWRSZXN1bHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmRvd25sb2FkZXIuRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5PQXV0aFRva2VuUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb24uRG93bmxvYWRSZXN1bHRDb2RlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuQ2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkNoZWNrQ29udGVudENoYW5nZVJlc3BvbnNlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLk1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmludGVncmF0aW9uLmRvd25sb2FkZXIuRG93bmxvYWREZXN0aW5hdGlvbk9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmludGVncmF0aW9uLmRvd25sb2FkZXIuRG93bmxvYWRNZXRhZGF0YVN0b3JlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlByb3BhZ2F0ZWRGbHVlbnRGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5Qcm9wYWdhdGVkRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuU3RyaW5nczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRmx1ZW50RnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJJOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKgorICogQW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIHtAbGluaworICogY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcn0gdXNpbmcgPGludGVybmFsPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgT2Zmcm9hZDJGaWxlRG93bmxvYWRlciBpbXBsZW1lbnRzIEZpbGVEb3dubG9hZGVyIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJPZmZyb2FkMkZpbGVEb3dubG9hZGVyIjsKKworICBwcml2YXRlIGZpbmFsIERvd25sb2FkZXIgZG93bmxvYWRlcjsKKyAgcHJpdmF0ZSBmaW5hbCBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIGZpbmFsIEV4ZWN1dG9yIGRvd25sb2FkRXhlY3V0b3I7CisgIHByaXZhdGUgZmluYWwgRG93bmxvYWRNZXRhZGF0YVN0b3JlIGRvd25sb2FkTWV0YWRhdGFTdG9yZTsKKyAgcHJpdmF0ZSBmaW5hbCBFeGNlcHRpb25IYW5kbGVyIGV4Y2VwdGlvbkhhbmRsZXI7CisgIHByaXZhdGUgZmluYWwgT3B0aW9uYWw8SW50ZWdlcj4gZGVmYXVsdFRyYWZmaWNUYWc7CisgIEBOdWxsYWJsZSBwcml2YXRlIGZpbmFsIE9BdXRoVG9rZW5Qcm92aWRlciBhdXRoVG9rZW5Qcm92aWRlcjsKKworICAvLyBUT0RPKGIvMjA4NzAzMDQyKTogcmVmYWN0b3IgaW5qZWN0aW9uIHRvIHJlbW92ZSBkZXBlbmRlbmN5IG9uIFByb3RvRGF0YVN0b3JlCisgIHB1YmxpYyBPZmZyb2FkMkZpbGVEb3dubG9hZGVyKAorICAgICAgRG93bmxvYWRlciBkb3dubG9hZGVyLAorICAgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZSwKKyAgICAgIEV4ZWN1dG9yIGRvd25sb2FkRXhlY3V0b3IsCisgICAgICBATnVsbGFibGUgT0F1dGhUb2tlblByb3ZpZGVyIGF1dGhUb2tlblByb3ZpZGVyLAorICAgICAgRG93bmxvYWRNZXRhZGF0YVN0b3JlIGRvd25sb2FkTWV0YWRhdGFTdG9yZSwKKyAgICAgIEV4Y2VwdGlvbkhhbmRsZXIgZXhjZXB0aW9uSGFuZGxlciwKKyAgICAgIE9wdGlvbmFsPEludGVnZXI+IGRlZmF1bHRUcmFmZmljVGFnKSB7CisgICAgdGhpcy5kb3dubG9hZGVyID0gZG93bmxvYWRlcjsKKyAgICB0aGlzLmZpbGVTdG9yYWdlID0gZmlsZVN0b3JhZ2U7CisgICAgdGhpcy5kb3dubG9hZEV4ZWN1dG9yID0gZG93bmxvYWRFeGVjdXRvcjsKKyAgICB0aGlzLmF1dGhUb2tlblByb3ZpZGVyID0gYXV0aFRva2VuUHJvdmlkZXI7CisgICAgdGhpcy5kb3dubG9hZE1ldGFkYXRhU3RvcmUgPSBkb3dubG9hZE1ldGFkYXRhU3RvcmU7CisgICAgdGhpcy5leGNlcHRpb25IYW5kbGVyID0gZXhjZXB0aW9uSGFuZGxlcjsKKyAgICB0aGlzLmRlZmF1bHRUcmFmZmljVGFnID0gZGVmYXVsdFRyYWZmaWNUYWc7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gc3RhcnREb3dubG9hZGluZygKKyAgICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0CisgICAgICAgICAgZmlsZURvd25sb2FkZXJSZXF1ZXN0KSB7CisgICAgU3RyaW5nIGZpbGVOYW1lID0gU3RyaW5ncy5udWxsVG9FbXB0eShmaWxlRG93bmxvYWRlclJlcXVlc3QuZmlsZVVyaSgpLmdldExhc3RQYXRoU2VnbWVudCgpKTsKKworICAgIERvd25sb2FkRGVzdGluYXRpb24gZG93bmxvYWREZXN0aW5hdGlvbjsKKyAgICB0cnkgeworICAgICAgZG93bmxvYWREZXN0aW5hdGlvbiA9IGJ1aWxkRG93bmxvYWREZXN0aW5hdGlvbihmaWxlRG93bmxvYWRlclJlcXVlc3QuZmlsZVVyaSgpKTsKKyAgICB9IGNhdGNoIChEb3dubG9hZEV4Y2VwdGlvbiBlKSB7CisgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoZSk7CisgICAgfQorCisgICAgRG93bmxvYWRSZXF1ZXN0IG9mZnJvYWQyRG93bmxvYWRSZXF1ZXN0ID0KKyAgICAgICAgYnVpbGREb3dubG9hZFJlcXVlc3QoZmlsZURvd25sb2FkZXJSZXF1ZXN0LCBkb3dubG9hZERlc3RpbmF0aW9uKTsKKworICAgIEZsdWVudEZ1dHVyZTxEb3dubG9hZFJlc3VsdD4gcmVzdWx0RnV0dXJlID0gZG93bmxvYWRlci5leGVjdXRlKG9mZnJvYWQyRG93bmxvYWRSZXF1ZXN0KTsKKworICAgIExvZ1V0aWwuZCgKKyAgICAgICAgIiVzOiBEYXRhIGRvd25sb2FkIHNjaGVkdWxlZCBmb3IgZmlsZTogJXMiLCBUQUcsIGZpbGVEb3dubG9hZGVyUmVxdWVzdC51cmxUb0Rvd25sb2FkKCkpOworCisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmUuZnJvbShyZXN1bHRGdXR1cmUpCisgICAgICAgIC5jYXRjaGluZ0FzeW5jKAorICAgICAgICAgICAgRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgY2F1c2UgLT4geworICAgICAgICAgICAgICBMb2dVdGlsLmQoCisgICAgICAgICAgICAgICAgICBjYXVzZSwKKyAgICAgICAgICAgICAgICAgICIlczogRmFpbGVkIHRvIGRvd25sb2FkIGZpbGUgJXMgZHVlIHRvOiAlcyIsCisgICAgICAgICAgICAgICAgICBUQUcsCisgICAgICAgICAgICAgICAgICBmaWxlTmFtZSwKKyAgICAgICAgICAgICAgICAgIFN0cmluZ3MubnVsbFRvRW1wdHkoY2F1c2UuZ2V0TWVzc2FnZSgpKSk7CisKKyAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24gZXhjZXB0aW9uID0KKyAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbkhhbmRsZXIubWFwVG9Eb3dubG9hZEV4Y2VwdGlvbigiZmFpbHVyZSBpbiBkb3dubG9hZCEiLCBjYXVzZSk7CisKKyAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGV4Y2VwdGlvbik7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgZG93bmxvYWRFeGVjdXRvcikKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgKERvd25sb2FkUmVzdWx0IHJlc3VsdCkgLT4geworICAgICAgICAgICAgICBMb2dVdGlsLmQoCisgICAgICAgICAgICAgICAgICAiJXM6IERvd25sb2FkZWQgZmlsZSAlcywgYnl0ZXMgd3JpdHRlbjogJWQiLAorICAgICAgICAgICAgICAgICAgVEFHLCBmaWxlTmFtZSwgcmVzdWx0LmJ5dGVzV3JpdHRlbigpKTsKKyAgICAgICAgICAgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLmNhdGNoaW5nQXN5bmMoCisgICAgICAgICAgICAgICAgICBkb3dubG9hZE1ldGFkYXRhU3RvcmUuZGVsZXRlKGZpbGVEb3dubG9hZGVyUmVxdWVzdC5maWxlVXJpKCkpLAorICAgICAgICAgICAgICAgICAgRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICAgICAgZSAtPiB7CisgICAgICAgICAgICAgICAgICAgIC8vIEZhaWxpbmcgdG8gY2xlYW4gdXAgbWV0YWRhdGEgc2hvdWxkbid0IGNhdXNlIGEgZmFpbHVyZSBpbiB0aGUgZnV0dXJlLCBsb2cgYW5kCisgICAgICAgICAgICAgICAgICAgIC8vIHJldHVybiB2b2lkLgorICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmQoZSwgIiVzOiBGYWlsZWQgdG8gY2xlYW51cCBtZXRhZGF0YSIsIFRBRyk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICBkb3dubG9hZEV4ZWN1dG9yKTsKKyAgICAgICAgICAgIH0sCisgICAgICAgICAgICBkb3dubG9hZEV4ZWN1dG9yKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxDaGVja0NvbnRlbnRDaGFuZ2VSZXNwb25zZT4gaXNDb250ZW50Q2hhbmdlZCgKKyAgICAgIENoZWNrQ29udGVudENoYW5nZVJlcXVlc3QgY2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdCkgeworICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgIkNoZWNraW5nIGZvciBjb250ZW50IGNoYW5nZXMgaXMgY3VycmVudGx5IHVuc3VwcG9ydGVkIGZvciBEb3dubG9hZGVyMiIpKTsKKyAgfQorCisgIHByaXZhdGUgRG93bmxvYWREZXN0aW5hdGlvbiBidWlsZERvd25sb2FkRGVzdGluYXRpb24oVXJpIGRlc3RpbmF0aW9uVXJpKQorICAgICAgdGhyb3dzIERvd25sb2FkRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgLy8gQ3JlYXRlIERvd25sb2FkRGVzdGluYXRpb24gdXNpbmcgbW9ic3RvcmUKKyAgICAgIHJldHVybiBmaWxlU3RvcmFnZS5vcGVuKAorICAgICAgICAgIGRlc3RpbmF0aW9uVXJpLCBEb3dubG9hZERlc3RpbmF0aW9uT3BlbmVyLmNyZWF0ZShkb3dubG9hZE1ldGFkYXRhU3RvcmUpKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBpZiAoZSBpbnN0YW5jZW9mIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbiB8fCBlLmdldENhdXNlKCkgaW5zdGFuY2VvZiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pIHsKKyAgICAgICAgTG9nVXRpbC5lKCIlczogVGhlIGZpbGUgdXJpIGlzIGludmFsaWQsIHVyaSA9ICVzIiwgVEFHLCBkZXN0aW5hdGlvblVyaSk7CisgICAgICAgIHRocm93IERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuTUFMRk9STUVEX0ZJTEVfVVJJX0VSUk9SKQorICAgICAgICAgICAgLnNldENhdXNlKGUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIExvZ1V0aWwuZShlLCAiJXM6IFVuYWJsZSB0byBjcmVhdGUgRG93bmxvYWREZXN0aW5hdGlvbiBmb3IgZmlsZSAlcyIsIFRBRywgZGVzdGluYXRpb25VcmkpOworICAgICAgICAvLyBUT0RPOiB0aGUgcmVzdWx0IGNvZGUgaXMgdGhlIG1vc3QgZXF1aXZhbGVudCB0byBkb3dubG9hZGVyMSAtLSBjb25zaWRlcgorICAgICAgICAvLyBjcmVhdGluZyBhIHNlcGFyYXRlIHJlc3VsdCBjb2RlIHRoYXQncyBtb3JlIGFwcHJvcHJpYXRlIGZvciBkb3dubG9hZGVyMi4KKyAgICAgICAgdGhyb3cgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKAorICAgICAgICAgICAgICAgIERvd25sb2FkUmVzdWx0Q29kZS5VTkFCTEVfVE9fQ1JFQVRFX01PQlNUT1JFX1JFU1BPTlNFX1dSSVRFUl9FUlJPUikKKyAgICAgICAgICAgIC5zZXRDYXVzZShlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBEb3dubG9hZFJlcXVlc3QgYnVpbGREb3dubG9hZFJlcXVlc3QoCisgICAgICBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdAorICAgICAgICAgIGZpbGVEb3dubG9hZGVyUmVxdWVzdCwKKyAgICAgIERvd25sb2FkRGVzdGluYXRpb24gZG93bmxvYWREZXN0aW5hdGlvbikgeworICAgIERvd25sb2FkUmVxdWVzdC5CdWlsZGVyIHJlcXVlc3RCdWlsZGVyID0KKyAgICAgICAgZG93bmxvYWRlci5uZXdSZXF1ZXN0QnVpbGRlcigKKyAgICAgICAgICAgIFVSSS5jcmVhdGUoZmlsZURvd25sb2FkZXJSZXF1ZXN0LnVybFRvRG93bmxvYWQoKSksIGRvd25sb2FkRGVzdGluYXRpb24pOworCisgICAgcmVxdWVzdEJ1aWxkZXIuc2V0T0F1dGhUb2tlblByb3ZpZGVyKGF1dGhUb2tlblByb3ZpZGVyKTsKKworICAgIGlmIChjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHMKKyAgICAgICAgICAgIC5ORVRXT1JLX0NPTk5FQ1RFRAorICAgICAgICA9PSBmaWxlRG93bmxvYWRlclJlcXVlc3QuZG93bmxvYWRDb25zdHJhaW50cygpKSB7CisgICAgICByZXF1ZXN0QnVpbGRlci5zZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpOworICAgIH0gZWxzZSB7CisgICAgICAvLyBVc2UgYWxsIG5ldHdvcmsgdHlwZXMgZXhjZXB0IGNlbGx1bGFyIGFuZCByZXF1aXJlIHVubWV0ZXJlZCBuZXR3b3JrLgorICAgICAgcmVxdWVzdEJ1aWxkZXIuc2V0RG93bmxvYWRDb25zdHJhaW50cygKKyAgICAgICAgICBEb3dubG9hZENvbnN0cmFpbnRzLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAuYWRkUmVxdWlyZWROZXR3b3JrVHlwZShOZXR3b3JrVHlwZS5XSUZJKQorICAgICAgICAgICAgICAuYWRkUmVxdWlyZWROZXR3b3JrVHlwZShOZXR3b3JrVHlwZS5FVEhFUk5FVCkKKyAgICAgICAgICAgICAgLmFkZFJlcXVpcmVkTmV0d29ya1R5cGUoTmV0d29ya1R5cGUuQkxVRVRPT1RIKQorICAgICAgICAgICAgICAuc2V0UmVxdWlyZVVubWV0ZXJlZE5ldHdvcmsodHJ1ZSkKKyAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgIH0KKworICAgIGlmIChmaWxlRG93bmxvYWRlclJlcXVlc3QudHJhZmZpY1RhZygpID4gMCkgeworICAgICAgLy8gUHJlZmVyIHRyYWZmaWMgdGFnIGZyb20gcmVxdWVzdC4KKyAgICAgIHJlcXVlc3RCdWlsZGVyLnNldFRyYWZmaWNTdGF0c1RhZyhmaWxlRG93bmxvYWRlclJlcXVlc3QudHJhZmZpY1RhZygpKTsKKyAgICB9IGVsc2UgaWYgKGRlZmF1bHRUcmFmZmljVGFnLmlzUHJlc2VudCgpICYmIGRlZmF1bHRUcmFmZmljVGFnLmdldCgpID4gMCkgeworICAgICAgLy8gVXNlIGRlZmF1bHQgdHJhZmZpYyB0YWcgYXMgYSBmYWxsYmFjayBpZiBwcmVzZW50LgorICAgICAgcmVxdWVzdEJ1aWxkZXIuc2V0VHJhZmZpY1N0YXRzVGFnKGRlZmF1bHRUcmFmZmljVGFnLmdldCgpKTsKKyAgICB9CisKKyAgICBmb3IgKFBhaXI8U3RyaW5nLCBTdHJpbmc+IGhlYWRlciA6IGZpbGVEb3dubG9hZGVyUmVxdWVzdC5leHRyYUh0dHBIZWFkZXJzKCkpIHsKKyAgICAgIHJlcXVlc3RCdWlsZGVyLmFkZEhlYWRlcihoZWFkZXIuZmlyc3QsIGhlYWRlci5zZWNvbmQpOworICAgIH0KKworICAgIHJldHVybiByZXF1ZXN0QnVpbGRlci5idWlsZCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9UaHJvdHRsaW5nRXhlY3V0b3IuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL1Rocm90dGxpbmdFeGVjdXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjljZWJmMTEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9UaHJvdHRsaW5nRXhlY3V0b3IuamF2YQpAQCAtMCwwICsxLDE1MiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5vZmZyb2FkOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLmJhc2UuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGw7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgamF2YS51dGlsLkFycmF5RGVxdWU7CitpbXBvcnQgamF2YS51dGlsLlF1ZXVlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uY29uY3VycmVudC5HdWFyZGVkQnk7CisKKy8qKgorICogUGFzc2VzIHRhc2tzIHRvIGEgZGVsZWdhdGUge0BsaW5rIEV4ZWN1dG9yfSBmb3IgZXhlY3V0aW9uLCBlbnN1cmluZyB0aGF0IG5vIG1vcmUgdGhhbiBhIGZpeGVkCisgKiBudW1iZXIgb2YgdGhlbSBhcmUgc3VibWl0dGVkIGF0IGFueSBvbmUgdGltZS4gSWYgdGhlIGxpbWl0IGlzIHJlYWNoZWQsIHRoZW4gbmV3IHRhc2tzIHdpbGwgYmUKKyAqIHF1ZXVlZCB1cCBhbmQgc3VibWl0dGVkIHdoZW4gcG9zc2libGUuCisgKgorICogPHA+SWYgdGhlIGRlbGVnYXRlIHtAbGluayBFeGVjdXRvcn0gaXMgb25seSBhY2Nlc3NlZCB2aWEgc29tZSB7QGxpbmsgVGhyb3R0bGluZ0V4ZWN1dG9yfSwgdGhpcworICogZWZmZWN0aXZlbHkgbGltaXRzIHRoZSBudW1iZXIgb2YgY29uY3VycmVudCB0YXNrcy90aHJlYWRzLiBBbHRlcm5hdGl2ZWx5LCB3ZSBjYW4gd3JhcCBhIHNoYXJlZAorICoge0BsaW5rIEV4ZWN1dG9yfSBpbiBhIHtAbGluayBUaHJvdHRsaW5nRXhlY3V0b3J9IGJlZm9yZSBwYXNzaW5nIGl0IHRvIHNvbWUgY29tcG9uZW50LCB0byBsaW1pdAorICogdGhlIGFtb3VudCBvZiBjb25jdXJyZW5jeSB0aGF0IGNvbXBvbmVudCBjYW4gcmVxdWVzdC4KKyAqCisgKiA8cD5JZiB0aGUgZGVsZWdhdGUge0BsaW5rIEV4ZWN1dG9yfSByZWplY3RzIHF1ZXVlZCB0YXNrcywgdGhleSB3aWxsIGJlIHNpbGVudGx5IGRyb3BwZWQuIFRvIGtlZXAKKyAqIHRoZSBpbXBsZW1lbnRhdGlvbiBzaW1wbGUsIHNob3VsZCB0aGUgZGVsZWdhdGUge0BsaW5rIEV4ZWN1dG9yfSByZWplY3QgdGFza3MsIHRoZW4gd2UgbWF5IGVuZCB1cAorICogd2l0aCBzb21lIHRhc2tzIHF1ZXVlZCBldmVuIGlmIGZld2VyIHRhc2tzIGFyZSBhY3R1YWxseSBydW5uaW5nIHRoYW4gb3VyIGJvdW5kIGFsbG93cy4gV2Ugd2lsbAorICoga2VlcCBzdWJtaXR0aW5nIG5ldyB0YXNrcywgaG93ZXZlciwgc28gdGhhdCB0cmFuc2llbnQgcHJvYmxlbXMgaW4gdGhlIHVuZGVybHlpbmcge0BsaW5rIEV4ZWN1dG9yfQorICogZG8gbm90IHByZXZlbnQgbmV3IHRhc2tzIGZyb20gcnVubmluZy4KKyAqLworcHVibGljIGNsYXNzIFRocm90dGxpbmdFeGVjdXRvciBpbXBsZW1lbnRzIEV4ZWN1dG9yIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJUaHJvdHRsaW5nRXhlY3V0b3IiOworCisgIHByaXZhdGUgZmluYWwgRXhlY3V0b3IgZGVsZWdhdGVFeGVjdXRvcjsKKyAgcHJpdmF0ZSBmaW5hbCBpbnQgbWF4aW11bVRocmVhZHM7CisKKyAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgbG9jayA9IG5ldyBPYmplY3QoKTsKKworICBAR3VhcmRlZEJ5KCJsb2NrIikKKyAgcHJpdmF0ZSBpbnQgY291bnQgPSAwOworCisgIEBHdWFyZGVkQnkoImxvY2siKQorICBwcml2YXRlIFF1ZXVlPFJ1bm5hYmxlPiBxdWV1ZSA9IG5ldyBBcnJheURlcXVlPD4oKTsKKworICBwdWJsaWMgVGhyb3R0bGluZ0V4ZWN1dG9yKEV4ZWN1dG9yIGRlbGVnYXRlLCBpbnQgbWF4aW11bVRocmVhZHMpIHsKKyAgICBkZWxlZ2F0ZUV4ZWN1dG9yID0gZGVsZWdhdGU7CisgICAgdGhpcy5tYXhpbXVtVGhyZWFkcyA9IG1heGltdW1UaHJlYWRzOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGV4ZWN1dGUoUnVubmFibGUgcnVubmFibGUpIHsKKyAgICBjaGVja05vdE51bGwocnVubmFibGUpOworCisgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICBpZiAoY291bnQgPj0gbWF4aW11bVRocmVhZHMpIHsKKyAgICAgICAgcXVldWUuYWRkKHJ1bm5hYmxlKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorCisgICAgICAvLyBXZSdyZSBnb2luZyB0byBydW4gdGhlIHRhc2sgaW1tZWRpYXRlbHksIG91dHNpZGUgdGhpcyBzeW5jaHJvbml6ZWQgYmxvY2sKKyAgICAgIGNvdW50Kys7CisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIGRlbGVnYXRlRXhlY3V0b3IuZXhlY3V0ZShuZXcgV3JhcHBlZFJ1bm5hYmxlKHJ1bm5hYmxlKSk7CisgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICBjb3VudC0tOworICAgICAgfQorICAgICAgdGhyb3cgdDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogU3VibWl0cyB0aGUgbmV4dCB0YXNrIGZyb20gdGhlIHtAbGluayBRdWV1ZX0sIGRlY3JlbWVudGluZyB0aGUgY291bnQgb2YgYWN0aXZlbHkgcnVubmluZyB0YXNrcworICAgKiBpZiB0aGVyZSBhcmVuJ3QgYW55LiBUaGlzIG1ldGhvZCBpcyBpbW1lZGlhdGVseSBhZnRlciBhIHtAbGluayBSdW5uYWJsZX0gaGFzIGNvbXBsZXRlZC4KKyAgICoKKyAgICogPHA+VGhlcmUgYXJlIGEgY291cGxlIG9mIGRlc2lnbiBwb2ludHMgaGVyZS4KKyAgICoKKyAgICogPHA+Rmlyc3RseSwgaG93IGRvIHdlIHJ1biB0aGUgbmV4dCB0YXNrPyBXZSBjb3VsZCBlaXRoZXIgc3VibWl0IHRoZSBuZXh0IHRhc2sgdXNpbmcge0BsaW5rCisgICAqIEV4ZWN1dG9yI2V4ZWN1dGUoKX0sIG9yIHdlIGNvdWxkIHJ1biBpdCBpbmxpbmUuIFRoZSBmaXJzdCBhcHByb2FjaCBpcyBzaW1wbGVyLCBidXQgaGFzIHRoZQorICAgKiBkcmF3YmFjayB0aGF0IHRoZSBkZWxlZ2F0ZSBFeGVjdXRvciBjYW4gc2VlIG1vcmUgdGhhbiB7QGNvZGUgbWF4aW11bVRocmVhZHN9IHRhc2tzIHJ1bm5pbmcKKyAgICogc2ltdWx0YW5lb3VzbHk6IGFzIHdlIGFyZSBzdWJtaXR0ZWQgaGVyZSBmcm9tIHRoZSBlbmQgb2YgYW4gb2xkIHRhc2ssIHRoZSBFeGVjdXRvciBicmllZmx5CisgICAqIGNvbnNpZGVycyBib3RoIHRoZSBvbGQgYW5kIG5ldyB0YXNrIHRvIGJlIHJ1bm5pbmcuIFRoZSBzZWNvbmQgYXBwcm9hY2ggYXZvaWRzIHRoaXMgYW5kIG1heSBiZQorICAgKiBzbGlnaHRseSBtb3JlIGVmZmljaWVudCwgYnV0IGhhcyBhZGRlZCBjb21wbGV4aXR5IChpbiBwYXJ0aWN1bGFyIGluIGV4Y2VwdGlvbiBoYW5kbGluZyAtIHdlCisgICAqIHN0aWxsIHdhbnQgYW55IHVuY2hlY2tlZCBUaG93YWJsZXMgdGhyb3duIGZyb20gYSB0YXNrIHRvIGJlIHByb3BhZ2F0ZWQgb24pLiBBbHNvLCBpZiBvdGhlcgorICAgKiB0YXNrcyBhcmUgd2FpdGluZyB0byBydW4gb24gdGhlIGRlbGVnYXRlIHtAbGluayBFeGVjdXRvcn0gd2l0aG91dCBwYXNzaW5nIHRocm91Z2ggdGhpcworICAgKiB0aHJvdHRsZSwgdGhlbiB0aGUgc2Vjb25kIGFwcHJvYWNoIGNhbiBwcmV2ZW50IHRob3NlIHRhc2tzIGZyb20gaGF2aW5nIGEgY2hhbmNlIHRvIHJ1bi4gSWYgaW4KKyAgICogZG91YnQsIGtlZXAgaXQgc2ltcGxlIC0gc28gd2UgYWRvcHQgdGhlIGZpcnN0IGFwcHJvYWNoLgorICAgKgorICAgKiA8cD5TZWNvbmRseSwgd2Ugd2FudCBhbnkgVGhyb3dhYmxlcyB0aHJvd24gZHVyaW5nIHRoZSB0YXNrIHRvIGJlIHByb3BhZ2F0ZWQgb24gdG8gdGhlIGRlbGVnYXRlCisgICAqIHtAbGluayBFeGVjdXRvcn0sIGFzIGlmIHRoZSB7QGxpbmsgVGhyb3R0bGluZ0V4ZWN1dG9yfSB3YXNuJ3QgaW4gdGhlIHdheS4gQnV0IHdoYXQgYWJvdXQKKyAgICogZXhjZXB0aW9ucyB0aHJvd24gYnkgdGhlIHtAbGluayBFeGVjdXRvciNleGVjdXRlfSBtZXRob2Q/IFRoYXQgbWV0aG9kIGNvdWxkIHRocm93IHtAbGluaworICAgKiBSZWplY3RlZEV4ZWN1dGlvbkV4Y2VwdGlvbn0gaW4gcGFydGljdWxhciBpZiB0aGUgZXhlY3V0b3IgaGFzIGJlZW4gc2h1dCBkb3duIGJ1dCBhbHNvIGZvciBhbnkKKyAgICogb3RoZXIgcmVhc29uLiBJdCBjb3VsZCBhbHNvIHRocm93IHRoZSB1c3VhbCByYW5nZSBvZiB1bmNoZWNrZWQgZXhjZXB0aW9ucy4gSW4gZWl0aGVyIHNpdHVhdGlvbgorICAgKiB3ZSBzaW1wbHkgZGVjcmVtZW50IHRoZSBjb3VudCBzbyB0aGF0IG5ld2x5IHN1Ym1pdHRlZCB0YXNrcyBjYW4gc3RpbGwgYmUgYXR0ZW1wdGVkLiBOb3RlIHRoYXQKKyAgICogdGhpcyBhcHByb2FjaCwgd2hpbGUgc2ltcGxlLCBjYW4gbGVhdmUgc29tZSB0YXNrcyAic3RyYW5kZWQiIG9uIHRoZSBxdWV1ZSB1bnRpbCBvdGhlciB0YXNrcyBhcmUKKyAgICogc3VibWl0dGVkIGFuZCBmaW5pc2ggLSBpZiB0aGUgdW5kZXJseWluZyBleGVjdXRvciBoYXMgYmVlbiBzaHV0ZG93biBvciBwZXJtYW5lbnRseSBicm9rZW4gdGhlbgorICAgKiB0aGlzIG1ha2VzIG5vIGRpZmZlcmVuY2U7IG90aGVyd2lzZSBzaG91bGQgbmV2ZXIgYXJpc2UgYnV0IGlmIHRoZXkgZG8sIGF0IGxlYXN0IG5ldyB0YXNrcyBjYW4KKyAgICogYXR0ZW1wdCB0byBiZSBydW4uCisgICAqLworICBwcml2YXRlIHZvaWQgc3VibWl0TmV4dFRhc2tPckRlY3JlbWVudENvdW50KCkgeworICAgIFJ1bm5hYmxlIHRvU3VibWl0OworICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgdG9TdWJtaXQgPSBxdWV1ZS5wb2xsKCk7CisgICAgICBpZiAodG9TdWJtaXQgPT0gbnVsbCkgeworICAgICAgICBjb3VudC0tOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIGRlbGVnYXRlRXhlY3V0b3IuZXhlY3V0ZShuZXcgV3JhcHBlZFJ1bm5hYmxlKHRvU3VibWl0KSk7CisgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgIC8vIFN1cHByZXNzIHRoaXMgZXhjZXB0aW9uLCB3aGljaCBpcyBwcm9iYWJseSBhIFJlamVjdGVkRXhlY3V0aW9uRXhjZXB0aW9uLiBXZSdyZSBjYWxsZWQgZnJvbQorICAgICAgLy8gdGhlIGZpbmFsbHkgYmxvY2sgYWZ0ZXIgc29tZSBvdGhlciB0YXNrIGhhcyBjb21wbGV0ZWQsIGFuZCB3ZSBkb24ndCB3YW50IHRvIHN1cHByZXNzIGFueQorICAgICAgLy8gZXhjZXB0aW9uIGZyb20gdGhlIGp1c3QtY29tcGxldGVkIHRhc2suCisgICAgICBMb2dVdGlsLmUodCwgIiVzOiBUYXNrIHN1Ym1pc3Npb24gZmFpbGVkOiAlcyIsIFRBRywgdG9TdWJtaXQpOworICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgIGNvdW50LS07CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBjbGFzcyBXcmFwcGVkUnVubmFibGUgaW1wbGVtZW50cyBSdW5uYWJsZSB7CisgICAgcHJpdmF0ZSBmaW5hbCBSdW5uYWJsZSBkZWxlZ2F0ZVJ1bm5hYmxlOworCisgICAgcHVibGljIFdyYXBwZWRSdW5uYWJsZShSdW5uYWJsZSBkZWxlZ2F0ZSkgeworICAgICAgZGVsZWdhdGVSdW5uYWJsZSA9IGRlbGVnYXRlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGRlbGVnYXRlUnVubmFibGUucnVuKCk7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBzdWJtaXROZXh0VGFza09yRGVjcmVtZW50Q291bnQoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL1RyYWZmaWNTdGF0c1NvY2tldEZhY3RvcnkuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL1RyYWZmaWNTdGF0c1NvY2tldEZhY3RvcnkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZGQ1ZThiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvVHJhZmZpY1N0YXRzU29ja2V0RmFjdG9yeS5qYXZhCkBAIC0wLDAgKzEsNzggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZDsKKworaW1wb3J0IGFuZHJvaWQubmV0LlRyYWZmaWNTdGF0czsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNvY2tldDsKK2ltcG9ydCBqYXZheC5uZXQuU29ja2V0RmFjdG9yeTsKKworLyoqIEEgY3VzdG9tIFNvY2tldEZhY3RvcnkgdGhhdCB0YWdzIHRoZSB0cmFmZmljIGdvaW5nIHRocm91Z2ggdGhlIHNvY2tldCBjcmVhdGVkIGJ5IGl0LiAqLworLy8gVE9ETyhiLzE0MTM2Mjc5OCk6IE1ha2UgcGFja2FnZS1wcml2YXRlIHdoZW4gT2tIdHRwRmlsZURvd25sb2FkZXJNb2R1bGUgc3VwcG9ydHMgbm9uLWZyYW1ld29yaworLy8gYXBwcy4KK3B1YmxpYyBmaW5hbCBjbGFzcyBUcmFmZmljU3RhdHNTb2NrZXRGYWN0b3J5IGV4dGVuZHMgU29ja2V0RmFjdG9yeSB7CisKKyAgcHJpdmF0ZSBmaW5hbCBTb2NrZXRGYWN0b3J5IGRlbGVnYXRlOworICBwcml2YXRlIGZpbmFsIGludCB0cmFmZmljVGFnOworCisgIHB1YmxpYyBUcmFmZmljU3RhdHNTb2NrZXRGYWN0b3J5KFNvY2tldEZhY3RvcnkgZGVsZWdhdGUsIGludCB0cmFmZmljVGFnKSB7CisgICAgdGhpcy5kZWxlZ2F0ZSA9IGRlbGVnYXRlOworICAgIHRoaXMudHJhZmZpY1RhZyA9IHRyYWZmaWNUYWc7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFNvY2tldCBzb2NrZXQgPSBkZWxlZ2F0ZS5jcmVhdGVTb2NrZXQoKTsKKyAgICBUcmFmZmljU3RhdHMuc2V0VGhyZWFkU3RhdHNUYWcodHJhZmZpY1RhZyk7CisgICAgVHJhZmZpY1N0YXRzLnRhZ1NvY2tldChzb2NrZXQpOworICAgIHJldHVybiBzb2NrZXQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoU3RyaW5nIGhvc3QsIGludCBwb3J0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFNvY2tldCBzb2NrZXQgPSBkZWxlZ2F0ZS5jcmVhdGVTb2NrZXQoaG9zdCwgcG9ydCk7CisgICAgVHJhZmZpY1N0YXRzLnNldFRocmVhZFN0YXRzVGFnKHRyYWZmaWNUYWcpOworICAgIFRyYWZmaWNTdGF0cy50YWdTb2NrZXQoc29ja2V0KTsKKyAgICByZXR1cm4gc29ja2V0OworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTb2NrZXQgY3JlYXRlU29ja2V0KFN0cmluZyBob3N0LCBpbnQgcG9ydCwgSW5ldEFkZHJlc3MgbG9jYWxIb3N0LCBpbnQgbG9jYWxQb3J0KQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBTb2NrZXQgc29ja2V0ID0gZGVsZWdhdGUuY3JlYXRlU29ja2V0KGhvc3QsIHBvcnQsIGxvY2FsSG9zdCwgbG9jYWxQb3J0KTsKKyAgICBUcmFmZmljU3RhdHMuc2V0VGhyZWFkU3RhdHNUYWcodHJhZmZpY1RhZyk7CisgICAgVHJhZmZpY1N0YXRzLnRhZ1NvY2tldChzb2NrZXQpOworICAgIHJldHVybiBzb2NrZXQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgaG9zdCwgaW50IHBvcnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgU29ja2V0IHNvY2tldCA9IGRlbGVnYXRlLmNyZWF0ZVNvY2tldChob3N0LCBwb3J0KTsKKyAgICBUcmFmZmljU3RhdHMuc2V0VGhyZWFkU3RhdHNUYWcodHJhZmZpY1RhZyk7CisgICAgVHJhZmZpY1N0YXRzLnRhZ1NvY2tldChzb2NrZXQpOworICAgIHJldHVybiBzb2NrZXQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFNvY2tldCBjcmVhdGVTb2NrZXQoSW5ldEFkZHJlc3MgYWRkcmVzcywgaW50IHBvcnQsIEluZXRBZGRyZXNzIGxvY2FsQWRkcmVzcywgaW50IGxvY2FsUG9ydCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgU29ja2V0IHNvY2tldCA9IGRlbGVnYXRlLmNyZWF0ZVNvY2tldChhZGRyZXNzLCBwb3J0LCBsb2NhbEFkZHJlc3MsIGxvY2FsUG9ydCk7CisgICAgVHJhZmZpY1N0YXRzLnNldFRocmVhZFN0YXRzVGFnKHRyYWZmaWNUYWcpOworICAgIFRyYWZmaWNTdGF0cy50YWdTb2NrZXQoc29ja2V0KTsKKyAgICByZXR1cm4gc29ja2V0OworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9kYWdnZXIvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9kYWdnZXIvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjA4MTRlOAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL2RhZ2dlci9CVUlMRApAQCAtMCwwICsxLDMxIEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9saWJyYXJ5IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbCisgICAgICAgICIvL3Zpc2liaWxpdHk6cHVibGljIiwKKyAgICBdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiQmFzZU9mZnJvYWRGaWxlRG93bmxvYWRlck1vZHVsZSIsCisgICAgc3JjcyA9IFsiQmFzZU9mZnJvYWRGaWxlRG93bmxvYWRlck1vZHVsZS5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hbm5vdGF0aW9ucyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlcjpGaWxlRG93bmxvYWRlciIsCisgICAgICAgICJAY29tX2dvb2dsZV9kYWdnZXIiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9kYWdnZXIvQmFzZU9mZnJvYWRGaWxlRG93bmxvYWRlck1vZHVsZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvZGFnZ2VyL0Jhc2VPZmZyb2FkRmlsZURvd25sb2FkZXJNb2R1bGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNzhiYzQyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvZGFnZ2VyL0Jhc2VPZmZyb2FkRmlsZURvd25sb2FkZXJNb2R1bGUuamF2YQpAQCAtMCwwICsxLDU0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLm9mZnJvYWQuZGFnZ2VyOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuYW5ub3RhdGlvbnMuU29ja2V0VHJhZmZpY1RhZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLk9BdXRoVG9rZW5Qcm92aWRlcjsKK2ltcG9ydCBkYWdnZXIuQmluZHNPcHRpb25hbE9mOworaW1wb3J0IGRhZ2dlci5Nb2R1bGU7CisKKy8qKgorICogRGFnZ2VyIG1vZHVsZSBmb3IgcHJvdmlkaW5nIHNoYXJlZCBiaW5kaW5ncyByZXF1aXJlZCBmb3IgT2Zmcm9hZEZpbGVEb3dubG9hZGVyLgorICoKKyAqIDxwPlRoZSBiaW5kaW5ncyBpbmNsdWRlZCBoZXJlIGFyZSBvcHRpb25hbCBiaW5kaW5ncyB1c2VkIGJ5IHRoZSBkaWZmZXJlbnQgcHJvdmlkZXJzLiBUaGlzIG1vZHVsZQorICogaXMgaW5jbHVkZWQgZGlyZWN0bHkgaW4gdGhlIG90aGVyIG1vZHVsZXMgc28gdGhlcmUgaXMgb25seSAxIHBsYWNlIHRoZXNlIGJpbmRpbmdzIGV4aXN0LgorICovCitATW9kdWxlCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQmFzZU9mZnJvYWRGaWxlRG93bmxvYWRlck1vZHVsZSB7CisKKyAgLyoqCisgICAqIE9wdGlvbmFsIE9BdXRoVG9rZW5Qcm92aWRlci4KKyAgICoKKyAgICogPHA+SWYgT0F1dGggdG9rZW5zIHNob3VsZCBiZSBwcm92aWRlZCB3aGVuIGRvd25sb2FkaW5nLCBjbGllbnRzIHNob3VsZCBwcm92aWRlIGEgYmluZGluZy4KKyAgICoKKyAgICogPHA+VXNlZCBieSBDcm9uZXQsIE9rSHR0cDMgYW5kIE9rSHR0cDIuCisgICAqLworICBAQmluZHNPcHRpb25hbE9mCisgIGFic3RyYWN0IE9BdXRoVG9rZW5Qcm92aWRlciBvcHRpb25hbE9BdXRoVG9rZW5Qcm92aWRlcigpOworCisgIC8qKgorICAgKiBPcHRpb25hbCBUcmFmZmljIFRhZy4KKyAgICoKKyAgICogPHA+SWYgbmV0d29yayB0cmFmZmljIHNob3VsZCBiZSB0YWdnZWQsIGNsaWVudHMgc2hvdWxkIHByb3ZpZGUgYSBiaW5kaW5nLgorICAgKgorICAgKiA8cD5Vc2VkIGJ5IE9rSHR0cDMgYW5kIE9rSHR0cDIuCisgICAqLworICBAQmluZHNPcHRpb25hbE9mCisgIEBTb2NrZXRUcmFmZmljVGFnCisgIGFic3RyYWN0IEludGVnZXIgb3B0aW9uYWxUcmFmZmljVGFnKCk7CisKKyAgcHJpdmF0ZSBCYXNlT2Zmcm9hZEZpbGVEb3dubG9hZGVyTW9kdWxlKCkge30KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL2RhZ2dlci9kb3dubG9hZGVyMi9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL2RhZ2dlci9kb3dubG9hZGVyMi9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xM2YwNWUwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvZGFnZ2VyL2Rvd25sb2FkZXIyL0JVSUxECkBAIC0wLDAgKzEsNTUgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsKKyAgICAgICAgIi8vdmlzaWJpbGl0eTpwdWJsaWMiLAorICAgIF0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJiYXNlIiwKKyAgICBzcmNzID0gWyJCYXNlRmlsZURvd25sb2FkZXJNb2R1bGUuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6YmFzZV9kZXBzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXI6RmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZDpFeGNlcHRpb25IYW5kbGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQ6T2Zmcm9hZDJGaWxlRG93bmxvYWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL2RhZ2dlcjpCYXNlT2Zmcm9hZEZpbGVEb3dubG9hZGVyTW9kdWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXI6ZG93bmxvYWRlcjIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3I6RG93bmxvYWRQcm9ncmVzc01vbml0b3IiLAorICAgICAgICAiQGFuZHJvaWR4X2Fubm90YXRpb25fYW5ub3RhdGlvbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICJAY29tX2dvb2dsZV9kYWdnZXIiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGRvd25sb2FkZXIiLAorICAgICAgICAiQGphdmF4X2luamVjdCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiYmFzZV9kZXBzIiwKKyAgICBzcmNzID0gWyJCYXNlRmlsZURvd25sb2FkZXJEZXBzTW9kdWxlLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZDpFeGNlcHRpb25IYW5kbGVyIiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfZGFnZ2VyIiwKKyAgICAgICAgIkBkb3dubG9hZGVyIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvZGFnZ2VyL2Rvd25sb2FkZXIyL0Jhc2VGaWxlRG93bmxvYWRlckRlcHNNb2R1bGUuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL2RhZ2dlci9kb3dubG9hZGVyMi9CYXNlRmlsZURvd25sb2FkZXJEZXBzTW9kdWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjk4ZDEzZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL2RhZ2dlci9kb3dubG9hZGVyMi9CYXNlRmlsZURvd25sb2FkZXJEZXBzTW9kdWxlLmphdmEKQEAgLTAsMCArMSw1MyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5vZmZyb2FkLmRhZ2dlci5kb3dubG9hZGVyMjsKKworaW1wb3J0IGFuZHJvaWR4LmFubm90YXRpb24uVmlzaWJsZUZvclRlc3Rpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmRvd25sb2FkZXIuVXJsRW5naW5lOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZC5FeGNlcHRpb25IYW5kbGVyOworaW1wb3J0IGRhZ2dlci5CaW5kc09wdGlvbmFsT2Y7CitpbXBvcnQgZGFnZ2VyLk1vZHVsZTsKKworLyoqCisgKiBEYWdnZXIgbW9kdWxlIGZvciBwcm92aWRpbmcgdGhlIGNvbW1vbiBkZXBlbmVuZGVjaWVzIG9mIEZpbGVEb3dubG9hZGVycyBiYWNrZWQgYnkgQW5kcm9pZAorICogRG93bmxvYWRlcjIuCisgKgorICogPHA+VGhlIGJpbmRpbmdzIGluY2x1ZGVkIGhlcmUgYXJlIG9wdGlvbmFsIGJpbmRpbmdzIHRvIGFsbG93IHBsYXRmb3JtLXNwZWNpZmljIGltcGxlbWVudGF0aW9ucyB0bworICogYmUgcHJvdmlkZWQgKGkuZS4gcHJvdmlkaW5nIGEgQ3JvbmV0LXNwZWNpZmljIEV4Y2VwdGlvbkhhbmRsZXIpLCBhbmQgY29tbW9uIGJpbmRpbmdzIHRoYXQgd2lsbCBiZQorICogdXNlZCBhY3Jvc3MgYWxsIEZpbGVEb3dubG9hZGVycyBiYWNrZWQgYnkgQW5kcm9pZCBEb3dubG9hZGVyMi4KKyAqLworQE1vZHVsZQorQFZpc2libGVGb3JUZXN0aW5nCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQmFzZUZpbGVEb3dubG9hZGVyRGVwc01vZHVsZSB7CisKKyAgLyoqCisgICAqIFBsYXRmb3JtIHNwZWNpZmljIHtAbGluayBFeGNlcHRpb25IYW5kbGVyfS4KKyAgICoKKyAgICogPHA+SWYgbm8gc3BlY2lmaWMgZXhjZXB0aW9uIGhhbmRsZXIgaXMgYXZhaWxhYmxlLCB0aGUgZGVmYXVsdCBvbmUgd2lsbCBiZSB1c2VkLgorICAgKi8KKyAgQEJpbmRzT3B0aW9uYWxPZgorICBhYnN0cmFjdCBFeGNlcHRpb25IYW5kbGVyIHBsYXRmb3JtU3BlY2lmaWNFeGNlcHRpb25IYW5kbGVyKCk7CisKKyAgLyoqCisgICAqIFBsYXRmb3JtIHNwZWNpZmljIHtAbGluayBVcmxFbmdpbmV9LgorICAgKgorICAgKiA8cD5JZiBubyBzcGVjaWZpYyBlbmdpbmUgaXMgcHJvdmlkZWQsIHRoZSBwbGF0Zm9ybSBlbmdpbmUgd2lsbCBiZSB1c2VkLgorICAgKi8KKyAgQEJpbmRzT3B0aW9uYWxPZgorICBhYnN0cmFjdCBVcmxFbmdpbmUgcGxhdGZvcm1TcGVjaWZpY1VybEVuZ2luZSgpOworCisgIHByaXZhdGUgQmFzZUZpbGVEb3dubG9hZGVyRGVwc01vZHVsZSgpIHt9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9kYWdnZXIvZG93bmxvYWRlcjIvQmFzZUZpbGVEb3dubG9hZGVyTW9kdWxlLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9kYWdnZXIvZG93bmxvYWRlcjIvQmFzZUZpbGVEb3dubG9hZGVyTW9kdWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDI1NjA4YwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL2RhZ2dlci9kb3dubG9hZGVyMi9CYXNlRmlsZURvd25sb2FkZXJNb2R1bGUuamF2YQpAQCAtMCwwICsxLDE3OCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5vZmZyb2FkLmRhZ2dlci5kb3dubG9hZGVyMjsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmU7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkeC5hbm5vdGF0aW9uLlZpc2libGVGb3JUZXN0aW5nOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkFuZHJvaWRDb25uZWN0aXZpdHlIYW5kbGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmRvd25sb2FkZXIuRG93bmxvYWRlci5TdGF0ZUNoYW5nZUNhbGxiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkZsb2dnZXJEb3dubG9hZGVyTG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLlBsYXRmb3JtQW5kcm9pZFRyYWZmaWNTdGF0c1RhZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5QbGF0Zm9ybVVybEVuZ2luZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5VcmxFbmdpbmU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuYW5ub3RhdGlvbnMuTWRkQ29udHJvbEV4ZWN1dG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmFubm90YXRpb25zLk1kZERvd25sb2FkRXhlY3V0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuYW5ub3RhdGlvbnMuU29ja2V0VHJhZmZpY1RhZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuT0F1dGhUb2tlblByb3ZpZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZC5FeGNlcHRpb25IYW5kbGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZC5PZmZyb2FkMkZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZC5kYWdnZXIuQmFzZU9mZnJvYWRGaWxlRG93bmxvYWRlck1vZHVsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5pbnRlZ3JhdGlvbi5kb3dubG9hZGVyLkRvd25sb2FkTWV0YWRhdGFTdG9yZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5TdXBwbGllcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGRhZ2dlci5MYXp5OworaW1wb3J0IGRhZ2dlci5Nb2R1bGU7CitpbXBvcnQgZGFnZ2VyLlByb3ZpZGVzOworaW1wb3J0IGRhZ2dlci5tdWx0aWJpbmRpbmdzLkludG9NYXA7CitpbXBvcnQgZGFnZ2VyLm11bHRpYmluZGluZ3MuU3RyaW5nS2V5OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworaW1wb3J0IGphdmF4LmluamVjdC5TaW5nbGV0b247CisKKy8qKgorICogRGFnZ2VyIG1vZHVsZSBmb3IgcHJvdmlkaW5nIEZpbGVEb3dubG9hZGVyIHRoYXQgdXNlcyBBbmRyb2lkIERvd25sb2FkZXIyLgorICoKKyAqIDxwPlRoaXMgbW9kdWxlIHNob3VsZCBvbmx5IGJlIHVzZWQgd2hlbiB7QGxpbmsgTXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlcn0gaXMgYmVpbmcgcHJvdmlkZWQgYnkKKyAqIHtAbGluayBGaWxlRG93bmxvYWRlck1vZHVsZX0uIFRoYXQgbW9kdWxlIGluY2x1ZGVzIGEgbWFwIG9mIEZpbGVEb3dubG9hZGVyIFN1cHBsaWVycywgd2hpY2ggdGhpcworICogbW9kdWxlIGFzc3VtZXMgaXMgYXZhaWxhYmxlIHRvIGJpbmQgaW50by4KKyAqLworQE1vZHVsZSgKKyAgICBpbmNsdWRlcyA9IHsKKyAgICAgIEJhc2VPZmZyb2FkRmlsZURvd25sb2FkZXJNb2R1bGUuY2xhc3MsCisgICAgICBCYXNlRmlsZURvd25sb2FkZXJEZXBzTW9kdWxlLmNsYXNzLAorICAgIH0pCitAVmlzaWJsZUZvclRlc3RpbmcKK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBCYXNlRmlsZURvd25sb2FkZXJNb2R1bGUgeworICBAUHJvdmlkZXMKKyAgQFNpbmdsZXRvbgorICBASW50b01hcAorICBAU3RyaW5nS2V5KCJodHRwcyIpCisgIHN0YXRpYyBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gcHJvdmlkZUZpbGVEb3dubG9hZGVyKAorICAgICAgQ29udGV4dCBjb250ZXh0LAorICAgICAgQE1kZERvd25sb2FkRXhlY3V0b3IgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIGRvd25sb2FkRXhlY3V0b3IsCisgICAgICBATWRkQ29udHJvbEV4ZWN1dG9yIExpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSBjb250cm9sRXhlY3V0b3IsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLAorICAgICAgRG93bmxvYWRNZXRhZGF0YVN0b3JlIGRvd25sb2FkTWV0YWRhdGFTdG9yZSwKKyAgICAgIE9wdGlvbmFsPERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yPiBkb3dubG9hZFByb2dyZXNzTW9uaXRvciwKKyAgICAgIE9wdGlvbmFsPExhenk8VXJsRW5naW5lPj4gdXJsRW5naW5lT3B0aW9uYWwsCisgICAgICBPcHRpb25hbDxMYXp5PEV4Y2VwdGlvbkhhbmRsZXI+PiBleGNlcHRpb25IYW5kbGVyT3B0aW9uYWwsCisgICAgICBPcHRpb25hbDxMYXp5PE9BdXRoVG9rZW5Qcm92aWRlcj4+IGF1dGhUb2tlblByb3ZpZGVyT3B0aW9uYWwsCisgICAgICBAU29ja2V0VHJhZmZpY1RhZyBPcHRpb25hbDxJbnRlZ2VyPiB0cmFmZmljVGFnLAorICAgICAgRmxhZ3MgZmxhZ3MpIHsKKyAgICByZXR1cm4gKCkgLT4KKyAgICAgICAgY3JlYXRlT2Zmcm9hZDJGaWxlRG93bmxvYWRlcigKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBkb3dubG9hZEV4ZWN1dG9yLAorICAgICAgICAgICAgY29udHJvbEV4ZWN1dG9yLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBkb3dubG9hZE1ldGFkYXRhU3RvcmUsCisgICAgICAgICAgICBkb3dubG9hZFByb2dyZXNzTW9uaXRvciwKKyAgICAgICAgICAgIHVybEVuZ2luZU9wdGlvbmFsLAorICAgICAgICAgICAgZXhjZXB0aW9uSGFuZGxlck9wdGlvbmFsLAorICAgICAgICAgICAgYXV0aFRva2VuUHJvdmlkZXJPcHRpb25hbCwKKyAgICAgICAgICAgIHRyYWZmaWNUYWcsCisgICAgICAgICAgICBmbGFncyk7CisgIH0KKworICBAVmlzaWJsZUZvclRlc3RpbmcKKyAgcHVibGljIHN0YXRpYyBPZmZyb2FkMkZpbGVEb3dubG9hZGVyIGNyZWF0ZU9mZnJvYWQyRmlsZURvd25sb2FkZXIoCisgICAgICBDb250ZXh0IGNvbnRleHQsCisgICAgICBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UgZG93bmxvYWRFeGVjdXRvciwKKyAgICAgIExpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSBjb250cm9sRXhlY3V0b3IsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLAorICAgICAgRG93bmxvYWRNZXRhZGF0YVN0b3JlIGRvd25sb2FkTWV0YWRhdGFTdG9yZSwKKyAgICAgIE9wdGlvbmFsPERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yPiBkb3dubG9hZFByb2dyZXNzTW9uaXRvciwKKyAgICAgIE9wdGlvbmFsPExhenk8VXJsRW5naW5lPj4gdXJsRW5naW5lT3B0aW9uYWwsCisgICAgICBPcHRpb25hbDxMYXp5PEV4Y2VwdGlvbkhhbmRsZXI+PiBleGNlcHRpb25IYW5kbGVyT3B0aW9uYWwsCisgICAgICBPcHRpb25hbDxMYXp5PE9BdXRoVG9rZW5Qcm92aWRlcj4+IGF1dGhUb2tlblByb3ZpZGVyT3B0aW9uYWwsCisgICAgICBPcHRpb25hbDxJbnRlZ2VyPiB0cmFmZmljVGFnLAorICAgICAgRmxhZ3MgZmxhZ3MpIHsKKyAgICBATnVsbGFibGUKKyAgICBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5PQXV0aFRva2VuUHJvdmlkZXIgYXV0aFRva2VuUHJvdmlkZXIgPQorICAgICAgICBhdXRoVG9rZW5Qcm92aWRlck9wdGlvbmFsLmlzUHJlc2VudCgpCisgICAgICAgICAgICA/IGNvbnZlcnRUb0Rvd25sb2FkZXJBdXRoVG9rZW5Qcm92aWRlcihhdXRoVG9rZW5Qcm92aWRlck9wdGlvbmFsLmdldCgpLmdldCgpKQorICAgICAgICAgICAgOiBudWxsOworCisgICAgRXhjZXB0aW9uSGFuZGxlciBoYW5kbGVyID0KKyAgICAgICAgZXhjZXB0aW9uSGFuZGxlck9wdGlvbmFsLnRyYW5zZm9ybShMYXp5OjpnZXQpLm9yKEV4Y2VwdGlvbkhhbmRsZXIud2l0aERlZmF1bHRIYW5kbGluZygpKTsKKworICAgIFVybEVuZ2luZSB1cmxFbmdpbmU7CisgICAgaWYgKHVybEVuZ2luZU9wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICB1cmxFbmdpbmUgPSB1cmxFbmdpbmVPcHRpb25hbC5nZXQoKS5nZXQoKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gVXNlIHtAbGluayBQbGF0Zm9ybVVybEVuZ2luZX0gaWYgb25lIHdhcyBub3QgcHJvdmlkZWQuCisgICAgICB1cmxFbmdpbmUgPQorICAgICAgICAgIG5ldyBQbGF0Zm9ybVVybEVuZ2luZSgKKyAgICAgICAgICAgICAgY29udHJvbEV4ZWN1dG9yLAorICAgICAgICAgICAgICAvKiBjb25uZWN0VGltZW91dE1zID0gKi8gZmxhZ3MudGltZVRvV2FpdEZvckRvd25sb2FkZXIoKSwKKyAgICAgICAgICAgICAgLyogcmVhZFRpbWVvdXRNcyA9ICovIGZsYWdzLnRpbWVUb1dhaXRGb3JEb3dubG9hZGVyKCksCisgICAgICAgICAgICAgIG5ldyBQbGF0Zm9ybUFuZHJvaWRUcmFmZmljU3RhdHNUYWdnZXIoKSk7CisgICAgfQorCisgICAgQW5kcm9pZENvbm5lY3Rpdml0eUhhbmRsZXIgY29ubmVjdGl2aXR5SGFuZGxlciA9CisgICAgICAgIG5ldyBBbmRyb2lkQ29ubmVjdGl2aXR5SGFuZGxlcigKKyAgICAgICAgICAgIGNvbnRleHQsIGRvd25sb2FkRXhlY3V0b3IsIC8qIHRpbWVvdXRNaWxsaXMgPSAqLyBmbGFncy50aW1lVG9XYWl0Rm9yRG93bmxvYWRlcigpKTsKKworICAgIEZsb2dnZXJEb3dubG9hZGVyTG9nZ2VyIGxvZ2dlciA9IG5ldyBGbG9nZ2VyRG93bmxvYWRlckxvZ2dlcigpOworCisgICAgRG93bmxvYWRlciBkb3dubG9hZGVyID0KKyAgICAgICAgbmV3IERvd25sb2FkZXIuQnVpbGRlcigpCisgICAgICAgICAgICAud2l0aElPRXhlY3V0b3IoY29udHJvbEV4ZWN1dG9yKQorICAgICAgICAgICAgLndpdGhDb25uZWN0aXZpdHlIYW5kbGVyKGNvbm5lY3Rpdml0eUhhbmRsZXIpCisgICAgICAgICAgICAud2l0aE1heENvbmN1cnJlbnREb3dubG9hZHMoZmxhZ3MuZG93bmxvYWRlck1heFRocmVhZHMoKSkKKyAgICAgICAgICAgIC53aXRoTG9nZ2VyKGxvZ2dlcikKKyAgICAgICAgICAgIC5hZGRVcmxFbmdpbmUoImh0dHBzIiwgdXJsRW5naW5lKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBpZiAoZG93bmxvYWRQcm9ncmVzc01vbml0b3IuaXNQcmVzZW50KCkpIHsKKyAgICAgIC8vIFdpcmUgdXAgZG93bmxvYWRlcidzIHN0YXRlIGNoYW5nZXMgdG8gRG93bmxvYWRQcm9ncmVzc01vbml0b3IgdG8gaGFuZGxlIGNvbm5lY3Rpdml0eQorICAgICAgLy8gcGF1c2VzLgorICAgICAgU3RhdGVDaGFuZ2VDYWxsYmFjayBjYWxsYmFjayA9CisgICAgICAgICAgc3RhdGUgLT4geworICAgICAgICAgICAgaWYgKHN0YXRlLmdldE51bURvd25sb2Fkc1BlbmRpbmdDb25uZWN0aXZpdHkoKSA+IDAKKyAgICAgICAgICAgICAgICAmJiBzdGF0ZS5nZXROdW1Eb3dubG9hZHNJbkZsaWdodCgpID09IDApIHsKKyAgICAgICAgICAgICAgLy8gSGFuZGxlIG5ldHdvcmsgY29ubmVjdGl2aXR5IHBhdXNlcworICAgICAgICAgICAgICBkb3dubG9hZFByb2dyZXNzTW9uaXRvci5nZXQoKS5wYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9OworICAgICAgZG93bmxvYWRlci5yZWdpc3RlclN0YXRlQ2hhbmdlQ2FsbGJhY2soY2FsbGJhY2ssIGNvbnRyb2xFeGVjdXRvcik7CisgICAgfQorCisgICAgcmV0dXJuIG5ldyBPZmZyb2FkMkZpbGVEb3dubG9hZGVyKAorICAgICAgICBkb3dubG9hZGVyLAorICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgZG93bmxvYWRFeGVjdXRvciwKKyAgICAgICAgYXV0aFRva2VuUHJvdmlkZXIsCisgICAgICAgIGRvd25sb2FkTWV0YWRhdGFTdG9yZSwKKyAgICAgICAgaGFuZGxlciwKKyAgICAgICAgdHJhZmZpY1RhZyk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5PQXV0aFRva2VuUHJvdmlkZXIKKyAgICAgIGNvbnZlcnRUb0Rvd25sb2FkZXJBdXRoVG9rZW5Qcm92aWRlcihPQXV0aFRva2VuUHJvdmlkZXIgYXV0aFRva2VuUHJvdmlkZXIpIHsKKyAgICByZXR1cm4gdXJpIC0+IGltbWVkaWF0ZUZ1dHVyZShhdXRoVG9rZW5Qcm92aWRlci5wcm92aWRlT0F1dGhUb2tlbih1cmkudG9TdHJpbmcoKSkpOworICB9CisKKyAgcHJpdmF0ZSBCYXNlRmlsZURvd25sb2FkZXJNb2R1bGUoKSB7fQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL0JVSUxEIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM0OTUwYjkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvQlVJTEQKQEAgLTAsMCArMSw0MyBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImZpbGUiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJCZWhhdmlvci5qYXZhIiwKKyAgICAgICAgIk1vbml0b3JJbnB1dFN0cmVhbS5qYXZhIiwKKyAgICAgICAgIk1vbml0b3JPdXRwdXRTdHJlYW0uamF2YSIsCisgICAgICAgICJPcGVuQ29udGV4dC5qYXZhIiwKKyAgICAgICAgIk9wZW5lci5qYXZhIiwKKyAgICAgICAgIlN5bmNocm9ub3VzRmlsZVN0b3JhZ2UuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpmb3J3YXJkaW5nX3N0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6bGl0ZV90cmFuc2Zvcm1fZnJhZ21lbnRzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpwcmVjb25kaXRpb25zIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICJAY29tX2dvb2dsZV9lcnJvcnByb25lX2Vycm9yX3Byb25lX2Fubm90YXRpb25zIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL0JlaGF2aW9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvQmVoYXZpb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NGZiN2UyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL0JlaGF2aW9yLmphdmEKQEAgLTAsMCArMSw1MiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZTsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBJbnRlcmZhY2UgZm9yIGFkZGluZyBiZWhhdmlvciB0byBob3cgYSBmaWxlIGlzIG9wZW5lZCB0aGF0J3MgaW5kZXBlbmRlbnQgZnJvbSB0aGUgT3BlbmVyIGFuZAorICogVHJhbnNmb3Jtcy4gRm9yIGV4YW1wbGUsIHRoaXMgaXMgdXNlZCB0byBzdXBwb3J0IGZpbGUgbG9ja2luZyBhbmQgc3luY2luZy4gSW5zdGFuY2VzIGFyZSBwYXNzZWQKKyAqIHRoZSB3aG9sZSBjaGFpbiBvZiBzdHJlYW1zICh3aGljaCBpbmNsdWRlcyBiYWNrZW5kcywgdHJhbnNmb3JtcyBhbmQgbW9uaXRvcnMpLiBUaGUgY2hhaW4gaXMKKyAqIG9yZGVyZWQgc28gdGhhdCB0aGUgZmlyc3Qgc3RyZWFtIGlzIHRoZSBvbmUgdGhhdCB0aGUgY2xpZW50IHNlZXMsIGFuZCB0aGUgbGFzdCBzdHJlYW0gdGhlCisgKiBiYWNrZW5kLiBXaGlsZSB0aGUgaW50ZXJmYWNlIG9ubHkgc2VlcyBJbnB1dC9PdXRwdXRTdHJlYW1zLCBtb3N0IGltcGxlbWVudGF0aW9ucyB3aWxsIHJlbHkgb24KKyAqIDxjb2RlPmluc3RhbmNlb2Y8L2NvZGU+IHRvIHNlZSBpZiB0aGVyZSBhcmUgb3RoZXIgZmVhdHVyZXMgYXZhaWxhYmxlIG9uIHRoZSBzdHJlYW0uCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgQmVoYXZpb3IgeworCisgIC8qKgorICAgKiBJbmZvcm0gdGhpcyBCZWhhdmlvciBhYm91dCB0aGlzIGlucHV0IGNoYWluLgorICAgKgorICAgKiBAcGFyYW0gY2hhaW4gVGhlIHRyYW5zZm9ybXMsIG1vbml0b3JzLCBhbmQgYmFja2VuZCAoaW4gdGhhdCBvcmRlcikuCisgICAqLworICBkZWZhdWx0IHZvaWQgZm9ySW5wdXRDaGFpbihMaXN0PElucHV0U3RyZWFtPiBjaGFpbikgdGhyb3dzIElPRXhjZXB0aW9uIHt9CisKKyAgLyoqCisgICAqIEluZm9ybSB0aGlzIEJlaGF2aW9yIGFib3V0IHRoaXMgb3V0cHV0IGNoYWluLgorICAgKgorICAgKiBAcGFyYW0gY2hhaW4gVGhlIHRyYW5zZm9ybXMsIG1vbml0b3JzLCBhbmQgYmFja2VuZCAoaW4gdGhhdCBvcmRlcikuCisgICAqLworICBkZWZhdWx0IHZvaWQgZm9yT3V0cHV0Q2hhaW4oTGlzdDxPdXRwdXRTdHJlYW0+IGNoYWluKSB0aHJvd3MgSU9FeGNlcHRpb24ge30KKworICAvKioKKyAgICogUGVyZm9ybSBhbnkgYXNwZWN0cyBvZiB0aGUgYmVoYXZpb3IgdGhhdCBhcmUgcmVxdWlyZWQgdG8gYmUgZXhlY3V0ZWQgaW1tZWRpYXRlbHkgcHJpb3IgdG8KKyAgICogY2xvc2luZyB0aGUgc3RyZWFtLgorICAgKi8KKyAgZGVmYXVsdCB2b2lkIGNvbW1pdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7fQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL01vbml0b3JJbnB1dFN0cmVhbS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL01vbml0b3JJbnB1dFN0cmVhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxYzUxMWYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvTW9uaXRvcklucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwxMDkgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGU7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uU2l6YWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbC5Gb3J3YXJkaW5nSW5wdXRTdHJlYW07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuUHJlY29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5Nb25pdG9yOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKiBTdHJlYW0gdGhhdCBpbnZva2VzIGlucHV0IHN0cmVhbSBtb25pdG9ycy4gKi8KK2ZpbmFsIGNsYXNzIE1vbml0b3JJbnB1dFN0cmVhbSBleHRlbmRzIEZvcndhcmRpbmdJbnB1dFN0cmVhbSBpbXBsZW1lbnRzIFNpemFibGUgeworICBwcml2YXRlIGZpbmFsIExpc3Q8TW9uaXRvci5JbnB1dE1vbml0b3I+IGlucHV0TW9uaXRvcnM7CisKKyAgcHJpdmF0ZSBNb25pdG9ySW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gaW5wdXQsIExpc3Q8TW9uaXRvci5JbnB1dE1vbml0b3I+IGlucHV0TW9uaXRvcnMpIHsKKyAgICBzdXBlcihpbnB1dCk7CisgICAgdGhpcy5pbnB1dE1vbml0b3JzID0gaW5wdXRNb25pdG9yczsKKyAgICBQcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoaW5wdXQgIT0gbnVsbCwgIklucHV0IHdhcyBudWxsIik7CisgIH0KKworICAvKioKKyAgICogV3JhcHMge0Bjb2RlIGlufSB3aXRoIGEgbmV3IHN0cmVhbSB0aGF0IG9yY2hlc3RyYXRlcyB7QGNvZGUgbW9uaXRvcnN9LCBvciByZXR1cm5zIG51bGwgaWYgdGhpcworICAgKiBJTyBkb2Vzbid0IG5lZWQgdG8gYmUgbW9uaXRvcmVkLgorICAgKi8KKyAgQE51bGxhYmxlCisgIHB1YmxpYyBzdGF0aWMgTW9uaXRvcklucHV0U3RyZWFtIG5ld0luc3RhbmNlKExpc3Q8TW9uaXRvcj4gbW9uaXRvcnMsIFVyaSB1cmksIElucHV0U3RyZWFtIGluKSB7CisgICAgTGlzdDxNb25pdG9yLklucHV0TW9uaXRvcj4gaW5wdXRNb25pdG9ycyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgIGZvciAoTW9uaXRvciBtb25pdG9yIDogbW9uaXRvcnMpIHsKKyAgICAgIE1vbml0b3IuSW5wdXRNb25pdG9yIGlucHV0TW9uaXRvciA9IG1vbml0b3IubW9uaXRvclJlYWQodXJpKTsKKyAgICAgIGlmIChpbnB1dE1vbml0b3IgIT0gbnVsbCkgeworICAgICAgICBpbnB1dE1vbml0b3JzLmFkZChpbnB1dE1vbml0b3IpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gIWlucHV0TW9uaXRvcnMuaXNFbXB0eSgpID8gbmV3IE1vbml0b3JJbnB1dFN0cmVhbShpbiwgaW5wdXRNb25pdG9ycykgOiBudWxsOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaW50IHJlc3VsdCA9IGluLnJlYWQoKTsKKyAgICBpZiAocmVzdWx0ICE9IC0xKSB7CisgICAgICBieXRlW10gYiA9IG5ldyBieXRlW10geyhieXRlKSByZXN1bHR9OworICAgICAgZm9yIChNb25pdG9yLklucHV0TW9uaXRvciBpbnB1dE1vbml0b3IgOiBpbnB1dE1vbml0b3JzKSB7CisgICAgICAgIGlucHV0TW9uaXRvci5ieXRlc1JlYWQoYiwgMCwgMSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCByZWFkKGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGludCByZXN1bHQgPSBpbi5yZWFkKGIpOworICAgIGlmIChyZXN1bHQgIT0gLTEpIHsKKyAgICAgIGZvciAoTW9uaXRvci5JbnB1dE1vbml0b3IgaW5wdXRNb25pdG9yIDogaW5wdXRNb25pdG9ycykgeworICAgICAgICBpbnB1dE1vbml0b3IuYnl0ZXNSZWFkKGIsIDAsIHJlc3VsdCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCByZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGludCByZXN1bHQgPSBpbi5yZWFkKGIsIG9mZiwgbGVuKTsKKyAgICBpZiAocmVzdWx0ICE9IC0xKSB7CisgICAgICBmb3IgKE1vbml0b3IuSW5wdXRNb25pdG9yIGlucHV0TW9uaXRvciA6IGlucHV0TW9uaXRvcnMpIHsKKyAgICAgICAgaW5wdXRNb25pdG9yLmJ5dGVzUmVhZChiLCBvZmYsIHJlc3VsdCk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBATnVsbGFibGUKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMb25nIHNpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICghKGluIGluc3RhbmNlb2YgU2l6YWJsZSkpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICByZXR1cm4gKChTaXphYmxlKSBpbikuc2l6ZSgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmb3IgKE1vbml0b3IuSW5wdXRNb25pdG9yIGlucHV0TW9uaXRvciA6IGlucHV0TW9uaXRvcnMpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIGlucHV0TW9uaXRvci5jbG9zZSgpOworICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgLy8gSWdub3JlLgorICAgICAgfQorICAgIH0KKyAgICBzdXBlci5jbG9zZSgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvTW9uaXRvck91dHB1dFN0cmVhbS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL01vbml0b3JPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMTc3YmFiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL01vbml0b3JPdXRwdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEwOCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZTsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbC5Gb3J3YXJkaW5nT3V0cHV0U3RyZWFtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLlByZWNvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuTW9uaXRvcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5OdWxsYWJsZTsKKworLyoqIFN0cmVhbSB0aGF0IGludm9rZXMgb3V0cHV0IHN0cmVhbSBtb25pdG9ycy4gKi8KK2ZpbmFsIGNsYXNzIE1vbml0b3JPdXRwdXRTdHJlYW0gZXh0ZW5kcyBGb3J3YXJkaW5nT3V0cHV0U3RyZWFtIHsKKyAgcHJpdmF0ZSBmaW5hbCBMaXN0PE1vbml0b3IuT3V0cHV0TW9uaXRvcj4gb3V0cHV0TW9uaXRvcnM7CisKKyAgcHJpdmF0ZSBNb25pdG9yT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXRwdXQsIExpc3Q8TW9uaXRvci5PdXRwdXRNb25pdG9yPiBvdXRwdXRNb25pdG9ycykgeworICAgIHN1cGVyKG91dHB1dCk7CisgICAgdGhpcy5vdXRwdXRNb25pdG9ycyA9IG91dHB1dE1vbml0b3JzOworICAgIFByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChvdXRwdXQgIT0gbnVsbCwgIk91dHB1dCB3YXMgbnVsbCIpOworICB9CisKKyAgLyoqCisgICAqIFdyYXBzIHtAY29kZSBvdXR9IHdpdGggYSBuZXcgc3RyZWFtIHRoYXQgb3JjaGVzdHJhdGVzIHtAY29kZSBtb25pdG9yc30sIG9yIHJldHVybnMgbnVsbCBpZiB0aGlzCisgICAqIElPIGRvZXNuJ3QgbmVlZCB0byBiZSBtb25pdG9yZWQuCisgICAqLworICBATnVsbGFibGUKKyAgcHVibGljIHN0YXRpYyBNb25pdG9yT3V0cHV0U3RyZWFtIG5ld0luc3RhbmNlRm9yV3JpdGUoCisgICAgICBMaXN0PE1vbml0b3I+IG1vbml0b3JzLCBVcmkgdXJpLCBPdXRwdXRTdHJlYW0gb3V0KSB7CisgICAgTGlzdDxNb25pdG9yLk91dHB1dE1vbml0b3I+IG91dHB1dE1vbml0b3JzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgZm9yIChNb25pdG9yIG1vbml0b3IgOiBtb25pdG9ycykgeworICAgICAgTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IgPSBtb25pdG9yLm1vbml0b3JXcml0ZSh1cmkpOworICAgICAgaWYgKG91dHB1dE1vbml0b3IgIT0gbnVsbCkgeworICAgICAgICBvdXRwdXRNb25pdG9ycy5hZGQob3V0cHV0TW9uaXRvcik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiAhb3V0cHV0TW9uaXRvcnMuaXNFbXB0eSgpID8gbmV3IE1vbml0b3JPdXRwdXRTdHJlYW0ob3V0LCBvdXRwdXRNb25pdG9ycykgOiBudWxsOworICB9CisKKyAgLyoqCisgICAqIFdyYXBzIHtAY29kZSBvdXR9IHdpdGggYSBuZXcgc3RyZWFtIHRoYXQgb3JjaGVzdHJhdGVzIHtAY29kZSBtb25pdG9yc30sIG9yIHJldHVybnMgbnVsbCBpZiB0aGlzCisgICAqIElPIGRvZXNuJ3QgbmVlZCB0byBiZSBtb25pdG9yZWQuCisgICAqLworICBATnVsbGFibGUKKyAgcHVibGljIHN0YXRpYyBNb25pdG9yT3V0cHV0U3RyZWFtIG5ld0luc3RhbmNlRm9yQXBwZW5kKAorICAgICAgTGlzdDxNb25pdG9yPiBtb25pdG9ycywgVXJpIHVyaSwgT3V0cHV0U3RyZWFtIG91dCkgeworICAgIExpc3Q8TW9uaXRvci5PdXRwdXRNb25pdG9yPiBvdXRwdXRNb25pdG9ycyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgIGZvciAoTW9uaXRvciBtb25pdG9yIDogbW9uaXRvcnMpIHsKKyAgICAgIE1vbml0b3IuT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yID0gbW9uaXRvci5tb25pdG9yQXBwZW5kKHVyaSk7CisgICAgICBpZiAob3V0cHV0TW9uaXRvciAhPSBudWxsKSB7CisgICAgICAgIG91dHB1dE1vbml0b3JzLmFkZChvdXRwdXRNb25pdG9yKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuICFvdXRwdXRNb25pdG9ycy5pc0VtcHR5KCkgPyBuZXcgTW9uaXRvck91dHB1dFN0cmVhbShvdXQsIG91dHB1dE1vbml0b3JzKSA6IG51bGw7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgb3V0LndyaXRlKGIpOworICAgIGJ5dGVbXSBicyA9IG5ldyBieXRlW10geyhieXRlKSBifTsKKyAgICBmb3IgKE1vbml0b3IuT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yIDogb3V0cHV0TW9uaXRvcnMpIHsKKyAgICAgIG91dHB1dE1vbml0b3IuYnl0ZXNXcml0dGVuKGJzLCAwLCAxKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgd3JpdGUoYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgb3V0LndyaXRlKGIpOworICAgIGZvciAoTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IgOiBvdXRwdXRNb25pdG9ycykgeworICAgICAgb3V0cHV0TW9uaXRvci5ieXRlc1dyaXR0ZW4oYiwgMCwgYi5sZW5ndGgpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBvdXQud3JpdGUoYiwgb2ZmLCBsZW4pOworICAgIGZvciAoTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IgOiBvdXRwdXRNb25pdG9ycykgeworICAgICAgb3V0cHV0TW9uaXRvci5ieXRlc1dyaXR0ZW4oYiwgb2ZmLCBsZW4pOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZm9yIChNb25pdG9yLk91dHB1dE1vbml0b3Igb3V0cHV0TW9uaXRvciA6IG91dHB1dE1vbml0b3JzKSB7CisgICAgICB0cnkgeworICAgICAgICBvdXRwdXRNb25pdG9yLmNsb3NlKCk7CisgICAgICB9IGNhdGNoIChUaHJvd2FibGUgdCkgeworICAgICAgICAvLyBJZ25vcmUuCisgICAgICB9CisgICAgfQorICAgIHN1cGVyLmNsb3NlKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9PcGVuQ29udGV4dC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL09wZW5Db250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGRjYjk2OAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9PcGVuQ29udGV4dC5qYXZhCkBAIC0wLDAgKzEsMjAxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5UcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JdGVyYWJsZXM7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIEVuY2Fwc3VsYXRlcyBzdGF0ZSBmb3IgYSBzaW5nbGUgb3BlbiBjYWxsIGluY2x1ZGluZyBzZWxlY3RlZCBiYWNrZW5kLCB0cmFuc2Zvcm1zLCBldGMuIFRoaXMgY2xhc3MKKyAqIGlzIHVzZWQgYXMgc2luZ2xlIHBhcmFtZXRlciB0byB7QGxpbmsgT3BlbmVyI29wZW59IGNhbGwuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBPcGVuQ29udGV4dCB7CisKKyAgcHJpdmF0ZSBmaW5hbCBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisgIHByaXZhdGUgZmluYWwgQmFja2VuZCBiYWNrZW5kOworICBwcml2YXRlIGZpbmFsIExpc3Q8VHJhbnNmb3JtPiB0cmFuc2Zvcm1zOworICBwcml2YXRlIGZpbmFsIExpc3Q8TW9uaXRvcj4gbW9uaXRvcnM7CisgIHByaXZhdGUgZmluYWwgVXJpIG9yaWdpbmFsVXJpOworICBwcml2YXRlIGZpbmFsIFVyaSBlbmNvZGVkVXJpOworCisgIC8qKiBCdWlsZGVyIGZvciBjb25zdHJ1Y3RpbmcgYW4gT3BlbkNvbnRleHQuICovCisgIHN0YXRpYyBjbGFzcyBCdWlsZGVyIHsKKyAgICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZTsKKyAgICBwcml2YXRlIEJhY2tlbmQgYmFja2VuZDsKKyAgICBwcml2YXRlIExpc3Q8VHJhbnNmb3JtPiB0cmFuc2Zvcm1zOworICAgIHByaXZhdGUgTGlzdDxNb25pdG9yPiBtb25pdG9yczsKKyAgICBwcml2YXRlIFVyaSBvcmlnaW5hbFVyaTsKKyAgICBwcml2YXRlIFVyaSBlbmNvZGVkVXJpOworCisgICAgcHJpdmF0ZSBCdWlsZGVyKCkge30KKworICAgIEJ1aWxkZXIgc2V0U3RvcmFnZShTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UpIHsKKyAgICAgIHRoaXMuc3RvcmFnZSA9IHN0b3JhZ2U7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBCdWlsZGVyIHNldEJhY2tlbmQoQmFja2VuZCBiYWNrZW5kKSB7CisgICAgICB0aGlzLmJhY2tlbmQgPSBiYWNrZW5kOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQnVpbGRlciBzZXRUcmFuc2Zvcm1zKExpc3Q8VHJhbnNmb3JtPiB0cmFuc2Zvcm1zKSB7CisgICAgICB0aGlzLnRyYW5zZm9ybXMgPSB0cmFuc2Zvcm1zOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgQnVpbGRlciBzZXRNb25pdG9ycyhMaXN0PE1vbml0b3I+IG1vbml0b3JzKSB7CisgICAgICB0aGlzLm1vbml0b3JzID0gbW9uaXRvcnM7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBCdWlsZGVyIHNldEVuY29kZWRVcmkoVXJpIGVuY29kZWRVcmkpIHsKKyAgICAgIHRoaXMuZW5jb2RlZFVyaSA9IGVuY29kZWRVcmk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBCdWlsZGVyIHNldE9yaWdpbmFsVXJpKFVyaSBvcmlnaW5hbFVyaSkgeworICAgICAgdGhpcy5vcmlnaW5hbFVyaSA9IG9yaWdpbmFsVXJpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgT3BlbkNvbnRleHQgYnVpbGQoKSB7CisgICAgICByZXR1cm4gbmV3IE9wZW5Db250ZXh0KHRoaXMpOworICAgIH0KKyAgfQorCisgIE9wZW5Db250ZXh0KEJ1aWxkZXIgYnVpbGRlcikgeworICAgIHRoaXMuc3RvcmFnZSA9IGJ1aWxkZXIuc3RvcmFnZTsKKyAgICB0aGlzLmJhY2tlbmQgPSBidWlsZGVyLmJhY2tlbmQ7CisgICAgdGhpcy50cmFuc2Zvcm1zID0gYnVpbGRlci50cmFuc2Zvcm1zOworICAgIHRoaXMubW9uaXRvcnMgPSBidWlsZGVyLm1vbml0b3JzOworICAgIHRoaXMub3JpZ2luYWxVcmkgPSBidWlsZGVyLm9yaWdpbmFsVXJpOworICAgIHRoaXMuZW5jb2RlZFVyaSA9IGJ1aWxkZXIuZW5jb2RlZFVyaTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgT3BlbkNvbnRleHQuQnVpbGRlciBidWlsZGVyKCkgeworICAgIHJldHVybiBuZXcgT3BlbkNvbnRleHQuQnVpbGRlcigpOworICB9CisKKyAgLyoqIEdldHMgYSByZWZlcmVuY2UgdG8gdGhlIHNhbWUgc3RvcmFnZSBpbnN0YW5jZS4gKi8KKyAgcHVibGljIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSgpIHsKKyAgICByZXR1cm4gc3RvcmFnZTsKKyAgfQorCisgIC8qKiBBY2Nlc3MgdGhlIGJhY2tlbmQgc2VsZWN0ZWQgYnkgdGhlIFVSSS4gKi8KKyAgcHVibGljIEJhY2tlbmQgYmFja2VuZCgpIHsKKyAgICByZXR1cm4gYmFja2VuZDsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm4gdGhlIFVSSSBhZnRlciBlbmNvZGluZyBvZiB0aGUgZmlsZW5hbWUgYW5kIHN0cmlwcGluZyBvZiB0aGUgZnJhZ21lbnQuIFRoaXMgaXMgd2hhdCB0aGUKKyAgICogYmFja2VuZCBzZWVzLgorICAgKi8KKyAgcHVibGljIFVyaSBlbmNvZGVkVXJpKCkgeworICAgIHJldHVybiBlbmNvZGVkVXJpOworICB9CisKKyAgLyoqIEdldCB0aGUgb3JpZ2luYWwgVVJJLiBUaGlzIGlzIHRoZSBvbmUgdGhlIGNhbGxlciBwYXNzZWQgdG8gdGhlIHN0b3JhZ2UgQVBJLiAqLworICBwdWJsaWMgVXJpIG9yaWdpbmFsVXJpKCkgeworICAgIHJldHVybiBvcmlnaW5hbFVyaTsKKyAgfQorCisgIC8qKgorICAgKiBDb21wb3NlcyBhbiBpbnB1dCBzdHJlYW0gYnkgY2hhaW5pbmcge0BsaW5rIE1vbml0b3JJbnB1dFN0cmVhbX0gYW5kIHtAbGluaworICAgKiBUcmFuc2Zvcm0jd3JhcEZvclJlYWR9cy4KKyAgICoKKyAgICogQHJldHVybiBBbGwgb2YgdGhlIGlucHV0IHN0cmVhbXMgaW4gdGhlIGNoYWluLiBUaGUgZmlyc3QgaXMgcmV0dXJuZWQgdG8gY2xpZW50LCBhbmQgdGhlIGxhc3QgaXMKKyAgICogICAgIHRoZSBvbmUgcHJvZHVjZWQgYnkgdGhlIGJhY2tlbmQuCisgICAqLworICBwdWJsaWMgTGlzdDxJbnB1dFN0cmVhbT4gY2hhaW5UcmFuc2Zvcm1zRm9yUmVhZChJbnB1dFN0cmVhbSBpbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMaXN0PElucHV0U3RyZWFtPiBjaGFpbiA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgIGNoYWluLmFkZChpbik7CisgICAgaWYgKCFtb25pdG9ycy5pc0VtcHR5KCkpIHsKKyAgICAgIE1vbml0b3JJbnB1dFN0cmVhbSBtb25pdG9yU3RyZWFtID0gTW9uaXRvcklucHV0U3RyZWFtLm5ld0luc3RhbmNlKG1vbml0b3JzLCBvcmlnaW5hbFVyaSwgaW4pOworICAgICAgaWYgKG1vbml0b3JTdHJlYW0gIT0gbnVsbCkgeworICAgICAgICBjaGFpbi5hZGQobW9uaXRvclN0cmVhbSk7CisgICAgICB9CisgICAgfQorICAgIGZvciAoVHJhbnNmb3JtIHRyYW5zZm9ybSA6IHRyYW5zZm9ybXMpIHsKKyAgICAgIGNoYWluLmFkZCh0cmFuc2Zvcm0ud3JhcEZvclJlYWQob3JpZ2luYWxVcmksIEl0ZXJhYmxlcy5nZXRMYXN0KGNoYWluKSkpOworICAgIH0KKyAgICBDb2xsZWN0aW9ucy5yZXZlcnNlKGNoYWluKTsKKyAgICByZXR1cm4gY2hhaW47CisgIH0KKworICAvKioKKyAgICogQ29tcG9zZXMgYW4gb3V0cHV0IHN0cmVhbSBieSBjaGFpbmluZyB7QGxpbmsgTW9uaXRvck91dHB1dFN0cmVhbX0gYW5kIHtAbGluaworICAgKiBUcmFuc2Zvcm0jd3JhcEZvcldyaXRlfXMuCisgICAqCisgICAqIEByZXR1cm4gQWxsIG9mIHRoZSBvdXRwdXQgc3RyZWFtcyBpbiB0aGUgY2hhaW4uIFRoZSBmaXJzdCBpcyByZXR1cm5lZCB0byBjbGllbnQsIGFuZCB0aGUgbGFzdAorICAgKiAgICAgaXMgdGhlIG9uZSBwcm9kdWNlZCBieSB0aGUgYmFja2VuZC4KKyAgICovCisgIHB1YmxpYyBMaXN0PE91dHB1dFN0cmVhbT4gY2hhaW5UcmFuc2Zvcm1zRm9yV3JpdGUoT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMaXN0PE91dHB1dFN0cmVhbT4gY2hhaW4gPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBjaGFpbi5hZGQob3V0KTsKKyAgICBpZiAoIW1vbml0b3JzLmlzRW1wdHkoKSkgeworICAgICAgTW9uaXRvck91dHB1dFN0cmVhbSBtb25pdG9yU3RyZWFtID0KKyAgICAgICAgICBNb25pdG9yT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlRm9yV3JpdGUobW9uaXRvcnMsIG9yaWdpbmFsVXJpLCBvdXQpOworICAgICAgaWYgKG1vbml0b3JTdHJlYW0gIT0gbnVsbCkgeworICAgICAgICBjaGFpbi5hZGQobW9uaXRvclN0cmVhbSk7CisgICAgICB9CisgICAgfQorICAgIGZvciAoVHJhbnNmb3JtIHRyYW5zZm9ybSA6IHRyYW5zZm9ybXMpIHsKKyAgICAgIGNoYWluLmFkZCh0cmFuc2Zvcm0ud3JhcEZvcldyaXRlKG9yaWdpbmFsVXJpLCBJdGVyYWJsZXMuZ2V0TGFzdChjaGFpbikpKTsKKyAgICB9CisgICAgQ29sbGVjdGlvbnMucmV2ZXJzZShjaGFpbik7CisgICAgcmV0dXJuIGNoYWluOworICB9CisKKyAgLyoqCisgICAqIENvbXBvc2VzIGFuIG91dHB1dCBzdHJlYW0gYnkgY2hhaW5pbmcge0BsaW5rIE1vbml0b3JPdXRwdXRTdHJlYW19IGFuZCB7QGxpbmsKKyAgICogVHJhbnNmb3JtI3dyYXBGb3JBcHBlbmR9cy4KKyAgICoKKyAgICogQHJldHVybiBBbGwgb2YgdGhlIG91dHB1dCBzdHJlYW1zIGluIHRoZSBjaGFpbi4gVGhlIGZpcnN0IGlzIHJldHVybmVkIHRvIGNsaWVudCwgYW5kIHRoZSBsYXN0CisgICAqICAgICBpcyB0aGUgb25lIHByb2R1Y2VkIGJ5IHRoZSBiYWNrZW5kLgorICAgKi8KKyAgcHVibGljIExpc3Q8T3V0cHV0U3RyZWFtPiBjaGFpblRyYW5zZm9ybXNGb3JBcHBlbmQoT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMaXN0PE91dHB1dFN0cmVhbT4gY2hhaW4gPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBjaGFpbi5hZGQob3V0KTsKKyAgICBpZiAoIW1vbml0b3JzLmlzRW1wdHkoKSkgeworICAgICAgTW9uaXRvck91dHB1dFN0cmVhbSBtb25pdG9yU3RyZWFtID0KKyAgICAgICAgICBNb25pdG9yT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlRm9yQXBwZW5kKG1vbml0b3JzLCBvcmlnaW5hbFVyaSwgb3V0KTsKKyAgICAgIGlmIChtb25pdG9yU3RyZWFtICE9IG51bGwpIHsKKyAgICAgICAgY2hhaW4uYWRkKG1vbml0b3JTdHJlYW0pOworICAgICAgfQorICAgIH0KKyAgICBmb3IgKFRyYW5zZm9ybSB0cmFuc2Zvcm0gOiB0cmFuc2Zvcm1zKSB7CisgICAgICBjaGFpbi5hZGQodHJhbnNmb3JtLndyYXBGb3JBcHBlbmQob3JpZ2luYWxVcmksIEl0ZXJhYmxlcy5nZXRMYXN0KGNoYWluKSkpOworICAgIH0KKyAgICBDb2xsZWN0aW9ucy5yZXZlcnNlKGNoYWluKTsKKyAgICByZXR1cm4gY2hhaW47CisgIH0KKworICAvKiogVGVsbHMgd2hldGhlciB0aGVyZSBhcmUgYW55IHRyYW5zZm9ybXMgY29uZmlndXJlZCBmb3IgdGhpcyBvcGVuIHJlcXVlc3QuICovCisgIHB1YmxpYyBib29sZWFuIGhhc1RyYW5zZm9ybXMoKSB7CisgICAgLy8gTk9URTogYSBtb3JlIGludGVsbGlnZW50IEFQSSBtaWdodCBjaGVjayBmb3IgYW55IHRyYW5zZm9ybXMgdGhhdCBhcmVuJ3QgU2l6YWJsZQorICAgIHJldHVybiAhdHJhbnNmb3Jtcy5pc0VtcHR5KCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9PcGVuZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9PcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMjQ3YzI5Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL09wZW5lci5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGU7CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIEludGVyZmFjZSBmb3Igb3BlbmluZyBhIGZpbGUuIEltcGxlbWVudGF0aW9uIGlzIHBhc3NlZCBhbiB7QGxpbmsgT3BlbkNvbnRleHR9IHdoaWNoIHByb3ZpZGVzCisgKiBhY2Nlc3MgdG8gdGhlIGJhY2tlbmQsIHRyYW5zZm9ybXMsIGFuZCBvdGhlciBpbmZvcm1hdGlvbiB0aGF0IGNhbiBiZSB1c2VkIHRvIGZ1bGZpbGwgdGhlIG9wZW4KKyAqIHJlcXVlc3QuIEZvciBleGFtcGxlLCBhIFByb3RvT3BlbmVyIGNvdWxkIHNpbXBseSBpbnZva2Uge0BsaW5rCisgKiBPcGVuQ29udGV4dCNjaGFpblRyYW5zZm9ybXNGb3JSZWFkfSBhbmQgcGFzcyB0aGF0IHRvIHRoZSBwcm90byBwYXJzZXIuCisgKgorICogPHA+T3BlbmVycyBhbHNvIGJlaGF2ZSBhIGxpdHRsZSBsaWtlIGJ1aWxkZXJzIGluIHRoYXQgdGhlaXIgYmVoYXZpb3IgY2FuIGJlIHBhcmFtZXRlcml6ZWQuIEZvcgorICogZXhhbXBsZSwgaWYgYW4gZXh0ZW5zaW9uIHJlZ2lzdHJ5IGlzIHJlcXVpcmVkLCBpdCBjYW4gYmUgc2V0IG9uIHRoZSBvcGVuZXIgYmVmb3JlIHBhc3NpbmcgdG8gZmlsZQorICogc3RvcmFnZS4KKyAqLworcHVibGljIGludGVyZmFjZSBPcGVuZXI8VD4geworICAvKiogSW52b2tlZCB0byBvcGVuIGEgZmlsZS4gKi8KKyAgVCBvcGVuKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvU3luY2hyb25vdXNGaWxlU3RvcmFnZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL1N5bmNocm9ub3VzRmlsZVN0b3JhZ2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYTU1ZTlkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL1N5bmNocm9ub3VzRmlsZVN0b3JhZ2UuamF2YQpAQCAtMCwwICsxLDQwOCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZTsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnRleHQuVGV4dFV0aWxzOworaW1wb3J0IGFuZHJvaWQudXRpbC5Mb2c7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uR2NQYXJhbTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5VbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLkxpdGVUcmFuc2Zvcm1GcmFnbWVudHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5Nb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLlRyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JdGVyYWJsZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5TZXRzOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DaGVja1JldHVyblZhbHVlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3RJdGVyYXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCisvKioKKyAqIEZpbGVTdG9yYWdlIGlzIGFuIGFic3RyYWN0aW9uIG92ZXIgcGxhdGZvcm0gRmlsZSBJL08gdGhhdCBzdXBwb3J0cyBwbHVnZ2FibGUgYmFja2VuZHMgYW5kCisgKiB0cmFuc2Zvcm1zLiBUaGlzIGlzIHRoZSBzeW5jaHJvbm91cyB2YXJpYW50IHdoaWNoIGlzIHVzZWZ1bCBmb3IgYmFja2dyb3VuZCBwcm9jZXNzaW5nIGFuZAorICogaW1wbGVtZW50aW5nIE9wZW5lcnMuCisgKgorICogPHA+Rm9yIHRlc3RpbmcsIGl0IGlzIHJlY29tbWVuZGVkIHRvIHVzZSBhIHJlYWwgYmFja2VuZCBzdWNoIGFzIEphdmFGaWxlQmFja2VuZCwgcmF0aGVyIHRoYW4KKyAqIG1vY2suCisgKgorICogPHA+U2VlIDxpbnRlcm5hbD4gZm9yIGRldGFpbHMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIk1vYlN0b3JlLkZpbGVTdG9yYWdlIjsKKworICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIEJhY2tlbmQ+IGJhY2tlbmRzID0gbmV3IEhhc2hNYXA8PigpOworICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIFRyYW5zZm9ybT4gdHJhbnNmb3JtcyA9IG5ldyBIYXNoTWFwPD4oKTsKKyAgcHJpdmF0ZSBmaW5hbCBMaXN0PE1vbml0b3I+IG1vbml0b3JzID0gbmV3IEFycmF5TGlzdDw+KCk7CisKKyAgLyoqCisgICAqIENvbnN0cnVjdHMgYSBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSB3aXRoIHRoZSBzcGVjaWZpZWQgZXhlY3V0b3JzLCBiYWNrZW5kcywgdHJhbnNmb3JtcywgYW5kCisgICAqIG1vbml0b3JzLgorICAgKgorICAgKiA8cD5JbiB0aGUgY2FzZSBvZiBhIGNvbGxpc2lvbiwgdGhlIGxhdGVyIGJhY2tlbmQvdHJhbnNmb3JtIHJlcGxhY2VzIGFueSBlYXJsaWVyIG9uZXMuCisgICAqCisgICAqIDxwPkZpbGVTdG9yYWdlIGlzIGV4cGVjdGVkIHRvIGJlIGEgc2luZ2xldG9uIHByb3ZpZGVkIGJ5IGRlcGVuZGVuY3kgaW5qZWN0aW9uLiBUcmFuc2Zvcm1zIGFuZAorICAgKiBiYWNrZW5kcyBzaG91bGQgYmUgcmVnaXN0ZXJlZCBvbmNlIHdoZW4gcHJvZHVjaW5nIHRoYXQgc2luZ2xldG9uLgorICAgKgorICAgKiA8cD5BbGwgbW9uaXRvcnMgYXJlIGV4ZWN1dGVkIGJldHdlZW4gdHJhbnNmb3JtcyBhbmQgdGhlIGJhY2tlbmQuIEZvciBleGFtcGxlLCBpZiB5b3UgaGFkIGEKKyAgICogY29tcHJlc3Npb24gdHJhbnNmb3JtLCB0aGUgbW9uaXRvciB3b3VsZCBzZWUgdGhlIGNvbXByZXNzZWQgYnl0ZXMuCisgICAqCisgICAqIEBwYXJhbSBiYWNrZW5kcyBSZWdpc3RlcnMgdGhlc2UgYmFja2VuZHMuCisgICAqIEBwYXJhbSB0cmFuc2Zvcm1zIFJlZ2lzdGVycyB0aGVzZSB0cmFuc2Zvcm1zLgorICAgKiBAcGFyYW0gbW9uaXRvcnMgUmVnaXN0ZXJzIHRoZXNlIG1vbml0b3JzLgorICAgKi8KKyAgcHVibGljIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICBMaXN0PEJhY2tlbmQ+IGJhY2tlbmRzLCBMaXN0PFRyYW5zZm9ybT4gdHJhbnNmb3JtcywgTGlzdDxNb25pdG9yPiBtb25pdG9ycykgeworICAgIHJlZ2lzdGVyUGx1Z2lucyhiYWNrZW5kcywgdHJhbnNmb3JtcywgbW9uaXRvcnMpOworICB9CisKKyAgLyoqIENvbnN0cnVjdHMgYSBuZXcgRmlsZVN0b3JhZ2Ugd2l0aCBUcmFuc2Zvcm1zIGJ1dCBubyBNb25pdG9ycy4gKi8KKyAgcHVibGljIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoTGlzdDxCYWNrZW5kPiBiYWNrZW5kcywgTGlzdDxUcmFuc2Zvcm0+IHRyYW5zZm9ybXMpIHsKKyAgICB0aGlzKGJhY2tlbmRzLCB0cmFuc2Zvcm1zLCBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKSk7CisgIH0KKworICAvKiogQ29uc3RydWN0cyBhIG5ldyBGaWxlU3RvcmFnZSB3aXRoIG5vIFRyYW5zZm9ybXMgb3IgTW9uaXRvcnMuICovCisgIHB1YmxpYyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKExpc3Q8QmFja2VuZD4gYmFja2VuZHMpIHsKKyAgICB0aGlzKGJhY2tlbmRzLCBDb2xsZWN0aW9ucy5lbXB0eUxpc3QoKSwgQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCkpOworICB9CisKKyAgLyoqCisgICAqIFJlZ2lzdGVycyBiYWNrZW5kcywgdHJhbnNmb3JtcyBhbmQgbW9uaXRvcnMgdG8gU3luY2hyb25vdXNGaWxlU3RvcmFnZS4KKyAgICoKKyAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZm9yIGF0dGVtcHRzIHRvIG92ZXJyaWRlIGV4aXN0aW5nIGJhY2tlbmRzIG9yIHRyYW5zZm9ybXMKKyAgICovCisgIHByaXZhdGUgdm9pZCByZWdpc3RlclBsdWdpbnMoCisgICAgICBMaXN0PEJhY2tlbmQ+IGJhY2tlbmRzLCBMaXN0PFRyYW5zZm9ybT4gdHJhbnNmb3JtcywgTGlzdDxNb25pdG9yPiBtb25pdG9ycykgeworICAgIGZvciAoQmFja2VuZCBiYWNrZW5kIDogYmFja2VuZHMpIHsKKyAgICAgIGlmIChUZXh0VXRpbHMuaXNFbXB0eShiYWNrZW5kLm5hbWUoKSkpIHsKKyAgICAgICAgTG9nLncoVEFHLCAiQ2Fubm90IHJlZ2lzdGVyIGJhY2tlbmQsIG5hbWUgZW1wdHkiKTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIEJhY2tlbmQgb2xkVmFsdWUgPSB0aGlzLmJhY2tlbmRzLnB1dChiYWNrZW5kLm5hbWUoKSwgYmFja2VuZCk7CisgICAgICBpZiAob2xkVmFsdWUgIT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgIkNhbm5vdCBvdmVycmlkZSBCYWNrZW5kICIKKyAgICAgICAgICAgICAgICArIG9sZFZhbHVlLmdldENsYXNzKCkuZ2V0Q2Fub25pY2FsTmFtZSgpCisgICAgICAgICAgICAgICAgKyAiIHdpdGggIgorICAgICAgICAgICAgICAgICsgYmFja2VuZC5nZXRDbGFzcygpLmdldENhbm9uaWNhbE5hbWUoKSk7CisgICAgICB9CisgICAgfQorICAgIGZvciAoVHJhbnNmb3JtIHRyYW5zZm9ybSA6IHRyYW5zZm9ybXMpIHsKKyAgICAgIGlmIChUZXh0VXRpbHMuaXNFbXB0eSh0cmFuc2Zvcm0ubmFtZSgpKSkgeworICAgICAgICBMb2cudyhUQUcsICJDYW5ub3QgcmVnaXN0ZXIgdHJhbnNmb3JtLCBuYW1lIGVtcHR5Iik7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgVHJhbnNmb3JtIG9sZFZhbHVlID0gdGhpcy50cmFuc2Zvcm1zLnB1dCh0cmFuc2Zvcm0ubmFtZSgpLCB0cmFuc2Zvcm0pOworICAgICAgaWYgKG9sZFZhbHVlICE9IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICJDYW5ub3QgdG8gb3ZlcnJpZGUgVHJhbnNmb3JtICIKKyAgICAgICAgICAgICAgICArIG9sZFZhbHVlLmdldENsYXNzKCkuZ2V0Q2Fub25pY2FsTmFtZSgpCisgICAgICAgICAgICAgICAgKyAiIHdpdGggIgorICAgICAgICAgICAgICAgICsgdHJhbnNmb3JtLmdldENsYXNzKCkuZ2V0Q2Fub25pY2FsTmFtZSgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgdGhpcy5tb25pdG9ycy5hZGRBbGwobW9uaXRvcnMpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgYSBTdHJpbmcgbGlzdGluZyByZWdpc3RlcmVkIGJhY2tlbmRzLCB0cmFuc2Zvcm1zIGFuZCBtb25pdG9ycyBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLgorICAgKi8KKyAgcHVibGljIFN0cmluZyBnZXREZWJ1Z0luZm8oKSB7CisgICAgU3RyaW5nIGJhY2tlbmRzRGVidWdTdHJpbmcgPQorICAgICAgICBUZXh0VXRpbHMuam9pbigKKyAgICAgICAgICAgICIsXG4iLAorICAgICAgICAgICAgU2V0cy5uZXdUcmVlU2V0KAorICAgICAgICAgICAgICAgIEl0ZXJhYmxlcy50cmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgIGJhY2tlbmRzLmtleVNldCgpLAorICAgICAgICAgICAgICAgICAgICBrZXkgLT4KKyAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZy5mb3JtYXQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgInByb3RvY29sOiAlMSRzLCBjbGFzczogJTIkcyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5LCBiYWNrZW5kcy5nZXQoa2V5KS5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSkpKSk7CisKKyAgICBTdHJpbmcgdHJhbnNmb3Jtc0RlYnVnU3RyaW5nID0KKyAgICAgICAgVGV4dFV0aWxzLmpvaW4oCisgICAgICAgICAgICAiLFxuIiwKKyAgICAgICAgICAgIFNldHMubmV3VHJlZVNldCgKKyAgICAgICAgICAgICAgICBJdGVyYWJsZXMudHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1zLnZhbHVlcygpLCB0cmFuc2Zvcm0gLT4gdHJhbnNmb3JtLmdldENsYXNzKCkuZ2V0U2ltcGxlTmFtZSgpKSkpOworCisgICAgU3RyaW5nIG1vbml0b3JzRGVidWdTdHJpbmcgPQorICAgICAgICBUZXh0VXRpbHMuam9pbigKKyAgICAgICAgICAgICIsXG4iLAorICAgICAgICAgICAgU2V0cy5uZXdUcmVlU2V0KAorICAgICAgICAgICAgICAgIEl0ZXJhYmxlcy50cmFuc2Zvcm0obW9uaXRvcnMsIG1vbml0b3IgLT4gbW9uaXRvci5nZXRDbGFzcygpLmdldFNpbXBsZU5hbWUoKSkpKTsKKworICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KAorICAgICAgICAiUmVnaXN0ZXJlZCBNb2JzdG9yZSBQbHVnaW5zOlxuXG5CYWNrZW5kczpcbiUxJHNcblxuVHJhbnNmb3JtczpcbiUyJHNcblxuTW9uaXRvcnM6XG4lMyRzIiwKKyAgICAgICAgYmFja2VuZHNEZWJ1Z1N0cmluZywgdHJhbnNmb3Jtc0RlYnVnU3RyaW5nLCBtb25pdG9yc0RlYnVnU3RyaW5nKTsKKyAgfQorCisgIC8qKgorICAgKiBPcGVuIFVSSSB3aXRoIGFuIE9wZW5lci4gVGhlIE9wZW5lciBkZXRlcm1pbmVzIHRoZSByZXR1cm4gdHlwZSwgZWcsIGEgU3RyZWFtIG9yIGEgUHJvdG8gYW5kIGlzCisgICAqIHJlc3BvbnNpYmxlIGZvciBpbXBsZW1lbnRpbmcgYW55IGFkZGl0aW9uYWwgYmVoYXZpb3Igc3VjaCBhcyBsb2NraW5nLgorICAgKgorICAgKiBAcGFyYW0gdXJpIFRoZSBVUkkgdG8gb3Blbi4KKyAgICogQHBhcmFtIG9wZW5lciBUaGUgZ2VuZXJpYyBvcGVuZXIgdG8gdXNlLgorICAgKiBAcGFyYW0gPFQ+IFRoZSBraW5kIG9mIHRoaW5nIHRoZSBvcGVuZXIgb3BlbnMuCisgICAqIEByZXR1cm4gVGhlIHJlc3VsdCBvZiB0aGUgb3BlbiBvcGVyYXRpb24uCisgICAqLworICBAQ2hlY2tSZXR1cm5WYWx1ZQorICBwdWJsaWMgPFQ+IFQgb3BlbihVcmkgdXJpLCBPcGVuZXI8VD4gb3BlbmVyKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIE9wZW5Db250ZXh0IGNvbnRleHQgPSBnZXRDb250ZXh0KHVyaSk7CisgICAgcmV0dXJuIG9wZW5lci5vcGVuKGNvbnRleHQpOworICB9CisKKyAgLyoqCisgICAqIERlbGV0ZXMgdGhlIGZpbGUgZGVub3RlZCBieSB7QGNvZGUgdXJpfS4KKyAgICoKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgZmlsZSBjb3VsZCBub3QgYmUgZGVsZXRlZCBmb3IgYW55IHJlYXNvbgorICAgKi8KKyAgcHVibGljIHZvaWQgZGVsZXRlRmlsZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIE9wZW5Db250ZXh0IGNvbnRleHQgPSBnZXRDb250ZXh0KHVyaSk7CisgICAgY29udGV4dC5iYWNrZW5kKCkuZGVsZXRlRmlsZShjb250ZXh0LmVuY29kZWRVcmkoKSk7CisgIH0KKworICAvKioKKyAgICogRGVsZXRlcyB0aGUgZGlyZWN0b3J5IGRlbm90ZWQgYnkge0Bjb2RlIHVyaX0uIFRoZSBkaXJlY3RvcnkgbXVzdCBiZSBlbXB0eSBpbiBvcmRlciB0byBiZQorICAgKiBkZWxldGVkLgorICAgKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBkaXJlY3RvcnkgY291bGQgbm90IGJlIGRlbGV0ZWQgZm9yIGFueSByZWFzb24KKyAgICovCisgIHB1YmxpYyB2b2lkIGRlbGV0ZURpcmVjdG9yeShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJhY2tlbmQgYmFja2VuZCA9IGdldEJhY2tlbmQodXJpLmdldFNjaGVtZSgpKTsKKyAgICBiYWNrZW5kLmRlbGV0ZURpcmVjdG9yeShzdHJpcEZyYWdtZW50KHVyaSkpOworICB9CisKKyAgLyoqCisgICAqIERlbGV0ZSBhIGZpbGUgb3IgZGlyZWN0b3J5IGFuZCBhbGwgaXRzIGNvbnRlbnRzIGF0IGEgc3BlY2lmaWVkIGxvY2F0aW9uLgorICAgKgorICAgKiBAcGFyYW0gdXJpIHRoZSBsb2NhdGlvbiB0byBkZWxldGUKKyAgICogQHJldHVybiB0cnVlIGlmIGFuZCBvbmx5IGlmIHRoZSBmaWxlIG9yIGRpcmVjdG9yeSBzcGVjaWZpZWQgYXQge0Bjb2RlIHVyaX0gd2FzIGRlbGV0ZWQuCisgICAqLworICBARGVwcmVjYXRlZCAvLyBzZWUge0BsaW5rCisgIC8vIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWN1cnNpdmVEZWxldGVPcGVuZXJ9CisgIHB1YmxpYyBib29sZWFuIGRlbGV0ZVJlY3Vyc2l2ZWx5KFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKCFleGlzdHModXJpKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoIWlzRGlyZWN0b3J5KHVyaSkpIHsKKyAgICAgIGRlbGV0ZUZpbGUodXJpKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICBmb3IgKFVyaSBjaGlsZCA6IGNoaWxkcmVuKHVyaSkpIHsKKyAgICAgIGRlbGV0ZVJlY3Vyc2l2ZWx5KGNoaWxkKTsKKyAgICB9CisgICAgZGVsZXRlRGlyZWN0b3J5KHVyaSk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKioKKyAgICogVGVsbHMgd2hldGhlciB0aGlzIGZpbGUgb3IgZGlyZWN0b3J5IGV4aXN0cy4KKyAgICoKKyAgICogPHA+VGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgdXJpIHBhdGggaXMgaW50ZXJwcmV0ZWQgYXMgYSBmaWxlIG5hbWUgYW5kIG1heSBiZSBlbmNvZGVkIGJ5IGEKKyAgICogdHJhbnNmb3JtLiBDYWxsZXJzIHNob3VsZCBjb25zaWRlciB1c2luZyB7QGxpbmsgI2lzRGlyZWN0b3J5fSwgc3RyaXBwaW5nIGZyYWdtZW50cywgb3IgYWRkaW5nIGEKKyAgICogdHJhaWxpbmcgc2xhc2ggdG8gYXZvaWQgYWNjaWRlbnRhbGx5IGVuY29kaW5nIGEgZGlyZWN0b3J5IG5hbWUuCisgICAqCisgICAqIEBwYXJhbSB1cmkKKyAgICogQHJldHVybiB0aGUgc3VjY2VzcyB2YWx1ZSBvZiB0aGUgb3BlcmF0aW9uLgorICAgKi8KKyAgQENoZWNrUmV0dXJuVmFsdWUKKyAgcHVibGljIGJvb2xlYW4gZXhpc3RzKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgT3BlbkNvbnRleHQgY29udGV4dCA9IGdldENvbnRleHQodXJpKTsKKyAgICByZXR1cm4gY29udGV4dC5iYWNrZW5kKCkuZXhpc3RzKGNvbnRleHQuZW5jb2RlZFVyaSgpKTsKKyAgfQorCisgIC8qKgorICAgKiBUZWxscyB3aGV0aGVyIHRoaXMgdXJpIHJlZmVycyB0byBhIGRpcmVjdG9yeS4KKyAgICoKKyAgICogQHBhcmFtIHVyaQorICAgKiBAcmV0dXJuIHRoZSBzdWNjZXNzIHZhbHVlIG9mIHRoZSBvcGVyYXRpb24uCisgICAqLworICBAQ2hlY2tSZXR1cm5WYWx1ZQorICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJhY2tlbmQgYmFja2VuZCA9IGdldEJhY2tlbmQodXJpLmdldFNjaGVtZSgpKTsKKyAgICByZXR1cm4gYmFja2VuZC5pc0RpcmVjdG9yeShzdHJpcEZyYWdtZW50KHVyaSkpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBuZXcgZGlyZWN0b3J5LiBBbnkgbm9uLWV4aXN0ZW50IHBhcmVudCBkaXJlY3RvcmllcyB3aWxsIGFsc28gYmUgY3JlYXRlZC4KKyAgICoKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgZGlyZWN0b3J5IGNvdWxkIG5vdCBiZSBjcmVhdGVkIGZvciBhbnkgcmVhc29uCisgICAqLworICBwdWJsaWMgdm9pZCBjcmVhdGVEaXJlY3RvcnkoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCYWNrZW5kIGJhY2tlbmQgPSBnZXRCYWNrZW5kKHVyaS5nZXRTY2hlbWUoKSk7CisgICAgYmFja2VuZC5jcmVhdGVEaXJlY3Rvcnkoc3RyaXBGcmFnbWVudCh1cmkpKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHRoZSBmaWxlIHNpemUuCisgICAqCisgICAqIDxwPklmIHRoZSB1cmkgcmVmZXJzIHRvIGEgZGlyZWN0b3J5IG9yIG5vbi1leGlzdGVudCwgcmV0dXJucyAwLgorICAgKgorICAgKiBAcGFyYW0gdXJpCisgICAqIEByZXR1cm4gdGhlIHNpemUgaW4gYnl0ZXMgb2YgdGhlIGZpbGUuCisgICAqLworICBAQ2hlY2tSZXR1cm5WYWx1ZQorICBwdWJsaWMgbG9uZyBmaWxlU2l6ZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIE9wZW5Db250ZXh0IGNvbnRleHQgPSBnZXRDb250ZXh0KHVyaSk7CisgICAgcmV0dXJuIGNvbnRleHQuYmFja2VuZCgpLmZpbGVTaXplKGNvbnRleHQuZW5jb2RlZFVyaSgpKTsKKyAgfQorCisgIC8qKgorICAgKiBSZW5hbWVzIHRoZSBmaWxlIG9yIGRpcmVjdG9yeSBmcm9tIG9uZSBsb2NhdGlvbiB0byBhbm90aGVyLiBUaGlzIGNhbiBvbmx5IGJlIHBlcmZvcm1lZCBpZiB0aGUKKyAgICogc2NoZW1lcyBvZiB0aGUgVXJpcyBtYXAgdG8gdGhlIHNhbWUgYmFja2VuZCBpbnN0YW5jZS4KKyAgICoKKyAgICogPHA+VGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgdXJpIHBhdGggaXMgaW50ZXJwcmV0ZWQgYXMgYSBmaWxlIG5hbWUgYW5kIG1heSBiZSBlbmNvZGVkIGJ5IGEKKyAgICogdHJhbnNmb3JtLiBDYWxsZXJzIHNob3VsZCBlbnN1cmUgYSB0cmFpbGluZyBzbGFzaCBpcyBpbmNsdWRlZCBmb3IgZGlyZWN0b3J5IG5hbWVzIG9yIHN0cmlwCisgICAqIHRyYW5zZm9ybXMgdG8gYXZvaWQgYWNjaWRlbnRhbGx5IGVuY29kaW5nIGEgZGlyZWN0b3J5IG5hbWUuCisgICAqCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gaWYgdGhlIGZpbGUgY291bGQgbm90IGJlIHJlbmFtZWQgZm9yIGFueSByZWFzb24KKyAgICovCisgIHB1YmxpYyB2b2lkIHJlbmFtZShVcmkgZnJvbSwgVXJpIHRvKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIE9wZW5Db250ZXh0IGZyb21Db250ZXh0ID0gZ2V0Q29udGV4dChmcm9tKTsKKyAgICBPcGVuQ29udGV4dCB0b0NvbnRleHQgPSBnZXRDb250ZXh0KHRvKTsKKyAgICAvLyBFdmVuIGlmIGl0J3MgdGhlIHNhbWUgcHJvdmlkZXIsIHJlcXVpcmUgdGhhdCB0aGUgYmFja2VuZCBpbnN0YW5jZXMgYmUgdGhlIHNhbWUKKyAgICAvLyBmb3IgYSByZW5hbWUgb3BlcmF0aW9uLiAoQ2FuIG1ha2UgbGVzcyByZXN0cmljdGl2ZSBpZiBuZWNlc3NhcnkuKQorICAgIGlmIChmcm9tQ29udGV4dC5iYWNrZW5kKCkgIT0gdG9Db250ZXh0LmJhY2tlbmQoKSkgeworICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oIkNhbm5vdCByZW5hbWUgZmlsZSBhY3Jvc3MgYmFja2VuZHMiKTsKKyAgICB9CisgICAgZnJvbUNvbnRleHQuYmFja2VuZCgpLnJlbmFtZShmcm9tQ29udGV4dC5lbmNvZGVkVXJpKCksIHRvQ29udGV4dC5lbmNvZGVkVXJpKCkpOworICB9CisKKyAgLyoqCisgICAqIExpc3RzIGNoaWxkcmVuIG9mIGEgcGFyZW50IGRpcmVjdG9yeSBVcmkuCisgICAqCisgICAqIEBwYXJhbSBwYXJlbnRVcmkgVGhlIHBhcmVudCBkaXJlY3RvcnkgdG8gbGlzdC4KKyAgICogQHJldHVybiB0aGUgbGlzdCBvZiBjaGlsZHJlbi4KKyAgICovCisgIEBDaGVja1JldHVyblZhbHVlCisgIHB1YmxpYyBJdGVyYWJsZTxVcmk+IGNoaWxkcmVuKFVyaSBwYXJlbnRVcmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQmFja2VuZCBiYWNrZW5kID0gZ2V0QmFja2VuZChwYXJlbnRVcmkuZ2V0U2NoZW1lKCkpOworICAgIExpc3Q8VHJhbnNmb3JtPiBlbmFibGVkVHJhbnNmb3JtcyA9IGdldEVuYWJsZWRUcmFuc2Zvcm1zKHBhcmVudFVyaSk7CisgICAgTGlzdDxVcmk+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8VXJpPigpOworICAgIFN0cmluZyBlbmNvZGVkRnJhZ21lbnQgPSBwYXJlbnRVcmkuZ2V0RW5jb2RlZEZyYWdtZW50KCk7CisgICAgZm9yIChVcmkgY2hpbGQgOiBiYWNrZW5kLmNoaWxkcmVuKHN0cmlwRnJhZ21lbnQocGFyZW50VXJpKSkpIHsKKyAgICAgIFVyaSBkZWNvZGVkQ2hpbGQgPQorICAgICAgICAgIGRlY29kZUZpbGVuYW1lKAorICAgICAgICAgICAgICBlbmFibGVkVHJhbnNmb3JtcywgY2hpbGQuYnVpbGRVcG9uKCkuZW5jb2RlZEZyYWdtZW50KGVuY29kZWRGcmFnbWVudCkuYnVpbGQoKSk7CisgICAgICByZXN1bHQuYWRkKGRlY29kZWRDaGlsZCk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKiogUmV0cmlldmVzIHRoZSB7QGxpbmsgR2NQYXJhbX0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBVUkkuICovCisgIHB1YmxpYyBHY1BhcmFtIGdldEdjUGFyYW0oVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBPcGVuQ29udGV4dCBjb250ZXh0ID0gZ2V0Q29udGV4dCh1cmkpOworICAgIHJldHVybiBjb250ZXh0LmJhY2tlbmQoKS5nZXRHY1BhcmFtKGNvbnRleHQuZW5jb2RlZFVyaSgpKTsKKyAgfQorCisgIC8qKiBTZXRzIHRoZSB7QGxpbmsgR2NQYXJhbX0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBVUkkuICovCisgIHB1YmxpYyB2b2lkIHNldEdjUGFyYW0oVXJpIHVyaSwgR2NQYXJhbSBwYXJhbSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBPcGVuQ29udGV4dCBjb250ZXh0ID0gZ2V0Q29udGV4dCh1cmkpOworICAgIGNvbnRleHQuYmFja2VuZCgpLnNldEdjUGFyYW0oY29udGV4dC5lbmNvZGVkVXJpKCksIHBhcmFtKTsKKyAgfQorCisgIHByaXZhdGUgT3BlbkNvbnRleHQgZ2V0Q29udGV4dChVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIExpc3Q8VHJhbnNmb3JtPiBlbmFibGVkVHJhbnNmb3JtcyA9IGdldEVuYWJsZWRUcmFuc2Zvcm1zKHVyaSk7CisgICAgcmV0dXJuIE9wZW5Db250ZXh0LmJ1aWxkZXIoKQorICAgICAgICAuc2V0U3RvcmFnZSh0aGlzKQorICAgICAgICAuc2V0QmFja2VuZChnZXRCYWNrZW5kKHVyaS5nZXRTY2hlbWUoKSkpCisgICAgICAgIC5zZXRNb25pdG9ycyhtb25pdG9ycykKKyAgICAgICAgLnNldFRyYW5zZm9ybXMoZW5hYmxlZFRyYW5zZm9ybXMpCisgICAgICAgIC5zZXRPcmlnaW5hbFVyaSh1cmkpCisgICAgICAgIC5zZXRFbmNvZGVkVXJpKGVuY29kZUZpbGVuYW1lKGVuYWJsZWRUcmFuc2Zvcm1zLCB1cmkpKQorICAgICAgICAuYnVpbGQoKTsKKyAgfQorCisgIHByaXZhdGUgQmFja2VuZCBnZXRCYWNrZW5kKFN0cmluZyBzY2hlbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQmFja2VuZCBiYWNrZW5kID0gYmFja2VuZHMuZ2V0KHNjaGVtZSk7CisgICAgaWYgKGJhY2tlbmQgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oCisgICAgICAgICAgU3RyaW5nLmZvcm1hdCgiQ2Fubm90IG9wZW4sIHVucmVnaXN0ZXJlZCBiYWNrZW5kOiAlcyIsIHNjaGVtZSkpOworICAgIH0KKyAgICByZXR1cm4gYmFja2VuZDsKKyAgfQorCisgIHByaXZhdGUgSW1tdXRhYmxlTGlzdDxUcmFuc2Zvcm0+IGdldEVuYWJsZWRUcmFuc2Zvcm1zKFVyaSB1cmkpCisgICAgICB0aHJvd3MgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbiB7CisgICAgSW1tdXRhYmxlTGlzdC5CdWlsZGVyPFRyYW5zZm9ybT4gYnVpbGRlciA9IEltbXV0YWJsZUxpc3QuYnVpbGRlcigpOworICAgIGZvciAoU3RyaW5nIG5hbWUgOiBMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLnBhcnNlVHJhbnNmb3JtTmFtZXModXJpKSkgeworICAgICAgVHJhbnNmb3JtIHRyYW5zZm9ybSA9IHRyYW5zZm9ybXMuZ2V0KG5hbWUpOworICAgICAgaWYgKHRyYW5zZm9ybSA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJObyBzdWNoIHRyYW5zZm9ybTogIiArIG5hbWUgKyAiOiAiICsgdXJpKTsKKyAgICAgIH0KKyAgICAgIGJ1aWxkZXIuYWRkKHRyYW5zZm9ybSk7CisgICAgfQorICAgIHJldHVybiBidWlsZGVyLmJ1aWxkKCkucmV2ZXJzZSgpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVXJpIHN0cmlwRnJhZ21lbnQoVXJpIHVyaSkgeworICAgIHJldHVybiB1cmkuYnVpbGRVcG9uKCkuZnJhZ21lbnQobnVsbCkuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBHaXZlIHRyYW5zZm9ybXMgdGhlIG9wcG9ydHVuaXR5IHRvIGVuY29kZSB0aGUgZmlsZSBwYXJ0IChsYXN0IHNlZ21lbnQgZm9yIGZpbGUgb3BlcmF0aW9ucykgb2YKKyAgICogdGhlIHVyaS4gQWxzbyBzdHJpcHMgZnJhZ21lbnQuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVcmkgZW5jb2RlRmlsZW5hbWUoTGlzdDxUcmFuc2Zvcm0+IHRyYW5zZm9ybXMsIFVyaSB1cmkpIHsKKyAgICBpZiAodHJhbnNmb3Jtcy5pc0VtcHR5KCkpIHsKKyAgICAgIHJldHVybiB1cmk7CisgICAgfQorICAgIExpc3Q8U3RyaW5nPiBzZWdtZW50cyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPih1cmkuZ2V0UGF0aFNlZ21lbnRzKCkpOworICAgIC8vIFRoaXMgVXJpIGltcGxlbWVudGF0aW9uJ3MgZ2V0UGF0aFNlZ21lbnRzKCkgaWdub3JlcyB0cmFpbGluZyAiLyIuCisgICAgaWYgKHNlZ21lbnRzLmlzRW1wdHkoKSB8fCB1cmkuZ2V0UGF0aCgpLmVuZHNXaXRoKCIvIikpIHsKKyAgICAgIHJldHVybiB1cmk7CisgICAgfQorICAgIFN0cmluZyBmaWxlbmFtZSA9IHNlZ21lbnRzLmdldChzZWdtZW50cy5zaXplKCkgLSAxKTsKKyAgICAvLyBSZXZlcnNlIHRyYW5zZm9ybXMsIHJlc3RvcmluZyB0aGVpciBvcmlnaW5hbCBvcmRlci4gKEluIGFsbCBvdGhlciBwbGFjZXMgdGhlIHJldmVyc2Ugb3JkZXIKKyAgICAvLyBpcyBtb3JlIGNvbnZlbmllbnQuKQorICAgIGZvciAoTGlzdEl0ZXJhdG9yPFRyYW5zZm9ybT4gaXRlciA9IHRyYW5zZm9ybXMubGlzdEl0ZXJhdG9yKHRyYW5zZm9ybXMuc2l6ZSgpKTsKKyAgICAgICAgaXRlci5oYXNQcmV2aW91cygpOyApIHsKKyAgICAgIFRyYW5zZm9ybSB0cmFuc2Zvcm0gPSBpdGVyLnByZXZpb3VzKCk7CisgICAgICBmaWxlbmFtZSA9IHRyYW5zZm9ybS5lbmNvZGUodXJpLCBmaWxlbmFtZSk7CisgICAgfQorICAgIHNlZ21lbnRzLnNldChzZWdtZW50cy5zaXplKCkgLSAxLCBmaWxlbmFtZSk7CisgICAgcmV0dXJuIHVyaS5idWlsZFVwb24oKS5wYXRoKFRleHRVdGlscy5qb2luKCIvIiwgc2VnbWVudHMpKS5lbmNvZGVkRnJhZ21lbnQobnVsbCkuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBHaXZlIHRyYW5zZm9ybXMgdGhlIG9wcG9ydHVuaXR5IHRvIGRlY29kZSB0aGUgZmlsZSBwYXJ0IChsYXN0IHNlZ21lbnQgZm9yIGZpbGUgb3BlcmF0aW9ucykgb2YKKyAgICogdGhlIHVyaS4gUmV2ZXJzZXMgZW5jb2RlRmlsZW5hbWUoKS4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFVyaSBkZWNvZGVGaWxlbmFtZShMaXN0PFRyYW5zZm9ybT4gdHJhbnNmb3JtcywgVXJpIHVyaSkgeworICAgIGlmICh0cmFuc2Zvcm1zLmlzRW1wdHkoKSkgeworICAgICAgcmV0dXJuIHVyaTsKKyAgICB9CisgICAgTGlzdDxTdHJpbmc+IHNlZ21lbnRzID0gbmV3IEFycmF5TGlzdDxTdHJpbmc+KHVyaS5nZXRQYXRoU2VnbWVudHMoKSk7CisgICAgLy8gVGhpcyBVcmkgaW1wbGVtZW50YXRpb24ncyBnZXRQYXRoU2VnbWVudHMoKSBpZ25vcmVzIHRyYWlsaW5nICIvIi4KKyAgICBpZiAoc2VnbWVudHMuaXNFbXB0eSgpIHx8IHVyaS5nZXRQYXRoKCkuZW5kc1dpdGgoIi8iKSkgeworICAgICAgcmV0dXJuIHVyaTsKKyAgICB9CisgICAgU3RyaW5nIGZpbGVuYW1lID0gSXRlcmFibGVzLmdldExhc3Qoc2VnbWVudHMpOworICAgIGZvciAoVHJhbnNmb3JtIHRyYW5zZm9ybSA6IHRyYW5zZm9ybXMpIHsKKyAgICAgIGZpbGVuYW1lID0gdHJhbnNmb3JtLmRlY29kZSh1cmksIGZpbGVuYW1lKTsKKyAgICB9CisgICAgc2VnbWVudHMuc2V0KHNlZ21lbnRzLnNpemUoKSAtIDEsIGZpbGVuYW1lKTsKKyAgICByZXR1cm4gdXJpLmJ1aWxkVXBvbigpLnBhdGgoVGV4dFV0aWxzLmpvaW4oIi8iLCBzZWdtZW50cykpLmJ1aWxkKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BY2NvdW50TWFuYWdlci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FjY291bnRNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjZlMzIyNgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BY2NvdW50TWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsMzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBhbmRyb2lkLmFjY291bnRzLkFjY291bnQ7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CisKKy8qKiBIZWxwZXIgZm9yIFVyaSBjbGFzc2VzIHRvIG1hbmFnZSBBbmRyb2lkIGFjY291bnRzLiAqLworcHVibGljIGludGVyZmFjZSBBY2NvdW50TWFuYWdlciB7CisKKyAgLyoqCisgICAqIFJldHVybnMgdGhlIElEIGFzc29jaWF0ZWQgd2l0aCB7QGNvZGUgYWNjb3VudH0sIG9yIGFzc2lnbnMgYW5kIHJldHVybnMgYSBuZXcgaWQgaWYgdGhlIGFjY291bnQKKyAgICogaXMgdW5yZWNvZ25pemVkLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxJbnRlZ2VyPiBnZXRBY2NvdW50SWQoQWNjb3VudCBhY2NvdW50KTsKKworICAvKiogUmV0dXJucyB0aGUgYWNjb3VudCBhc3NvY2lhdGVkIHdpdGgge0Bjb2RlIGFjY291bnRJZH0sIG9yIGZhaWxzIGlmIHRoZSBpZCBpcyB1bnJlY29nbml6ZWQuICovCisgIExpc3RlbmFibGVGdXR1cmU8QWNjb3VudD4gZ2V0QWNjb3VudChpbnQgYWNjb3VudElkKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BY2NvdW50U2VyaWFsaXphdGlvbi5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FjY291bnRTZXJpYWxpemF0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODU2NmRkZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BY2NvdW50U2VyaWFsaXphdGlvbi5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBhbmRyb2lkLmFjY291bnRzLkFjY291bnQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuUHJlY29uZGl0aW9uczsKKworLyoqIEhlbHBlciBmb3IgVXJpIGNsYXNzZXMgdG8gc2VyaWFsaXplIEFuZHJvaWQgYWNjb3VudHMuICovCitwdWJsaWMgZmluYWwgY2xhc3MgQWNjb3VudFNlcmlhbGl6YXRpb24geworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTSEFSRURfQUNDT1VOVF9TVFIgPSAic2hhcmVkIjsKKworICAvKiogQSBjb21tb24ge0BsaW5rIEFjY291bnR9IHdpdGggbm8gYXNzb2NpYXRlZCB1c2VyOyBpdCBhcHBlYXJzIGFzICJzaGFyZWQiIG9uIHRoZSBmaWxlc3lzdGVtLiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIEFjY291bnQgU0hBUkVEX0FDQ09VTlQgPSBuZXcgQWNjb3VudChTSEFSRURfQUNDT1VOVF9TVFIsICJtb2JzdG9yZSIpOworCisgIC8qKgorICAgKiBWYWxpZGF0ZXMgYW5kIHNlcmlhbGl6ZXMgYW4ge0BsaW5rIEFjY291bnR9IGludG8gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gIjx0eXBlPjo8bmFtZT4iLCB3aXRoCisgICAqIHRoZSBleGNlcHRpb24gb2Yge0BsaW5rICNTSEFSRURfQUNDT1VOVH0gd2hpY2ggaXMgc2VyaWFsaXplZCBhcyB7QGxpbmsgI1NIQVJFRF9BQ0NPVU5UX1NUUn0uCisgICAqCisgICAqIDxwPlRoZSBhY2NvdW50IHdpbGwgYmUgVVJMIGVuY29kZWQgaW4gaXRzIFVSSSByZXByZXNlbnRhdGlvbiAoc28sIGVnLCAiPGludGVybmFsPkBnbWFpbC5jb20iCisgICAqIHdpbGwgYXBwZWFyIGFzICJ5b3UlNDBnbWFpbC5jb20iKSwgYnV0IG5vdCBpbiB0aGUgZmlsZSBwYXRoIHJlcHJlc2VudGF0aW9uIHVzZWQgdG8gYWNjZXNzIGRpc2suCisgICAqIHtAbGluayAjU0hBUkVEX0FDQ09VTlR9IHNob3dzIHVwIGFzICJzaGFyZWQiIG9uIHRoZSBmaWxlc3lzdGVtLgorICAgKgorICAgKiA8cD5UaGlzIG1ldGhvZCBwZXJmb3JtcyBzb21lIGFjY291bnQgdmFsaWRhdGlvbi4gQW5kcm9pZCBBY2NvdW50IGl0c2VsZiByZXF1aXJlcyB0aGF0IGJvdGggdGhlCisgICAqIHR5cGUgYW5kIG5hbWUgZmllbGRzIGJlIHByZXNlbnQuIEluIGFkZGl0aW9uIHRvIHRoaXMgcmVxdWlyZW1lbnQsIHRoaXMgbWV0aG9kIHJlcXVpcmVzIHRoYXQgdGhlCisgICAqIHR5cGUgY29udGFpbiBubyBjb2xvbnMgKGFzIHRoZXNlIGFyZSB0aGUgZGVsaW1pdGVyIHVzZWQgaW50ZXJuYWxseSBmb3IgdGhlIGFjY291bnQKKyAgICogc2VyaWFsaXphdGlvbiksIGFuZCB0aGF0IG5laXRoZXIgdGhlIHR5cGUgbm9yIHRoZSBuYW1lIGluY2x1ZGUgYW55IHNsYXNoZXMgKGFzIHRoZXNlIGFyZSBmaWxlCisgICAqIHNlcGFyYXRvcnMpLgorICAgKgorICAgKiA8cD5Ob3RlIHRoZSBMaW51eCBmaWxlc3lzdGVtIGFjY2VwdHMgZmlsZW5hbWVzIGNvbXBvc2VkIG9mIGFueSBieXRlcyBleGNlcHQgIi8iIGFuZCBOVUxMLgorICAgKgorICAgKiBAdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgYWNjb3VudCBkb2VzIG5vdCBjb25mb3JtIHRvIHRoZSBzcGVjaWZpY2F0aW9ucyBhYm92ZQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgc2VyaWFsaXplKEFjY291bnQgYWNjb3VudCkgeworICAgIHZhbGlkYXRlKGFjY291bnQpOworICAgIGlmIChpc1NoYXJlZEFjY291bnQoYWNjb3VudCkpIHsKKyAgICAgIHJldHVybiBTSEFSRURfQUNDT1VOVF9TVFI7CisgICAgfQorICAgIHJldHVybiBhY2NvdW50LnR5cGUgKyAiOiIgKyBhY2NvdW50Lm5hbWU7CisgIH0KKworICAvKioKKyAgICogUGFyc2VzIGFuIGFjY291bnQgc3RyaW5nIGdlbmVyYXRlZCBieSB7QGxpbmsgI3NlcmlhbGl6ZX0gYmFjayBpbnRvIGFuIHtAbGluayBBY2NvdW50fSwgb3IKKyAgICogdGhyb3dzIHtAbGluayBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259IGlmIHtAY29kZSBhY2NvdW50U3RyfSBoYXMgYW4gdW5yZWNvZ25pemVkIGZvcm1hdC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQWNjb3VudCBkZXNlcmlhbGl6ZShTdHJpbmcgYWNjb3VudFN0cikgeworICAgIGlmIChpc1NoYXJlZEFjY291bnQoYWNjb3VudFN0cikpIHsKKyAgICAgIHJldHVybiBTSEFSRURfQUNDT1VOVDsKKyAgICB9CisgICAgaW50IGNvbG9uSWR4ID0gYWNjb3VudFN0ci5pbmRleE9mKCc6Jyk7CisgICAgUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KGNvbG9uSWR4ID4gLTEsICJNYWxmb3JtZWQgYWNjb3VudCIpOworICAgIFN0cmluZyB0eXBlID0gYWNjb3VudFN0ci5zdWJzdHJpbmcoMCwgY29sb25JZHgpOworICAgIFN0cmluZyBuYW1lID0gYWNjb3VudFN0ci5zdWJzdHJpbmcoY29sb25JZHggKyAxKTsKKyAgICByZXR1cm4gbmV3IEFjY291bnQobmFtZSwgdHlwZSk7CisgIH0KKworICBzdGF0aWMgYm9vbGVhbiBpc1NoYXJlZEFjY291bnQoU3RyaW5nIGFjY291bnRTdHIpIHsKKyAgICByZXR1cm4gU0hBUkVEX0FDQ09VTlRfU1RSLmVxdWFscyhhY2NvdW50U3RyKTsKKyAgfQorCisgIHN0YXRpYyBib29sZWFuIGlzU2hhcmVkQWNjb3VudChBY2NvdW50IGFjY291bnQpIHsKKyAgICByZXR1cm4gU0hBUkVEX0FDQ09VTlQuZXF1YWxzKGFjY291bnQpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB2YWxpZGF0ZShBY2NvdW50IGFjY291bnQpIHsKKyAgICAvLyBBbmRyb2lkIEFjY291bnQgYWxyZWFkeSB2YWxpZGF0ZXMgdGhhdCBuYW1lIGFuZCB0eXBlIGFyZSBub3QgZW1wdHkuCisgICAgUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KGFjY291bnQudHlwZS5pbmRleE9mKCc6JykgPT0gLTEsICJBY2NvdW50IHR5cGUgY29udGFpbnMgJzonLiIpOworICAgIFByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChhY2NvdW50LnR5cGUuaW5kZXhPZignLycpID09IC0xLCAiQWNjb3VudCB0eXBlIGNvbnRhaW5zICcvJy4iKTsKKyAgICBQcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoYWNjb3VudC5uYW1lLmluZGV4T2YoJy8nKSA9PSAtMSwgIkFjY291bnQgbmFtZSBjb250YWlucyAnLycuIik7CisgIH0KKworICBwcml2YXRlIEFjY291bnRTZXJpYWxpemF0aW9uKCkge30KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BbmRyb2lkRmlsZUJhY2tlbmQuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BbmRyb2lkRmlsZUJhY2tlbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMWQ4YjlkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FuZHJvaWRGaWxlQmFja2VuZC5qYXZhCkBAIC0wLDAgKzEsMjY4IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgYW5kcm9pZC5hbm5vdGF0aW9uLlRhcmdldEFwaTsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZDsKK2ltcG9ydCBhbmRyb2lkLnRleHQuVGV4dFV0aWxzOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGFuZHJvaWR4LmFubm90YXRpb24uVmlzaWJsZUZvclRlc3Rpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uRmlsZVN0b3JhZ2VVbmF2YWlsYWJsZUV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5Mb2NrU2NvcGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uTWFsZm9ybWVkVXJpRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLlByZWNvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5Gb3J3YXJkaW5nQmFja2VuZDsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5jb25jdXJyZW50Lkd1YXJkZWRCeTsKKworLyoqIEEgYmFja2VuZCB0aGF0IGltcGxlbWVudHMgImFuZHJvaWQ6IiBzY2hlbWUgdXNpbmcge0BsaW5rIEphdmFGaWxlQmFja2VuZH0uICovCitwdWJsaWMgZmluYWwgY2xhc3MgQW5kcm9pZEZpbGVCYWNrZW5kIGV4dGVuZHMgRm9yd2FyZGluZ0JhY2tlbmQgeworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIGZpbmFsIEJhY2tlbmQgYmFja2VuZDsKKyAgcHJpdmF0ZSBmaW5hbCBEaXJlY3RCb290Q2hlY2tlciBkaXJlY3RCb290Q2hlY2tlcjsKKyAgQE51bGxhYmxlIHByaXZhdGUgZmluYWwgQmFja2VuZCByZW1vdGVCYWNrZW5kOworICBATnVsbGFibGUgcHJpdmF0ZSBmaW5hbCBBY2NvdW50TWFuYWdlciBhY2NvdW50TWFuYWdlcjsKKworICBwcml2YXRlIGZpbmFsIE9iamVjdCBsb2NrID0gbmV3IE9iamVjdCgpOworCisgIEBHdWFyZGVkQnkoImxvY2siKQorICBATnVsbGFibGUKKyAgcHJpdmF0ZSBTdHJpbmcgbGF6eURwc0RhdGFEaXJQYXRoOyAvLyBJbml0aWFsaXplZCBhbmQgYWNjZXNzZWQgdmlhIGdldERwc0RhdGFEaXJQYXRoKCkKKworICAvKioKKyAgICogUmV0dXJucyBhbiB7QGxpbmsgQW5kcm9pZEZpbGVCYWNrZW5kfSBidWlsZGVyIGZvciB0aGUgY2FsbGluZyB7QGNvZGUgY29udGV4dH0uIE1vc3Qgb3B0aW9ucyBhcmUKKyAgICogZGlzYWJsZWQgYnkgZGVmYXVsdDsgc2VlIGphdmFkb2MgaW4ge0BsaW5rIEJ1aWxkZXJ9IGZvciBmdXJ0aGVyIGNvbmZpZ3VyYXRpb24gZG9jdW1lbnRhdGlvbi4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBidWlsZGVyKENvbnRleHQgY29udGV4dCkgeworICAgIHJldHVybiBuZXcgQnVpbGRlcihjb250ZXh0KTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIGFuIHtAbGluayBBbmRyb2lkRmlsZUJhY2tlbmR9IHdpdGggdGhlIGN1c3RvbWl6ZWQge0Bjb2RlIGJhY2tlbmR9LiBTaG91bGQgb25seSBiZSB1c2VkCisgICAqIGluIHRlc3Qgd2hlcmUgYSBjdXN0b21pemVkIGJhY2tlbmQgaXMgbmVlZGVkIGZvciBzaW11bGF0aW5nIGZpbGUgb3BlcmF0aW9uIGZhaWx1cmVzIG9yIGRlbGF5cy4KKyAgICovCisgIEBWaXNpYmxlRm9yVGVzdGluZworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgYnVpbGRlcldpdGhPdmVycmlkZUZvclRlc3QoQ29udGV4dCBjb250ZXh0LCBCYWNrZW5kIGJhY2tlbmQpIHsKKyAgICBQcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoCisgICAgICAgIGJhY2tlbmQgIT0gbnVsbCwgIkNhbm5vdCBpbnZva2UgYnVpbGRlcldpdGhPdmVycmlkZUZvclRlc3Qgd2l0aCBudWxsIHN1cHBsaWVkIGFzIEJhY2tlbmQuIik7CisgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIoY29udGV4dCk7CisgICAgYnVpbGRlci5iYWNrZW5kID0gYmFja2VuZDsKKyAgICByZXR1cm4gYnVpbGRlcjsKKyAgfQorCisgIC8qKiBCdWlsZGVyIGZvciB0aGUge0BsaW5rIEFuZHJvaWRGaWxlQmFja2VuZH0gY2xhc3MuICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciB7CisgICAgLy8gUmVxdWlyZWQgcGFyYW1ldGVycworICAgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworCisgICAgLy8gT3B0aW9uYWwgcGFyYW1ldGVycworICAgIEBOdWxsYWJsZSBwcml2YXRlIEJhY2tlbmQgcmVtb3RlQmFja2VuZDsKKyAgICBATnVsbGFibGUgcHJpdmF0ZSBBY2NvdW50TWFuYWdlciBhY2NvdW50TWFuYWdlcjsKKyAgICBATnVsbGFibGUgcHJpdmF0ZSBCYWNrZW5kIGJhY2tlbmQ7CisgICAgcHJpdmF0ZSBMb2NrU2NvcGUgbG9ja1Njb3BlID0gbmV3IExvY2tTY29wZSgpOworCisgICAgcHJpdmF0ZSBCdWlsZGVyKENvbnRleHQgY29udGV4dCkgeworICAgICAgUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KGNvbnRleHQgIT0gbnVsbCwgIkNvbnRleHQgY2Fubm90IGJlIG51bGwiKTsKKyAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcmVtb3RlIGJhY2tlbmQgdGhhdCBpcyBpbnZva2VkIHdoZW4gdGhlIFVSSSdzIGF1dGhvcml0eSByZWZlcnMgdG8gYSBwYWNrYWdlIG90aGVyCisgICAgICogdGhhbiB5b3VyIG93bi4gVGhlIG9ubHkgbWV0aG9kcyBjYWxsZWQgb24ge0Bjb2RlIHJlbW90ZUJhY2tlbmR9IGFyZSB7QGxpbmsgI29wZW5Gb3JSZWFkfSBhbmQKKyAgICAgKiB7QGxpbmsgI29wZW5Gb3JOYXRpdmVSZWFkfSwgdGhvdWdoIHRoaXMgbWF5IGV4cGFuZCBpbiB0aGUgZnV0dXJlLiBEZWZhdWx0cyB0byB7QGNvZGUgbnVsbH0uCisgICAgICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVtb3RlQmFja2VuZChCYWNrZW5kIHJlbW90ZUJhY2tlbmQpIHsKKyAgICAgIHRoaXMucmVtb3RlQmFja2VuZCA9IHJlbW90ZUJhY2tlbmQ7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSB7QGxpbmsgQWNjb3VudE1hbmFnZXJ9IGludm9rZWQgdG8gcmVzb2x2ZSAibWFuYWdlZCIgVVJJcy4gRGVmYXVsdHMgdG8ge0Bjb2RlIG51bGx9LAorICAgICAqIGluIHdoaWNoIGNhc2Ugb3BlcmF0aW9ucyBvbiAibWFuYWdlZCIgVVJJcyB3aWxsIGZhaWwuCisgICAgICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0QWNjb3VudE1hbmFnZXIoQWNjb3VudE1hbmFnZXIgYWNjb3VudE1hbmFnZXIpIHsKKyAgICAgIHRoaXMuYWNjb3VudE1hbmFnZXIgPSBhY2NvdW50TWFuYWdlcjsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIE92ZXJyaWRlcyB0aGUgZGVmYXVsdCBiYWNrZW5kLXNjb3BlZCB7QGxpbmsgTG9ja1Njb3BlfSB3aXRoIHRoZSBnaXZlbiB7QGNvZGUgbG9ja1Njb3BlfS4gVGhpcworICAgICAqIGluamVjdGlvbiBpcyBvbmx5IG5lY2Vzc2FyeSBpZiB0aGVyZSBhcmUgbXVsdGlwbGUgYmFja2VuZCBpbnN0YW5jZXMgaW4gdGhlIHNhbWUgcHJvY2VzcyBhbmQKKyAgICAgKiB0aGVyZSdzIGEgcmlzayBvZiB0aGVtIGFjcXVpcmluZyBhIGxvY2sgb24gdGhlIHNhbWUgdW5kZXJseWluZyBmaWxlLgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIHNldExvY2tTY29wZShMb2NrU2NvcGUgbG9ja1Njb3BlKSB7CisgICAgICBQcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoCisgICAgICAgICAgYmFja2VuZCA9PSBudWxsLAorICAgICAgICAgICJMb2NrU2NvcGUgd2lsbCBub3QgYmUgdXNlZCBpbiB0aGUgY3VzdG9tIGJhY2tlbmQuIE9ubHkgY2FsbCBidWlsZGVyV2l0aE92ZXJyaWRlRm9yVGVzdCIKKyAgICAgICAgICAgICAgKyAiIGlmIHlvdSB3YW50IHRvIG92ZXJyaWRlIHRoZSBiYWNrZW5kIGZvciB0ZXN0aW5nLCBvciBjYWxsIGJ1aWxkZXIgdG9nZXRoZXIgd2l0aCIKKyAgICAgICAgICAgICAgKyAiIHNldExvY2tTY29wZSB0byBzZXQgYSBuZXcgbG9jayBzY29wZS4iKTsKKyAgICAgIHRoaXMubG9ja1Njb3BlID0gbG9ja1Njb3BlOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIEFuZHJvaWRGaWxlQmFja2VuZCBidWlsZCgpIHsKKyAgICAgIHJldHVybiBuZXcgQW5kcm9pZEZpbGVCYWNrZW5kKHRoaXMpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgQW5kcm9pZEZpbGVCYWNrZW5kKEJ1aWxkZXIgYnVpbGRlcikgeworICAgIGJhY2tlbmQgPSBidWlsZGVyLmJhY2tlbmQgIT0gbnVsbCA/IGJ1aWxkZXIuYmFja2VuZCA6IG5ldyBKYXZhRmlsZUJhY2tlbmQoYnVpbGRlci5sb2NrU2NvcGUpOworICAgIGNvbnRleHQgPSBidWlsZGVyLmNvbnRleHQ7CisgICAgcmVtb3RlQmFja2VuZCA9IGJ1aWxkZXIucmVtb3RlQmFja2VuZDsKKyAgICBhY2NvdW50TWFuYWdlciA9IGJ1aWxkZXIuYWNjb3VudE1hbmFnZXI7CisKKyAgICBkaXJlY3RCb290Q2hlY2tlciA9IHVudXNlZENvbnRleHQgLT4gdHJ1ZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgQmFja2VuZCBkZWxlZ2F0ZSgpIHsKKyAgICByZXR1cm4gYmFja2VuZDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIG5hbWUoKSB7CisgICAgcmV0dXJuICJhbmRyb2lkIjsKKyAgfQorCisgIC8qKgorICAgKiB7QGluaGVyaXREb2N9CisgICAqCisgICAqIDxwPlVSSSBtYXkgYmVsb25nIHRvIGEgZGlmZmVyZW50IGF1dGhvcml0eS4KKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgSW5wdXRTdHJlYW0gb3BlbkZvclJlYWQoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoaXNSZW1vdGVBdXRob3JpdHkodXJpKSkgeworICAgICAgdGhyb3dJZlJlbW90ZUJhY2tlbmRVbmF2YWlsYWJsZSgpOworICAgICAgcmV0dXJuIHJlbW90ZUJhY2tlbmQub3BlbkZvclJlYWQodXJpKTsKKyAgICB9CisgICAgcmV0dXJuIHN1cGVyLm9wZW5Gb3JSZWFkKHVyaSk7CisgIH0KKworICAvKioKKyAgICoge0Bpbmhlcml0RG9jfQorICAgKgorICAgKiA8cD5VUkkgbWF5IGJlbG9uZyB0byBhIGRpZmZlcmVudCBhdXRob3JpdHkuCisgICAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIFBhaXI8VXJpLCBDbG9zZWFibGU+IG9wZW5Gb3JOYXRpdmVSZWFkKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGlzUmVtb3RlQXV0aG9yaXR5KHVyaSkpIHsKKyAgICAgIHRocm93SWZSZW1vdGVCYWNrZW5kVW5hdmFpbGFibGUoKTsKKyAgICAgIHJldHVybiByZW1vdGVCYWNrZW5kLm9wZW5Gb3JOYXRpdmVSZWFkKHVyaSk7CisgICAgfQorICAgIHJldHVybiBzdXBlci5vcGVuRm9yTmF0aXZlUmVhZCh1cmkpOworICB9CisKKyAgLyoqCisgICAqIHtAaW5oZXJpdERvY30KKyAgICoKKyAgICogPHA+VVJJIG1heSBiZWxvbmcgdG8gYSBkaWZmZXJlbnQgYXV0aG9yaXR5LgorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGV4aXN0cyhVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChpc1JlbW90ZUF1dGhvcml0eSh1cmkpKSB7CisgICAgICB0aHJvd0lmUmVtb3RlQmFja2VuZFVuYXZhaWxhYmxlKCk7CisgICAgICByZXR1cm4gcmVtb3RlQmFja2VuZC5leGlzdHModXJpKTsKKyAgICB9CisgICAgcmV0dXJuIHN1cGVyLmV4aXN0cyh1cmkpOworICB9CisKKyAgcHJpdmF0ZSBib29sZWFuIGlzUmVtb3RlQXV0aG9yaXR5KFVyaSB1cmkpIHsKKyAgICByZXR1cm4gIVRleHRVdGlscy5pc0VtcHR5KHVyaS5nZXRBdXRob3JpdHkoKSkKKyAgICAgICAgJiYgIWNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKS5lcXVhbHModXJpLmdldEF1dGhvcml0eSgpKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB0aHJvd0lmUmVtb3RlVXJpKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGlzUmVtb3RlQXV0aG9yaXR5KHVyaSkpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigib3BlcmF0aW9uIGlzIG5vdCBwZXJtaXR0ZWQgaW4gb3RoZXIgYXV0aG9yaXRpZXMuIik7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIHRocm93SWZSZW1vdGVCYWNrZW5kVW5hdmFpbGFibGUoKSB0aHJvd3MgRmlsZVN0b3JhZ2VVbmF2YWlsYWJsZUV4Y2VwdGlvbiB7CisgICAgaWYgKHJlbW90ZUJhY2tlbmQgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IEZpbGVTdG9yYWdlVW5hdmFpbGFibGVFeGNlcHRpb24oCisgICAgICAgICAgIkFuZHJvaWQgYmFja2VuZCBjYW5ub3QgcGVyZm9ybSByZW1vdGUgb3BlcmF0aW9ucyB3aXRob3V0IGEgcmVtb3RlIGJhY2tlbmQiKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIFVyaSByZXdyaXRlVXJpKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gQ29udmVydHMgZnJvbSBhbmRyb2lkIC0+IGZpbGUKKyAgICBpZiAoaXNSZW1vdGVBdXRob3JpdHkodXJpKSkgeworICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbigiT3BlcmF0aW9uIGFjcm9zcyBhdXRob3JpdGllcyBpcyBub3QgYWxsb3dlZC4iKTsKKyAgICB9CisgICAgRmlsZSBmaWxlID0gdG9GaWxlKHVyaSk7CisgICAgVXJpIGZpbGVVcmkgPSBGaWxlVXJpLmJ1aWxkZXIoKS5mcm9tRmlsZShmaWxlKS5idWlsZCgpOworICAgIHJldHVybiBmaWxlVXJpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBVcmkgcmV2ZXJzZVJld3JpdGVVcmkoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBDb252ZXJ0cyBmcm9tIGZpbGUgLT4gYW5kcm9pZAorICAgIHRyeSB7CisgICAgICByZXR1cm4gQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLmZyb21BYnNvbHV0ZVBhdGgodXJpLmdldFBhdGgoKSwgYWNjb3VudE1hbmFnZXIpLmJ1aWxkKCk7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBGaWxlIHRvRmlsZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93SWZSZW1vdGVVcmkodXJpKTsKKyAgICBGaWxlIGZpbGUgPSBBbmRyb2lkVXJpQWRhcHRlci5mb3JDb250ZXh0KGNvbnRleHQsIGFjY291bnRNYW5hZ2VyKS50b0ZpbGUodXJpKTsKKyAgICB0aHJvd0lmU3RvcmFnZUlzTG9ja2VkKGZpbGUpOworICAgIHJldHVybiBmaWxlOworICB9CisKKyAgLyoqIFV0aWxpdGllcyBmb3IgaW50ZXJhY3Rpbmcgd2l0aCBBbmRyb2lkIERpcmVjdCBCb290IG1vZGUuICovCisgIHByaXZhdGUgaW50ZXJmYWNlIERpcmVjdEJvb3RDaGVja2VyIHsKKyAgICAvKiogUmV0dXJucyB0cnVlIGlmIHRoZSBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IGRpcmVjdCBib290IG9yIHRoZSB1c2VyIGlzIHVubG9ja2VkLiAqLworICAgIGJvb2xlYW4gaXNVc2VyVW5sb2NrZWQoQ29udGV4dCBjb250ZXh0KTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB0aHJvd0lmU3RvcmFnZUlzTG9ja2VkKEZpbGUgZmlsZSkgdGhyb3dzIEZpbGVTdG9yYWdlVW5hdmFpbGFibGVFeGNlcHRpb24geworICAgIC8vIElmIHRoZSBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IERpcmVjdEJvb3Qgb3IgaGFzIGJlZW4gdW5sb2NrZWQsIGFsbCBmaWxlcyBhcmUgYXZhaWxhYmxlLgorICAgIGlmIChkaXJlY3RCb290Q2hlY2tlci5pc1VzZXJVbmxvY2tlZChjb250ZXh0KSkgeworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIC8vIER1cmluZyBEaXJlY3RCb290LCBvbmx5IGZpbGVzIGluIGRldmljZS1wcm90ZWN0ZWQgc3RvcmFnZSBhcmUgYXZhaWxhYmxlLgorICAgIFN0cmluZyBkcHNEYXRhRGlyUGF0aCA9IGdldERwc0RhdGFEaXJQYXRoKCk7CisgICAgU3RyaW5nIGZpbGVQYXRoID0gZmlsZS5nZXRBYnNvbHV0ZVBhdGgoKTsKKyAgICBpZiAoIWZpbGVQYXRoLnN0YXJ0c1dpdGgoZHBzRGF0YURpclBhdGgpKSB7CisgICAgICB0aHJvdyBuZXcgRmlsZVN0b3JhZ2VVbmF2YWlsYWJsZUV4Y2VwdGlvbigKKyAgICAgICAgICAiQ2Fubm90IGFjY2VzcyBjcmVkZW50aWFsLXByb3RlY3RlZCBkYXRhIGZyb20gZGlyZWN0IGJvb3QiKTsKKyAgICB9CisgIH0KKworICBAVGFyZ2V0QXBpKEJ1aWxkLlZFUlNJT05fQ09ERVMuTikKKyAgcHJpdmF0ZSBTdHJpbmcgZ2V0RHBzRGF0YURpclBhdGgoKSB7CisgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICBpZiAobGF6eURwc0RhdGFEaXJQYXRoID09IG51bGwpIHsKKyAgICAgICAgRmlsZSBkcHNEYXRhRGlyID0gQW5kcm9pZEZpbGVFbnZpcm9ubWVudC5nZXREZXZpY2VQcm90ZWN0ZWREYXRhRGlyKGNvbnRleHQpOworICAgICAgICBsYXp5RHBzRGF0YURpclBhdGggPSBkcHNEYXRhRGlyLmdldEFic29sdXRlUGF0aCgpOworICAgICAgfQorICAgICAgcmV0dXJuIGxhenlEcHNEYXRhRGlyUGF0aDsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BbmRyb2lkRmlsZUVudmlyb25tZW50LmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQW5kcm9pZEZpbGVFbnZpcm9ubWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3NWFhZTIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQW5kcm9pZEZpbGVFbnZpcm9ubWVudC5qYXZhCkBAIC0wLDAgKzEsMjQxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgYW5kcm9pZC5hbm5vdGF0aW9uLlRhcmdldEFwaTsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkOworaW1wb3J0IGFuZHJvaWQub3MuRW52aXJvbm1lbnQ7CitpbXBvcnQgYW5kcm9pZC5vcy5TdGF0RnM7CitpbXBvcnQgYW5kcm9pZC5vcy5TeXN0ZW1DbG9jazsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogUHJvdmlkZXMgYWNjZXNzIHRvIGhpZ2gtbGV2ZWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIEFuZHJvaWQgZmlsZSBlbnZpcm9ubWVudC4gVGhlc2UgdXRpbGl0aWVzIGFyZQorICogbmVpdGhlciBpbnRlbmRlZCBub3IgYXZhaWxhYmxlIGZvciB1c2Ugb3V0c2lkZSBvZiB0aGUgTW9iU3RvcmUgbGlicmFyeSBpbXBsZW1lbnRhdGlvbi4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFuZHJvaWRGaWxlRW52aXJvbm1lbnQgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiQW5kcm9pZEZpbGVFbnZpcm9ubWVudCI7CisKKyAgLyoqIFJldHVybnMgYWxsIHtAY29kZSBkaXJzfSB0aGF0IGFyZSBjdXJyZW50bHkgbW91bnRlZCB3aXRoIGZ1bGwgcmVhZC93cml0ZSBhY2Nlc3MuICovCisgIHB1YmxpYyBzdGF0aWMgTGlzdDxGaWxlPiBnZXRNb3VudGVkRXh0ZXJuYWxEaXJzKExpc3Q8RmlsZT4gZGlycykgeworICAgIExpc3Q8RmlsZT4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgZm9yIChGaWxlIGRpciA6IGRpcnMpIHsKKyAgICAgIGlmIChkaXIgPT0gbnVsbCkgeworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIFN0cmluZyBzdGF0ZSA9IGdldFN0b3JhZ2VTdGF0ZShkaXIpOworICAgICAgaWYgKExvZy5pc0xvZ2dhYmxlKFRBRywgTG9nLkRFQlVHKSkgeworICAgICAgICBMb2cuZChUQUcsIFN0cmluZy5mb3JtYXQoIkV4dGVybmFsIHN0b3JhZ2U6IFslc10gaXMgWyVzXSIsIGRpci5nZXRBYnNvbHV0ZVBhdGgoKSwgc3RhdGUpKTsKKyAgICAgIH0KKyAgICAgIGlmIChFbnZpcm9ubWVudC5NRURJQV9NT1VOVEVELmVxdWFscyhzdGF0ZSkpIHsKKyAgICAgICAgcmVzdWx0LmFkZChkaXIpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHNoYXJlZC9leHRlcm5hbCBzdG9yYWdlIG1lZGlhIGF0IHRoZSBnaXZlbiBwYXRoLiBUaGlzIGlzIGEKKyAgICogcHJpdmF0ZSBBUEkgdG8gc3VwcG9ydCB7QGxpbmsgRW52aXJvbm1lbnQjZ2V0U3RvcmFnZVN0YXRlKEZpbGUpfSBhY3Jvc3MgYWxsIHNkayBsZXZlbHMuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0U3RvcmFnZVN0YXRlKEZpbGUgZGlyKSB7CisgICAgaWYgKEJ1aWxkLlZFUlNJT04uU0RLX0lOVCA+PSBCdWlsZC5WRVJTSU9OX0NPREVTLktJVEtBVCkgeworICAgICAgcmV0dXJuIGdldFN0b3JhZ2VTdGF0ZUtLKGRpcik7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBnZXRTdG9yYWdlU3RhdGVJQ1MoZGlyKTsKKyAgICB9CisgIH0KKworICAvKiogUHJpdmF0ZSBBUEkgdG8gc3VwcG9ydCB7QGxpbmsgI2dldFN0b3JhZ2VTdGF0ZX0gb24gc2RrIEtLIGFuZCBoaWdoZXIuICovCisgIEBUYXJnZXRBcGkoQnVpbGQuVkVSU0lPTl9DT0RFUy5LSVRLQVQpCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRTdG9yYWdlU3RhdGVLSyhGaWxlIGRpcikgeworICAgIHJldHVybiBFbnZpcm9ubWVudC5nZXRTdG9yYWdlU3RhdGUoZGlyKTsKKyAgfQorCisgIC8qKiBQcml2YXRlIEFQSSB0byBzdXBwb3J0IHtAbGluayAjZ2V0U3RvcmFnZVN0YXRlfSBvbiBsb3dlciBzZGsgbGV2ZWxzLiAqLworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0U3RvcmFnZVN0YXRlSUNTKEZpbGUgZGlyKSB7CisgICAgLy8gSW1wbGVtZW50YXRpb24gdGFrZW4gZGlyZWN0bHkgZnJvbSBFbnZpcm9ubWVudENvbXBhdCNnZXRTdG9yYWdlU3RhdGUuIE5vdGUgdGhhdCBKQiBhbmQgYmVsb3cKKyAgICAvLyBvbmx5IHN1cHBvcnQgb25lIGV4dGVybmFsIHN0b3JhZ2UgcGFydGl0aW9uLCB0aHVzIGNhbiBvbmx5IHJldHVybiBhIG1lYW5pbmdmdWwgdmFsdWUgZm9yIGEKKyAgICAvLyBkaXJlY3RvcnkgdW5kZXIgdGhhdCBwYXJ0aXRpb24uCisgICAgdHJ5IHsKKyAgICAgIFN0cmluZyBkaXJQYXRoID0gZGlyLmdldENhbm9uaWNhbFBhdGgoKTsKKyAgICAgIFN0cmluZyBleHRlcm5hbFBhdGggPSBFbnZpcm9ubWVudC5nZXRFeHRlcm5hbFN0b3JhZ2VEaXJlY3RvcnkoKS5nZXRDYW5vbmljYWxQYXRoKCk7CisgICAgICBpZiAoZGlyUGF0aC5zdGFydHNXaXRoKGV4dGVybmFsUGF0aCkpIHsKKyAgICAgICAgcmV0dXJuIEVudmlyb25tZW50LmdldEV4dGVybmFsU3RvcmFnZVN0YXRlKCk7CisgICAgICB9CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTG9nLncoVEFHLCAiRmFpbGVkIHRvIHJlc29sdmUgY2Fub25pY2FsIHBhdGgiLCBlKTsKKyAgICB9CisgICAgcmV0dXJuICJ1bmtub3duIjsgLy8gPT0gRW52aXJvbm1lbnQuTUVESUFfVU5LTk9XTiwgd2hpY2ggaXNuJ3QgYXZhaWxhYmxlIGJlbG93IEtLCisgIH0KKworICAvKioKKyAgICogUmV0dXJucyBhbGwgYXZhaWxhYmxlIG5vbi1lbXVsYXRlZCBleHRlcm5hbCBjYWNoZSBkaXJlY3Rvcmllcy4gVGhpcyBtZXRob2QgZG9lcyBub3QgZ3VhcmFudGVlCisgICAqIHRoYXQgdGhlIHJldHVybmVkIHBhdGhzIGFyZSBtb3VudGVkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBMaXN0PEZpbGU+IGdldE5vbkVtdWxhdGVkRXh0ZXJuYWxDYWNoZURpcnMoQ29udGV4dCBjb250ZXh0KSB7CisgICAgaWYgKEJ1aWxkLlZFUlNJT04uU0RLX0lOVCA+PSBCdWlsZC5WRVJTSU9OX0NPREVTLkxPTExJUE9QKSB7CisgICAgICByZXR1cm4gZ2V0Tm9uRW11bGF0ZWRFeHRlcm5hbENhY2hlRGlyc0xQKGNvbnRleHQpOworICAgIH0gZWxzZSBpZiAoQnVpbGQuVkVSU0lPTi5TREtfSU5UID49IEJ1aWxkLlZFUlNJT05fQ09ERVMuS0lUS0FUKSB7CisgICAgICByZXR1cm4gZ2V0Tm9uRW11bGF0ZWRFeHRlcm5hbENhY2hlRGlyc0tLKGNvbnRleHQpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gZ2V0Tm9uRW11bGF0ZWRFeHRlcm5hbENhY2hlRGlyc0lDUyhjb250ZXh0KTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUHJpdmF0ZSBBUEk7IHBsZWFzZSB1c2Uge0BsaW5rICNnZXROb25FbXVsYXRlZEV4dGVybmFsQ2FjaGVEaXJzfSBkaXJlY3RseS4gVGhpcyBpbXBsZW1lbnRhdGlvbgorICAgKiBvZiB7QGxpbmsgI2dldE5vbkVtdWxhdGVkRXh0ZXJuYWxDYWNoZURpcnN9IHVzZXMgdGhlIG5ldyBBUElzIGF2YWlsYWJsZSBvbiBMT0xMSVBPUCBhbmQgbGF0ZXIKKyAgICogaW4gb3JkZXIgdG8gcXVlcnkgZWFjaCBleHRlcm5hbCBzdG9yYWdlIHBhcnRpdGlvbiBmb3IgZW11bGF0aW9uLgorICAgKi8KKyAgQFRhcmdldEFwaShCdWlsZC5WRVJTSU9OX0NPREVTLkxPTExJUE9QKQorICBwcml2YXRlIHN0YXRpYyBMaXN0PEZpbGU+IGdldE5vbkVtdWxhdGVkRXh0ZXJuYWxDYWNoZURpcnNMUChDb250ZXh0IGNvbnRleHQpIHsKKyAgICBMaXN0PEZpbGU+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8PigpOworCisgICAgZm9yIChGaWxlIGRpciA6IEFycmF5cy5hc0xpc3QoY29udGV4dC5nZXRFeHRlcm5hbENhY2hlRGlycygpKSkgeworICAgICAgdHJ5IHsKKyAgICAgICAgaWYgKGRpciAhPSBudWxsICYmICFFbnZpcm9ubWVudC5pc0V4dGVybmFsU3RvcmFnZUVtdWxhdGVkKGRpcikpIHsKKyAgICAgICAgICByZXN1bHQuYWRkKGRpcik7CisgICAgICAgIH0KKyAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIE5PVEU6IG9uIHNvbWUgZGV2aWNlcyBhbmQgQVBJIGxldmVscywgRW52aXJvbm1lbnQuaXNFeHRlcm5hbFN0b3JhZ2VFbXVsYXRlZChGaWxlKQorICAgICAgICAvLyB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiB0aGUgcGFydGl0aW9uIGlzIG5vdCBtb3VudGVkLiBJbiBhbnkgY2FzZSB0aGlzIG1lYW5zIHRoZSBkaXIKKyAgICAgICAgLy8gaXMgdW5hdmFpbGFibGUsIHNvIHdlIGNhbiBjb250aW51ZSBwYXN0IGl0LiBTZWUgYi8yOTgzMzM0OSBmb3IgbW9yZSBpbmZvLgorICAgICAgICAvLyBUT0RPKGIvNjQwNzg3MDcpOiBlbmFibGUgUm9ib2xlY3RyaWMgdG8gdGhyb3cgZXhjZXB0aW9ucyBoZXJlIHRvIGluY3JlYXNlIHRlc3QgY292ZXJhZ2UKKyAgICAgICAgTG9nLncoCisgICAgICAgICAgICBUQUcsCisgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KCJpc0V4dGVybmFsU3RvcmFnZUVtdWxhdGVkKEZpbGUpIGZhaWxlZCBmb3IgWyVzXSIsIGRpci5nZXRBYnNvbHV0ZVBhdGgoKSksCisgICAgICAgICAgICBlKTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBQcml2YXRlIEFQSTsgcGxlYXNlIHVzZSB7QGxpbmsgI2dldE5vbkVtdWxhdGVkRXh0ZXJuYWxDYWNoZURpcnN9IGRpcmVjdGx5LiBUaGlzIGltcGxlbWVudGF0aW9uCisgICAqIG9mIHtAbGluayAjZ2V0Tm9uRW11bGF0ZWRFeHRlcm5hbENhY2hlRGlyc30gc3VwcG9ydHMgbG93ZXIgU0RLIGxldmVscyBhbmQgY2FuJ3QgcXVlcnkgc2Vjb25kYXJ5CisgICAqIHBhcnRpdGlvbnMgZm9yIGVtdWxhdGlvbi4gSG93ZXZlciwgb25seSB0aGUgcHJpbWFyeSBwYXJ0aXRpb24gY2FuIGJlIGVtdWxhdGVkIG9uIHN1Y2ggZGV2aWNlcy4KKyAgICovCisgIEBUYXJnZXRBcGkoQnVpbGQuVkVSU0lPTl9DT0RFUy5LSVRLQVQpCisgIHByaXZhdGUgc3RhdGljIExpc3Q8RmlsZT4gZ2V0Tm9uRW11bGF0ZWRFeHRlcm5hbENhY2hlRGlyc0tLKENvbnRleHQgY29udGV4dCkgeworICAgIExpc3Q8RmlsZT4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDw+KCk7CisKKyAgICAvLyBJZiB0aGUgcHJpbWFyeSBleHRlcm5hbCBzdG9yYWdlIGlzIG5vbi1lbXVsYXRlZCwgcmV0dXJuIGl0CisgICAgRmlsZVtdIGRpcnMgPSBjb250ZXh0LmdldEV4dGVybmFsQ2FjaGVEaXJzKCk7CisgICAgaWYgKCFFbnZpcm9ubWVudC5pc0V4dGVybmFsU3RvcmFnZUVtdWxhdGVkKCkgJiYgZGlyc1swXSAhPSBudWxsKSB7CisgICAgICByZXN1bHQuYWRkKGRpcnNbMF0pOworICAgIH0KKworICAgIC8vIENoZWNrIHNlY29uZGFyeSBzdG9yYWdlLiBXZSBza2lwIHRoZSBmaXJzdCBkaXIgKHByaW1hcnkpLCB3aGljaCB3ZSBhbHJlYWR5IGNoZWNrZWQuIFNlY29uZGFyeQorICAgIC8vIGRpcnMgY2Fubm90IGJlIGV4cGxpY2l0bHkgY2hlY2tlZCBmb3IgZW11bGF0aW9uIGJlY2F1c2Ugb2YgdGhlIEFQSSBsZXZlbCwgYnV0IGFyZSBhc3N1bWVkCisgICAgLy8gdG8gYmUgbm9uLWVtdWxhdGVkLiBTZWUge0BsaW5rIGh0dHBzOi8vc291cmNlLmFuZHJvaWQuY29tL2RldmljZXMvc3RvcmFnZS9jb25maWctZXhhbXBsZX0gYW5kCisgICAgLy8ge0BsaW5rIGNvbS5nb29nbGUuYW5kcm9pZC5hcHBzLmdtbS5zaGFyZWQudXRpbC5GaWxlVXRpbCNnZXROb25FbXVsYXRlZEV4dGVybmFsRmlsZXNEaXJLS30uCisgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBkaXJzLmxlbmd0aDsgaSsrKSB7CisgICAgICBpZiAoZGlyc1tpXSAhPSBudWxsKSB7CisgICAgICAgIHJlc3VsdC5hZGQoZGlyc1tpXSk7CisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIC8qKgorICAgKiBQcml2YXRlIEFQSTsgcGxlYXNlIHVzZSB7QGxpbmsgI2dldE5vbkVtdWxhdGVkRXh0ZXJuYWxDYWNoZURpcnN9IGRpcmVjdGx5LiBUaGlzIGltcGxlbWVudGF0aW9uCisgICAqIHN1cHBvcnRzIHNkayBsZXZlbHMgYmVsb3cgS2l0S2F0LCBhbmQgZHVlIHRvIHRoZSBsaW1pdGVkIEFQSSBjYW4gb25seSByZXR1cm4gYSBzaW5nbGUgZXh0ZXJuYWwKKyAgICogc3RvcmFnZSBwYXJ0aXRpb24gKHdoaWNoIG1heSBiZSBlbXVsYXRlZCwgaW4gd2hpY2ggY2FzZSBub25lIGFyZSByZXR1cm5lZCkuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBMaXN0PEZpbGU+IGdldE5vbkVtdWxhdGVkRXh0ZXJuYWxDYWNoZURpcnNJQ1MoQ29udGV4dCBjb250ZXh0KSB7CisgICAgRmlsZSBkaXIgPSBjb250ZXh0LmdldEV4dGVybmFsQ2FjaGVEaXIoKTsKKyAgICBpZiAoIUVudmlyb25tZW50LmlzRXh0ZXJuYWxTdG9yYWdlRW11bGF0ZWQoKSAmJiBkaXIgIT0gbnVsbCkgeworICAgICAgcmV0dXJuIEFycmF5cy5hc0xpc3QoZGlyKTsKKyAgICB9CisgICAgcmV0dXJuIENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOworICB9CisKKyAgLyoqIFJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyBmcmVlIGFuZCBhdmFpbGFibGUgb24gdGhlIGZpbGUgc3lzdGVtIG9mIHtAY29kZSBkaXJ9LiAqLworICBwdWJsaWMgc3RhdGljIGxvbmcgZ2V0QXZhaWxhYmxlU3RvcmFnZVNwYWNlKEZpbGUgZGlyKSB7CisgICAgaWYgKEJ1aWxkLlZFUlNJT04uU0RLX0lOVCA+PSBCdWlsZC5WRVJTSU9OX0NPREVTLkpFTExZX0JFQU5fTVIyKSB7CisgICAgICByZXR1cm4gZ2V0QXZhaWxhYmxlU3RvcmFnZVNwYWNlSkJNUjIoZGlyKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGdldEF2YWlsYWJsZVN0b3JhZ2VTcGFjZUlDUyhkaXIpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBCYXNlZCBvbiBjbC8xODkyNjc4MTguIFBhcmFwaHJhc2VkIGhlcmU6CisgICAqCisgICAqIDxwPkFjY29yZGluZyB0byBBR1NBIGJ1ZyBiLzMwOTU5NjA5IGFuZCBzaW1pbGFyIGJ1Z3MgaW4gb3RoZXIgMXN0IHBhcnR5IGFwcHMsIHRoZSBDb250ZXh0IGNhbgorICAgKiByZXR1cm4gYSBudWxsIGZpbGVzRGlyIG9uIFNESyB2ZXJzaW9ucyBiZWZvcmUgTi4gVGhlIHJvb3QgY2F1c2UgaXMgYSByYWNlIGNvbmRpdGlvbiBiZXR3ZWVuIHR3bworICAgKiB0aHJlYWRzIHRoYXQgdHJ5IHRvIGluaXRpYWxpemUgdGhlIGFwcGxpY2F0aW9uJ3MgZGlyZWN0b3J5IHN0cnVjdHVyZSBpbW1lZGlhdGVseSBmb2xsb3dpbmcKKyAgICogaW5zdGFsbGF0aW9uLiBPbmUgdGhyZWFkIHdhaXRzLCBhbmQgdGhlIG90aGVyIHJldHVybnMgYSBudWxsIEZpbGUgcG9pbnRlci4gVGhlIGJ1ZyBpcyBmaXhlZCBpbgorICAgKiBBbmRyb2lkIE4uIFRoZSB3b3JrYXJvdW5kIGZvciBvbGRlciByZWxlYXNlcyBpcyB0byB3YWl0LiBBIHNob3J0IHdoaWxlIGFmdGVyIGZhaWxpbmcsIHRoZQorICAgKiBkaXJlY3Rvcnkgc3RydWN0dXJlIGlzIGluaXRpYWxpemVkLCBhbmQgdGhlIHByZXZpb3VzbHkgZmFpbGluZyBDb250ZXh0IHJldHVybnMgYSB2YWxpZCBGaWxlCisgICAqIHBvaW50ZXIuIElmIHRoYXQgZG9lc24ndCB3b3JrLCB0aGVuIHRoZSBDb250ZXh0IG11c3QgYmUgYnJva2VuIGZvciBvdGhlciByZWFzb25zLiBXZSB0aHJvdyBhbgorICAgKiBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaW4gdGhpcyBjYXNlLgorICAgKi8KKyAgLy8gVE9ETyhiLzcwMjU1ODM1KTogcmVuYW1lIHRvIG5vdCBzdWdnZXN0IE4gaXMgc2FmZSBzaW5jZSBidWcgYWZmZWN0cyB1cCB0byBhbmQgaW5jbHVkaW5nIHNkayBOCisgIHB1YmxpYyBzdGF0aWMgRmlsZSBnZXRGaWxlc0RpcldpdGhQcmVOV29ya2Fyb3VuZChDb250ZXh0IGNvbnRleHQpIHsKKyAgICBGaWxlIGZpbGVzRGlyID0gY29udGV4dC5nZXRGaWxlc0RpcigpOworICAgIC8vIEFjY29yZGluZyB0byBBbmRyb2lkIGRvY3MsIHRoaXMgY2FuJ3QgaGFwcGVuLCBidXQgYSBwcmUtTiBidWcgbWFrZXMgdGhpcyBzb21ldGltZXMgcmV0dXJuCisgICAgLy8gbnVsbC4gU2VlIGIvMzA5NTk2MDkgZm9yIGRldGFpbHMuCisgICAgaWYgKGZpbGVzRGlyID09IG51bGwpIHsKKyAgICAgIC8vIFRoZSBjYXVzZSBpcyBhbiBpbnRlcm5hbCByYWNlIGNvbmRpdGlvbi4gU2xlZXAgYW5kIHRyeSBhZ2Fpbi4KKyAgICAgIFN5c3RlbUNsb2NrLnNsZWVwKDEwMCk7CisgICAgICBmaWxlc0RpciA9IGNvbnRleHQuZ2V0RmlsZXNEaXIoKTsKKyAgICAgIGlmIChmaWxlc0RpciA9PSBudWxsKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oImdldEZpbGVzRGlyIHJldHVybmVkIG51bGwgdHdpY2UuIik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmaWxlc0RpcjsKKyAgfQorCisgIC8qKiBQcml2YXRlIEFQSSB0byBzdXBwb3J0IHtAbGluayAjZ2V0QXZhaWxhYmxlU3RvcmFnZVNwYWNlfSBvbiBzZGsgSkItTVIyIGFuZCBoaWdoZXIuICovCisgIEBUYXJnZXRBcGkoQnVpbGQuVkVSU0lPTl9DT0RFUy5KRUxMWV9CRUFOX01SMikKKyAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBnZXRBdmFpbGFibGVTdG9yYWdlU3BhY2VKQk1SMihGaWxlIGRpcikgeworICAgIFN0YXRGcyBzdGF0ID0gbmV3IFN0YXRGcyhkaXIuZ2V0UGF0aCgpKTsKKyAgICByZXR1cm4gc3RhdC5nZXRBdmFpbGFibGVCeXRlcygpOworICB9CisKKyAgLyoqIFByaXZhdGUgQVBJIHRvIHN1cHBvcnQge0BsaW5rICNnZXRBdmFpbGFibGVTdG9yYWdlU3BhY2V9IG9uIGxvd2VyIHNkayBsZXZlbHMuICovCisgIHByaXZhdGUgc3RhdGljIGxvbmcgZ2V0QXZhaWxhYmxlU3RvcmFnZVNwYWNlSUNTKEZpbGUgZGlyKSB7CisgICAgU3RhdEZzIHN0YXQgPSBuZXcgU3RhdEZzKGRpci5nZXRQYXRoKCkpOworICAgIHJldHVybiAobG9uZykgc3RhdC5nZXRCbG9ja1NpemUoKSAqIHN0YXQuZ2V0QXZhaWxhYmxlQmxvY2tzKCk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB0aGUgZGF0YSBkaXJlY3Rvcnkgb2Yge0Bjb2RlIGNvbnRleHR9IGluIHRoZSBEaXJlY3RCb290IHN0b3JhZ2UgcGFydGl0aW9uLiBFYWNoIGNhbGwgdG8KKyAgICogdGhpcyBtZXRob2QgY3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB7QGxpbmsgQ29udGV4dH0sIHNvIHRoZSByZXN1bHQgc2hvdWxkIHJldXNlZCBpZiBwb3NzaWJsZS4KKyAgICovCisgIEBUYXJnZXRBcGkoQnVpbGQuVkVSU0lPTl9DT0RFUy5OKQorICBwdWJsaWMgc3RhdGljIEZpbGUgZ2V0RGV2aWNlUHJvdGVjdGVkRGF0YURpcihDb250ZXh0IGNvbnRleHQpIHsKKyAgICBDb250ZXh0IGRwc0NvbnRleHQgPSBjb250ZXh0LmNyZWF0ZURldmljZVByb3RlY3RlZFN0b3JhZ2VDb250ZXh0KCk7CisgICAgRmlsZSBkcHNGaWxlc0RpciA9IGdldEZpbGVzRGlyV2l0aFByZU5Xb3JrYXJvdW5kKGRwc0NvbnRleHQpOworICAgIEZpbGUgZHBzRGF0YURpciA9IGRwc0ZpbGVzRGlyLmdldFBhcmVudEZpbGUoKTsKKyAgICByZXR1cm4gZHBzRGF0YURpcjsKKyAgfQorCisgIHByaXZhdGUgQW5kcm9pZEZpbGVFbnZpcm9ubWVudCgpIHt9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQW5kcm9pZFVyaS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FuZHJvaWRVcmkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYTZiYzJlCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FuZHJvaWRVcmkuamF2YQpAQCAtMCwwICsxLDM3MCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kczsKKworaW1wb3J0IGFuZHJvaWQuYWNjb3VudHMuQWNjb3VudDsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5NYWxmb3JtZWRVcmlFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuTGl0ZVRyYW5zZm9ybUZyYWdtZW50czsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbC5QcmVjb25kaXRpb25zOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5UcmFuc2Zvcm1Qcm90b3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLlRyYW5zZm9ybVByb3RvOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuU2V0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworCisvKiogSGVscGVyIGNsYXNzIGZvciAiYW5kcm9pZDoiIFVSSXMuICovCitwdWJsaWMgZmluYWwgY2xhc3MgQW5kcm9pZFVyaSB7CisKKyAgLyoqCisgICAqIFJldHVybnMgYW4gYW5kcm9pZDogc2NoZW1lIFVSSSBidWlsZGVyIGZvciBwYWNrYWdlIHtAY29kZSBwYWNrYWdlTmFtZX0uIElmIG5vIHNldHRlciBpcyBjYWxsZWQKKyAgICogYmVmb3JlIHtAbGluayBCdWlsZGVyI2J1aWxkfSwgdGhlIHJlc3VsdGFudCBVUkkgd2lsbCBwb2ludCB0byB0aGUgY29tbW9uIGludGVybmFsIGFwcCBzdG9yYWdlLAorICAgKiBpLmUuICJhbmRyb2lkOi8vPHBhY2thZ2VOYW1lPi9maWxlcy9jb21tb24vc2hhcmVkLyIKKyAgICoKKyAgICogQHBhcmFtIGNvbnRleHQgVGhlIGFuZHJvaWQgZW52aXJvbm1lbnQuCisgICAqLworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgYnVpbGRlcihDb250ZXh0IGNvbnRleHQpIHsKKyAgICByZXR1cm4gbmV3IEJ1aWxkZXIoY29udGV4dCk7CisgIH0KKworICBwcml2YXRlIEFuZHJvaWRVcmkoKSB7fQorCisgIC8vIE1vZHVsZSBuYW1lcyBhcmUgbm9uLWVtcHR5IHN0cmluZ3Mgb2YgW2Etel0gd2l0aCBpbnRlcmxlYXZlZCB1bmRlcnNjb3JlcworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIE1PRFVMRV9QQVRURVJOID0gUGF0dGVybi5jb21waWxlKCJbYS16XSsoX1thLXpdKykqIik7CisKKyAgLy8gTmFtZSByZWdpc3RlcmVkIGZvciB0aGUgQW5kcm9pZCBiYWNrZW5kCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1FX05BTUUgPSAiYW5kcm9pZCI7CisKKyAgLy8gVVJJIHBhdGggZnJhZ21lbnRzIHdpdGggc3BlY2lhbCBtZWFuaW5nCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRVNfTE9DQVRJT04gPSAiZmlsZXMiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIE1BTkFHRURfTE9DQVRJT04gPSAibWFuYWdlZCI7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0FDSEVfTE9DQVRJT04gPSAiY2FjaGUiOworICAvLyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIuYW5kcm9pZC5jb20vdHJhaW5pbmcvYXJ0aWNsZXMvZGlyZWN0LWJvb3QuaHRtbAorICBzdGF0aWMgZmluYWwgU3RyaW5nIERJUkVDVF9CT09UX0ZJTEVTX0xPQ0FUSU9OID0gImRpcmVjdGJvb3QtZmlsZXMiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIERJUkVDVF9CT09UX0NBQ0hFX0xPQ0FUSU9OID0gImRpcmVjdGJvb3QtY2FjaGUiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIEVYVEVSTkFMX0xPQ0FUSU9OID0gImV4dGVybmFsIjsKKworICAvLyBUaGUgIm1hbmFnZWQiIGxvY2F0aW9uIG1hcHMgdG8gYSBzdWJkaXJlY3Rvcnkgd2l0aGluIC9maWxlcy8uCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUFOQUdFRF9GSUxFU19ESVJfU1VCRElSRUNUT1JZID0gIm1hbmFnZWQiOworCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09NTU9OX01PRFVMRSA9ICJjb21tb24iOworICBzdGF0aWMgZmluYWwgQWNjb3VudCBTSEFSRURfQUNDT1VOVCA9IEFjY291bnRTZXJpYWxpemF0aW9uLlNIQVJFRF9BQ0NPVU5UOworCisgIC8vIE1vZHVsZSBuYW1lcyByZXNlcnZlZCBmb3IgZnV0dXJlIHVzZSBvciB0aGF0IGFyZSBvdGhlcndpc2UgZGlzYWxsb3dlZC4gTm90ZSB0aGF0IEltbXV0YWJsZVNldAorICAvLyBpcyBhdm9pZGVkIGluIG9yZGVyIHRvIGF2b2lkIGd1YXZhIGRlcGVuZGVuY3kuCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNldDxTdHJpbmc+IFJFU0VSVkVEX01PRFVMRVMgPQorICAgICAgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KAorICAgICAgICAgIG5ldyBIYXNoU2V0PD4oCisgICAgICAgICAgICAgIEFycmF5cy5hc0xpc3QoCisgICAgICAgICAgICAgICAgICAiZGVmYXVsdCIsICJ1bnVzZWQiLCAic3BlY2lhbCIsICJyZXNlcnZlZCIsICJzaGFyZWQiLCAidmlydHVhbCIsICJtYW5hZ2VkIikpKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZXQ8U3RyaW5nPiBWQUxJRF9MT0NBVElPTlMgPQorICAgICAgQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KAorICAgICAgICAgIG5ldyBIYXNoU2V0PD4oCisgICAgICAgICAgICAgIEFycmF5cy5hc0xpc3QoCisgICAgICAgICAgICAgICAgICBGSUxFU19MT0NBVElPTiwKKyAgICAgICAgICAgICAgICAgIENBQ0hFX0xPQ0FUSU9OLAorICAgICAgICAgICAgICAgICAgTUFOQUdFRF9MT0NBVElPTiwKKyAgICAgICAgICAgICAgICAgIERJUkVDVF9CT09UX0ZJTEVTX0xPQ0FUSU9OLAorICAgICAgICAgICAgICAgICAgRElSRUNUX0JPT1RfQ0FDSEVfTE9DQVRJT04sCisgICAgICAgICAgICAgICAgICBFWFRFUk5BTF9MT0NBVElPTikpKTsKKworICAvKioKKyAgICogVmFsaWRhdGVzIHRoZSB7QGNvZGUgbG9jYXRpb259IG9mIGFuIEFuZHJvaWQgVVJJIHBhdGg7ICJmaWxlcyIgYW5kICJkaXJlY3Rib290IiBhcmUgdGhlIG9ubHkKKyAgICogdmFsaWQgc3RyaW5ncy4KKyAgICovCisgIHN0YXRpYyB2b2lkIHZhbGlkYXRlTG9jYXRpb24oU3RyaW5nIGxvY2F0aW9uKSB7CisgICAgUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KAorICAgICAgICBWQUxJRF9MT0NBVElPTlMuY29udGFpbnMobG9jYXRpb24pLAorICAgICAgICAiVGhlIG9ubHkgc3VwcG9ydGVkIGxvY2F0aW9ucyBhcmUgJXM6ICVzIiwKKyAgICAgICAgVkFMSURfTE9DQVRJT05TLAorICAgICAgICBsb2NhdGlvbik7CisgIH0KKyAgLyoqCisgICAqIFZhbGlkYXRlcyB0aGUge0Bjb2RlIG1vZHVsZX0gb2YgYW4gQW5kcm9pZCBVUkkgcGF0aC4gQW55IG5vbi1lbXB0eSBzdHJpbmcgb2YgW2Etel0gd2l0aAorICAgKiBpbnRlcmxlYXZlZCB1bmRlcnNjb3JlcyB0aGF0IGlzIG5vdCBsaXN0ZWQgYXMgcmVzZXJ2ZWQgaXMgdmFsaWQuCisgICAqLworICBzdGF0aWMgdm9pZCB2YWxpZGF0ZU1vZHVsZShTdHJpbmcgbW9kdWxlKSB7CisgICAgUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KAorICAgICAgICBNT0RVTEVfUEFUVEVSTi5tYXRjaGVyKG1vZHVsZSkubWF0Y2hlcygpLCAiTW9kdWxlIG11c3QgbWF0Y2ggW2Etel0rKF9bYS16XSspKjogJXMiLCBtb2R1bGUpOworICAgIFByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudCgKKyAgICAgICAgIVJFU0VSVkVEX01PRFVMRVMuY29udGFpbnMobW9kdWxlKSwKKyAgICAgICAgIk1vZHVsZSBuYW1lIGlzIHJlc2VydmVkIGFuZCBjYW5ub3QgYmUgdXNlZDogJXMiLAorICAgICAgICBtb2R1bGUpOworICB9CisKKyAgLyoqCisgICAqIFZhbGlkYXRlcyB0aGUge0Bjb2RlIHVudXNlZFJlbGF0aXZlUGF0aH0gb2YgYW4gQW5kcm9pZCBVUkkgcGF0aC4gQXQgcHJlc2VudCB0aW1lIHRoaXMgaXMgYQorICAgKiBuby1vcC4KKyAgICoKKyAgICogQHBhcmFtIHVudXNlZFJlbGF0aXZlUGF0aCBOb3QgdXNlZC4KKyAgICovCisgIHN0YXRpYyB2b2lkIHZhbGlkYXRlUmVsYXRpdmVQYXRoKFN0cmluZyB1bnVzZWRSZWxhdGl2ZVBhdGgpIHsKKyAgICAvLyBOby1vcAorICB9CisKKyAgLyoqIEJ1aWxkZXIgZm9yIEFuZHJvaWQgVXJpcy4gKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBCdWlsZGVyIHsKKworICAgIC8vIFVSSSBhdXRob3JpdHk7IHJlcXVpcmVkCisgICAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisKKyAgICAvLyBVUkkgcGF0aCBjb21wb25lbnRzOyBvcHRpb25hbAorICAgIHByaXZhdGUgU3RyaW5nIHBhY2thZ2VOYW1lOyAvLyBUT0RPOiBzaG91bGQgZGVmYXVsdCBiZSAiIj8KKyAgICBwcml2YXRlIFN0cmluZyBsb2NhdGlvbiA9IEFuZHJvaWRVcmkuRklMRVNfTE9DQVRJT047CisgICAgcHJpdmF0ZSBTdHJpbmcgbW9kdWxlID0gQW5kcm9pZFVyaS5DT01NT05fTU9EVUxFOworICAgIHByaXZhdGUgQWNjb3VudCBhY2NvdW50ID0gQW5kcm9pZFVyaS5TSEFSRURfQUNDT1VOVDsKKyAgICBwcml2YXRlIFN0cmluZyByZWxhdGl2ZVBhdGggPSAiIjsKKworICAgIHByaXZhdGUgZmluYWwgSW1tdXRhYmxlTGlzdC5CdWlsZGVyPFN0cmluZz4gZW5jb2RlZFNwZWNzID0gSW1tdXRhYmxlTGlzdC5idWlsZGVyKCk7CisKKyAgICBwcml2YXRlIEJ1aWxkZXIoQ29udGV4dCBjb250ZXh0KSB7CisgICAgICBQcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoY29udGV4dCAhPSBudWxsLCAiQ29udGV4dCBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsKKyAgICAgIHRoaXMucGFja2FnZU5hbWUgPSBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCk7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgcGFja2FnZSB0byB1c2UgaW4gdGhlIGFuZHJvaWQgdXJpIEFVVEhPUklUWS4gRGVmYXVsdCBpcyBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkuCisgICAgICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2FnZShTdHJpbmcgcGFja2FnZU5hbWUpIHsKKyAgICAgIHRoaXMucGFja2FnZU5hbWUgPSBwYWNrYWdlTmFtZTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHByaXZhdGUgQnVpbGRlciBzZXRMb2NhdGlvbihTdHJpbmcgbG9jYXRpb24pIHsKKyAgICAgIEFuZHJvaWRVcmkudmFsaWRhdGVMb2NhdGlvbihsb2NhdGlvbik7CisgICAgICB0aGlzLmxvY2F0aW9uID0gbG9jYXRpb247CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBzZXRNYW5hZ2VkTG9jYXRpb24oKSB7CisgICAgICByZXR1cm4gc2V0TG9jYXRpb24oTUFOQUdFRF9MT0NBVElPTik7CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXIgc2V0RXh0ZXJuYWxMb2NhdGlvbigpIHsKKyAgICAgIHJldHVybiBzZXRMb2NhdGlvbihFWFRFUk5BTF9MT0NBVElPTik7CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXIgc2V0RGlyZWN0Qm9vdEZpbGVzTG9jYXRpb24oKSB7CisgICAgICByZXR1cm4gc2V0TG9jYXRpb24oRElSRUNUX0JPT1RfRklMRVNfTE9DQVRJT04pOworICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyIHNldERpcmVjdEJvb3RDYWNoZUxvY2F0aW9uKCkgeworICAgICAgcmV0dXJuIHNldExvY2F0aW9uKERJUkVDVF9CT09UX0NBQ0hFX0xPQ0FUSU9OKTsKKyAgICB9CisKKyAgICAvKiogSW50ZXJuYWwgbG9jYXRpb24sIGFrYSAiZmlsZXMiLCBpcyB0aGUgZGVmYXVsdCBsb2NhdGlvbi4gKi8KKyAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnRlcm5hbExvY2F0aW9uKCkgeworICAgICAgcmV0dXJuIHNldExvY2F0aW9uKEZJTEVTX0xPQ0FUSU9OKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBzZXRDYWNoZUxvY2F0aW9uKCkgeworICAgICAgcmV0dXJuIHNldExvY2F0aW9uKENBQ0hFX0xPQ0FUSU9OKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBzZXRNb2R1bGUoU3RyaW5nIG1vZHVsZSkgeworICAgICAgQW5kcm9pZFVyaS52YWxpZGF0ZU1vZHVsZShtb2R1bGUpOworICAgICAgdGhpcy5tb2R1bGUgPSBtb2R1bGU7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBhY2NvdW50LiBBbmRyb2lkVXJpLlNIQVJFRF9BQ0NPVU5UIGlzIHRoZSBkZWZhdWx0LCBhbmQgaXQgc2hvd3MgdXAgYXMgInNoYXJlZCIgb24KKyAgICAgKiB0aGUgZmlsZXN5c3RlbS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgbWV0aG9kIHBlcmZvcm1zIHNvbWUgYWNjb3VudCB2YWxpZGF0aW9uLiBBbmRyb2lkIEFjY291bnQgaXRzZWxmIHJlcXVpcmVzIHRoYXQgYm90aAorICAgICAqIHRoZSB0eXBlIGFuZCBuYW1lIGZpZWxkcyBiZSBwcmVzZW50LiBJbiBhZGRpdGlvbiB0byB0aGlzIHJlcXVpcmVtZW50LCB0aGlzIGJhY2tlbmQgcmVxdWlyZXMKKyAgICAgKiB0aGF0IHRoZSB0eXBlIGNvbnRhaW4gbm8gY29sb25zIChhcyB0aGVzZSBhcmUgdGhlIGRlbGltaXRlciB1c2VkIGludGVybmFsbHkgZm9yIHRoZSBhY2NvdW50CisgICAgICogc2VyaWFsaXphdGlvbiksIGFuZCB0aGF0IG5laXRoZXIgdGhlIHR5cGUgbm9yIHRoZSBuYW1lIGluY2x1ZGUgYW55IHNsYXNoZXMgKGFzIHRoZXNlIGFyZSBmaWxlCisgICAgICogc2VwYXJhdG9ycykuCisgICAgICoKKyAgICAgKiA8cD5UaGUgYWNjb3VudCB3aWxsIGJlIFVSTCBlbmNvZGVkIGluIGl0cyBVUkkgcmVwcmVzZW50YXRpb24gKHNvLCBlZywgIjxpbnRlcm5hbD5AZ21haWwuY29tIgorICAgICAqIHdpbGwgYXBwZWFyIGFzICJ5b3UlNDBnbWFpbC5jb20iKSwgYnV0IG5vdCBpbiB0aGUgZmlsZSBwYXRoIHJlcHJlc2VudGF0aW9uIHVzZWQgdG8gYWNjZXNzCisgICAgICogZGlzay4KKyAgICAgKgorICAgICAqIDxwPk5vdGUgdGhlIExpbnV4IGZpbGVzeXN0ZW0gYWNjZXB0cyBmaWxlbmFtZXMgY29tcG9zZWQgb2YgYW55IGJ5dGVzIGV4Y2VwdCAiLyIgYW5kIE5VTEwuCisgICAgICoKKyAgICAgKiBAcGFyYW0gYWNjb3VudCBUaGUgYWNjb3VudCB0byBzZXQuCisgICAgICogQHJldHVybiBUaGUgZmx1ZW50IEJ1aWxkZXIuCisgICAgICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0QWNjb3VudChBY2NvdW50IGFjY291bnQpIHsKKyAgICAgIEFjY291bnRTZXJpYWxpemF0aW9uLnNlcmlhbGl6ZShhY2NvdW50KTsgLy8gcGVyZm9ybXMgdmFsaWRhdGlvbiBpbnRlcm5hbGx5CisgICAgICB0aGlzLmFjY291bnQgPSBhY2NvdW50OworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgY29tcG9uZW50IG9mIHRoZSBwYXRoIGFmdGVyIGxvY2F0aW9uLCBtb2R1bGUgYW5kIGFjY291bnQuIEEgc2luZ2xlIGxlYWRpbmcgc2xhc2gKKyAgICAgKiB3aWxsIGJlIHRyaW1tZWQgaWYgcHJlc2VudC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVpbGRlciBzZXRSZWxhdGl2ZVBhdGgoU3RyaW5nIHJlbGF0aXZlUGF0aCkgeworICAgICAgaWYgKHJlbGF0aXZlUGF0aC5zdGFydHNXaXRoKCIvIikpIHsKKyAgICAgICAgcmVsYXRpdmVQYXRoID0gcmVsYXRpdmVQYXRoLnN1YnN0cmluZygxKTsKKyAgICAgIH0KKyAgICAgIEFuZHJvaWRVcmkudmFsaWRhdGVSZWxhdGl2ZVBhdGgocmVsYXRpdmVQYXRoKTsKKyAgICAgIHRoaXMucmVsYXRpdmVQYXRoID0gcmVsYXRpdmVQYXRoOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogVXBkYXRlcyBidWlsZGVyIHdpdGggbXVsdGlwbGUgZmllbGRzIGZyb20gZmlsZSBwYXJhbTogbG9jYXRpb24sIG1vZHVsZSwgYWNjb3VudCBhbmQgcmVsYXRpdmUKKyAgICAgKiBwYXRoLiBUaGlzIG1ldGhvZCB3aWxsIGZhaWwgb24gIm1hbmFnZWQiIHBhdGhzIChzZWUge0BsaW5rIGZyb21GaWxlKEZpbGUsIEFjY291bnRNYW5hZ2VyKX0pLgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIGZyb21GaWxlKEZpbGUgZmlsZSkgeworICAgICAgcmV0dXJuIGZyb21BYnNvbHV0ZVBhdGgoZmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSwgLyogYWNjb3VudE1hbmFnZXI9ICovIG51bGwpOworICAgIH0KKworICAgIC8qKgorICAgICAqIFVwZGF0ZXMgYnVpbGRlciB3aXRoIG11bHRpcGxlIGZpZWxkcyBmcm9tIGZpbGUgcGFyYW06IGxvY2F0aW9uLCBtb2R1bGUsIGFjY291bnQgYW5kIHJlbGF0aXZlCisgICAgICogcGF0aC4gQSBub24tbnVsbCB7QGNvZGUgYWNjb3VudE1hbmFnZXJ9IGlzIHJlcXVpcmVkIHRvIGhhbmRsZSAibWFuYWdlZCIgcGF0aHMuCisgICAgICovCisgICAgcHVibGljIEJ1aWxkZXIgZnJvbUZpbGUoRmlsZSBmaWxlLCBATnVsbGFibGUgQWNjb3VudE1hbmFnZXIgYWNjb3VudE1hbmFnZXIpIHsKKyAgICAgIHJldHVybiBmcm9tQWJzb2x1dGVQYXRoKGZpbGUuZ2V0QWJzb2x1dGVQYXRoKCksIGFjY291bnRNYW5hZ2VyKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGJ1aWxkZXIgd2l0aCBtdWx0aXBsZSBmaWVsZHMgZnJvbSBhYnNvbHV0ZSBwYXRoIHBhcmFtOiBsb2NhdGlvbiwgbW9kdWxlLCBhY2NvdW50IGFuZAorICAgICAqIHJlbGF0aXZlIHBhdGguIFRoaXMgbWV0aG9kIHdpbGwgZmFpbCBvbiAibWFuYWdlZCIgcGF0aHMgKHNlZSB7QGxpbmsgZnJvbUFic29sdXRlUGF0aChTdHJpbmcsCisgICAgICogQWNjb3VudE1hbmFnZXIpfSkuCisgICAgICovCisgICAgcHVibGljIEJ1aWxkZXIgZnJvbUFic29sdXRlUGF0aChTdHJpbmcgYWJzb2x1dGVQYXRoKSB7CisgICAgICByZXR1cm4gZnJvbUFic29sdXRlUGF0aChhYnNvbHV0ZVBhdGgsIC8qIGFjY291bnRNYW5hZ2VyPSAqLyBudWxsKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBVcGRhdGVzIGJ1aWxkZXIgd2l0aCBtdWx0aXBsZSBmaWVsZHMgZnJvbSBhYnNvbHV0ZSBwYXRoIHBhcmFtOiBsb2NhdGlvbiwgbW9kdWxlLCBhY2NvdW50IGFuZAorICAgICAqIHJlbGF0aXZlIHBhdGguIEEgbm9uLW51bGwge0Bjb2RlIGFjY291bnRNYW5hZ2VyfSBpcyByZXF1aXJlZCB0byBoYW5kbGUgIm1hbmFnZWQiIHBhdGhzLgorICAgICAqLworICAgIC8vIFRPRE8oYi8xMjk0NjcwNTEpOiByZW1vdmUgcmVxdWlyZW1lbnQgZm9yIHNlZ21lbnRzIGFmdGVyIDB0aCAobG9naWNhbCBsb2NhdGlvbikKKyAgICBwdWJsaWMgQnVpbGRlciBmcm9tQWJzb2x1dGVQYXRoKFN0cmluZyBhYnNvbHV0ZVBhdGgsIEBOdWxsYWJsZSBBY2NvdW50TWFuYWdlciBhY2NvdW50TWFuYWdlcikgeworICAgICAgLy8gR2V0IHRoZSBmaWxlJ3MgcGF0aCB3aXRoaW4gaW50ZXJuYWwgZmlsZXMsIC9tb2R1bGUvYWNjb3VudDwvcmVsYXRpdmVQYXRoPgorICAgICAgRmlsZSBmaWxlc0RpciA9IEFuZHJvaWRGaWxlRW52aXJvbm1lbnQuZ2V0RmlsZXNEaXJXaXRoUHJlTldvcmthcm91bmQoY29udGV4dCk7CisgICAgICBTdHJpbmcgZmlsZXNEaXJQYXRoID0gZmlsZXNEaXIuZ2V0QWJzb2x1dGVQYXRoKCk7CisgICAgICBTdHJpbmcgY2FjaGVEaXJQYXRoID0gY29udGV4dC5nZXRDYWNoZURpcigpLmdldEFic29sdXRlUGF0aCgpOworICAgICAgU3RyaW5nIG1hbmFnZWREaXJQYXRoID0gbmV3IEZpbGUoZmlsZXNEaXIsIE1BTkFHRURfRklMRVNfRElSX1NVQkRJUkVDVE9SWSkuZ2V0QWJzb2x1dGVQYXRoKCk7CisgICAgICBTdHJpbmcgZXh0ZXJuYWxEaXJQYXRoID0gbnVsbDsKKyAgICAgIEZpbGUgZXh0ZXJuYWxGaWxlc0RpciA9IGNvbnRleHQuZ2V0RXh0ZXJuYWxGaWxlc0RpcihudWxsKTsKKyAgICAgIGlmIChleHRlcm5hbEZpbGVzRGlyICE9IG51bGwpIHsKKyAgICAgICAgZXh0ZXJuYWxEaXJQYXRoID0gZXh0ZXJuYWxGaWxlc0Rpci5nZXRBYnNvbHV0ZVBhdGgoKTsKKyAgICAgIH0KKyAgICAgIFN0cmluZyBkaXJlY3RCb290RmlsZXNQYXRoID0gbnVsbDsKKyAgICAgIFN0cmluZyBkaXJlY3RCb290Q2FjaGVQYXRoID0gbnVsbDsKKyAgICAgIGlmIChCdWlsZC5WRVJTSU9OLlNES19JTlQgPj0gQnVpbGQuVkVSU0lPTl9DT0RFUy5OKSB7CisgICAgICAgIC8vIFRPRE8oYi8xNDM2MTA4NzIpOiBydW4gYWZ0ZXIgY2hlY2tpbmcgb3RoZXIgZGlycyB0byBtaW5pbWl6ZSBpbXBhY3Qgb2YgbmV3IENvbnRleHQoKSdzCisgICAgICAgIEZpbGUgZHBzRGF0YURpciA9IEFuZHJvaWRGaWxlRW52aXJvbm1lbnQuZ2V0RGV2aWNlUHJvdGVjdGVkRGF0YURpcihjb250ZXh0KTsKKyAgICAgICAgZGlyZWN0Qm9vdEZpbGVzUGF0aCA9IG5ldyBGaWxlKGRwc0RhdGFEaXIsICJmaWxlcyIpLmdldEFic29sdXRlUGF0aCgpOworICAgICAgICBkaXJlY3RCb290Q2FjaGVQYXRoID0gbmV3IEZpbGUoZHBzRGF0YURpciwgImNhY2hlIikuZ2V0QWJzb2x1dGVQYXRoKCk7CisgICAgICB9CisKKyAgICAgIFN0cmluZyBpbnRlcm5hbFBhdGg7CisgICAgICBpZiAoYWJzb2x1dGVQYXRoLnN0YXJ0c1dpdGgobWFuYWdlZERpclBhdGgpKSB7CisgICAgICAgIC8vIG1hbmFnZWREaXJQYXRoIG11c3QgYmUgY2hlY2tlZCBiZWZvcmUgZmlsZXNEaXJQYXRoIGJlY2F1c2UgZmlsZXNEaXJQYXRoIGlzIGEgcHJlZml4LgorICAgICAgICBzZXRMb2NhdGlvbihBbmRyb2lkVXJpLk1BTkFHRURfTE9DQVRJT04pOworICAgICAgICBpbnRlcm5hbFBhdGggPSBhYnNvbHV0ZVBhdGguc3Vic3RyaW5nKG1hbmFnZWREaXJQYXRoLmxlbmd0aCgpKTsKKyAgICAgIH0gZWxzZSBpZiAoYWJzb2x1dGVQYXRoLnN0YXJ0c1dpdGgoZmlsZXNEaXJQYXRoKSkgeworICAgICAgICBzZXRMb2NhdGlvbihBbmRyb2lkVXJpLkZJTEVTX0xPQ0FUSU9OKTsKKyAgICAgICAgaW50ZXJuYWxQYXRoID0gYWJzb2x1dGVQYXRoLnN1YnN0cmluZyhmaWxlc0RpclBhdGgubGVuZ3RoKCkpOworICAgICAgfSBlbHNlIGlmIChhYnNvbHV0ZVBhdGguc3RhcnRzV2l0aChjYWNoZURpclBhdGgpKSB7CisgICAgICAgIHNldExvY2F0aW9uKEFuZHJvaWRVcmkuQ0FDSEVfTE9DQVRJT04pOworICAgICAgICBpbnRlcm5hbFBhdGggPSBhYnNvbHV0ZVBhdGguc3Vic3RyaW5nKGNhY2hlRGlyUGF0aC5sZW5ndGgoKSk7CisgICAgICB9IGVsc2UgaWYgKGV4dGVybmFsRGlyUGF0aCAhPSBudWxsICYmIGFic29sdXRlUGF0aC5zdGFydHNXaXRoKGV4dGVybmFsRGlyUGF0aCkpIHsKKyAgICAgICAgc2V0TG9jYXRpb24oQW5kcm9pZFVyaS5FWFRFUk5BTF9MT0NBVElPTik7CisgICAgICAgIGludGVybmFsUGF0aCA9IGFic29sdXRlUGF0aC5zdWJzdHJpbmcoZXh0ZXJuYWxEaXJQYXRoLmxlbmd0aCgpKTsKKyAgICAgIH0gZWxzZSBpZiAoZGlyZWN0Qm9vdEZpbGVzUGF0aCAhPSBudWxsICYmIGFic29sdXRlUGF0aC5zdGFydHNXaXRoKGRpcmVjdEJvb3RGaWxlc1BhdGgpKSB7CisgICAgICAgIHNldExvY2F0aW9uKEFuZHJvaWRVcmkuRElSRUNUX0JPT1RfRklMRVNfTE9DQVRJT04pOworICAgICAgICBpbnRlcm5hbFBhdGggPSBhYnNvbHV0ZVBhdGguc3Vic3RyaW5nKGRpcmVjdEJvb3RGaWxlc1BhdGgubGVuZ3RoKCkpOworICAgICAgfSBlbHNlIGlmIChkaXJlY3RCb290Q2FjaGVQYXRoICE9IG51bGwgJiYgYWJzb2x1dGVQYXRoLnN0YXJ0c1dpdGgoZGlyZWN0Qm9vdENhY2hlUGF0aCkpIHsKKyAgICAgICAgc2V0TG9jYXRpb24oQW5kcm9pZFVyaS5ESVJFQ1RfQk9PVF9DQUNIRV9MT0NBVElPTik7CisgICAgICAgIGludGVybmFsUGF0aCA9IGFic29sdXRlUGF0aC5zdWJzdHJpbmcoZGlyZWN0Qm9vdENhY2hlUGF0aC5sZW5ndGgoKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAorICAgICAgICAgICAgIlBhdGggbXVzdCBiZSBpbiBhcHAtcHJpdmF0ZSBmaWxlcyBkaXIgb3IgZXh0ZXJuYWwgZmlsZXMgZGlyOiAiICsgYWJzb2x1dGVQYXRoKTsKKyAgICAgIH0KKworICAgICAgLy8gRXh0cmFjdCBjb21wb25lbnRzIGFjY29yZGluZyB0byBhbmRyb2lkOiBmaWxlIGxheW91dC4gVGhlIDB0aCBlbGVtZW50IG9mIHNwbGl0KCkgd2lsbCBiZQorICAgICAgLy8gYW4gZW1wdHkgc3RyaW5nIHByZWNlZGluZyB0aGUgZmlyc3QgY2hhcmFjdGVyICIvIgorICAgICAgTGlzdDxTdHJpbmc+IHBhdGhGcmFnbWVudHMgPSBBcnJheXMuYXNMaXN0KGludGVybmFsUGF0aC5zcGxpdChGaWxlLnNlcGFyYXRvcikpOworICAgICAgUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KAorICAgICAgICAgIHBhdGhGcmFnbWVudHMuc2l6ZSgpID49IDMsCisgICAgICAgICAgIlBhdGggbXVzdCBiZSBpbiBtb2R1bGUgYW5kIGFjY291bnQgc3ViZGlyZWN0b3JpZXM6ICVzIiwKKyAgICAgICAgICBhYnNvbHV0ZVBhdGgpOworICAgICAgc2V0TW9kdWxlKHBhdGhGcmFnbWVudHMuZ2V0KDEpKTsKKworICAgICAgU3RyaW5nIGFjY291bnRTdHIgPSBwYXRoRnJhZ21lbnRzLmdldCgyKTsKKyAgICAgIGlmIChNQU5BR0VEX0xPQ0FUSU9OLmVxdWFscyhsb2NhdGlvbikgJiYgIUFjY291bnRTZXJpYWxpemF0aW9uLmlzU2hhcmVkQWNjb3VudChhY2NvdW50U3RyKSkgeworICAgICAgICBpbnQgYWNjb3VudElkOworICAgICAgICB0cnkgeworICAgICAgICAgIGFjY291bnRJZCA9IEludGVnZXIucGFyc2VJbnQoYWNjb3VudFN0cik7CisgICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihlKTsKKyAgICAgICAgfQorCisgICAgICAgIC8vIEJsb2NrcyBvbiBkaXNrIElPIHRvIHJlYWQgYWNjb3VudCB0YWJsZS4KKyAgICAgICAgLy8gVE9ETyhiLzExNTk0MDM5Nik6IHN1cmZhY2UgYmFkIGFjY291bnQgYXMgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIChjaGFuZ2UgQVBJIHNpZ25hdHVyZT8pCisgICAgICAgIFByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChhY2NvdW50TWFuYWdlciAhPSBudWxsLCAiQWNjb3VudE1hbmFnZXIgY2Fubm90IGJlIG51bGwiKTsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBzZXRBY2NvdW50KGFjY291bnRNYW5hZ2VyLmdldEFjY291bnQoYWNjb3VudElkKS5nZXQoKSk7CisgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBUaHJlYWQuY3VycmVudFRocmVhZCgpLmludGVycnVwdCgpOworICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24obmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbihlKSk7CisgICAgICAgIH0gY2F0Y2ggKEV4ZWN1dGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihuZXcgTWFsZm9ybWVkVXJpRXhjZXB0aW9uKGUuZ2V0Q2F1c2UoKSkpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBzZXRBY2NvdW50KEFjY291bnRTZXJpYWxpemF0aW9uLmRlc2VyaWFsaXplKGFjY291bnRTdHIpKTsKKyAgICAgIH0KKworICAgICAgc2V0UmVsYXRpdmVQYXRoKGludGVybmFsUGF0aC5zdWJzdHJpbmcobW9kdWxlLmxlbmd0aCgpICsgYWNjb3VudFN0ci5sZW5ndGgoKSArIDIpKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyIHdpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtIHNwZWMpIHsKKyAgICAgIGVuY29kZWRTcGVjcy5hZGQoVHJhbnNmb3JtUHJvdG9zLnRvRW5jb2RlZFNwZWMoc3BlYykpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLy8gVE9ETyhiLzExNTk0MDM5Nik6IGFkZCBNYWxmb3JtZWRVcmlFeGNlcHRpb24gdG8gc2lnbmF0dXJlCisgICAgcHVibGljIFVyaSBidWlsZCgpIHsKKyAgICAgIFN0cmluZyB1cmlQYXRoID0KKyAgICAgICAgICAiLyIKKyAgICAgICAgICAgICAgKyBsb2NhdGlvbgorICAgICAgICAgICAgICArICIvIgorICAgICAgICAgICAgICArIG1vZHVsZQorICAgICAgICAgICAgICArICIvIgorICAgICAgICAgICAgICArIEFjY291bnRTZXJpYWxpemF0aW9uLnNlcmlhbGl6ZShhY2NvdW50KQorICAgICAgICAgICAgICArICIvIgorICAgICAgICAgICAgICArIHJlbGF0aXZlUGF0aDsKKyAgICAgIFN0cmluZyBmcmFnbWVudCA9IExpdGVUcmFuc2Zvcm1GcmFnbWVudHMuam9pblRyYW5zZm9ybVNwZWNzKGVuY29kZWRTcGVjcy5idWlsZCgpKTsKKworICAgICAgcmV0dXJuIG5ldyBVcmkuQnVpbGRlcigpCisgICAgICAgICAgLnNjaGVtZShBbmRyb2lkVXJpLlNDSEVNRV9OQU1FKQorICAgICAgICAgIC5hdXRob3JpdHkocGFja2FnZU5hbWUpCisgICAgICAgICAgLnBhdGgodXJpUGF0aCkKKyAgICAgICAgICAuZW5jb2RlZEZyYWdtZW50KGZyYWdtZW50KQorICAgICAgICAgIC5idWlsZCgpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FuZHJvaWRVcmlBZGFwdGVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQW5kcm9pZFVyaUFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjQyMjMyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FuZHJvaWRVcmlBZGFwdGVyLmphdmEKQEAgLTAsMCArMSwxNDMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBhbmRyb2lkLmFjY291bnRzLkFjY291bnQ7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQ7CitpbXBvcnQgYW5kcm9pZC50ZXh0LlRleHRVdGlsczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5NYWxmb3JtZWRVcmlFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKgorICogQWRhcHRlciBmb3IgY29udmVydGluZyAiYW5kcm9pZDoiIFVSSXMgaW50byBqYXZhLmlvLkZpbGUuIFRoaXMgaXMgY29uc2lkZXJlZCBkYW5nZXJvdXMgc2luY2UgaXQKKyAqIGlnbm9yZXMgcGFydHMgb2YgdGhlIFVyaSBhdCB0aGUgY2FsbGVyJ3MgcGVyaWwsIGFuZCB0aHVzIGlzIG9ubHkgYXZhaWxhYmxlIHRvIGFsbG93bGlzdGVkIGNsaWVudHMKKyAqIChtb3N0bHkgaW50ZXJuYWwpLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgQW5kcm9pZFVyaUFkYXB0ZXIgaW1wbGVtZW50cyBVcmlBZGFwdGVyIHsKKworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dDsKKyAgQE51bGxhYmxlIHByaXZhdGUgZmluYWwgQWNjb3VudE1hbmFnZXIgYWNjb3VudE1hbmFnZXI7CisKKyAgcHJpdmF0ZSBBbmRyb2lkVXJpQWRhcHRlcihDb250ZXh0IGNvbnRleHQsIEBOdWxsYWJsZSBBY2NvdW50TWFuYWdlciBhY2NvdW50TWFuYWdlcikgeworICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CisgICAgdGhpcy5hY2NvdW50TWFuYWdlciA9IGFjY291bnRNYW5hZ2VyOworICB9CisKKyAgLyoqIFRoaXMgYWRhcHRlciB3aWxsIGZhaWwgb24gIm1hbmFnZWQiIFVSSXMgKHNlZSB7QGxpbmsgZm9yQ29udGV4dChDb250ZXh0LCBBY2NvdW50TWFuYWdlcil9KS4gKi8KKyAgcHVibGljIHN0YXRpYyBBbmRyb2lkVXJpQWRhcHRlciBmb3JDb250ZXh0KENvbnRleHQgY29udGV4dCkgeworICAgIHJldHVybiBuZXcgQW5kcm9pZFVyaUFkYXB0ZXIoY29udGV4dCwgLyogYWNjb3VudE1hbmFnZXI9ICovIG51bGwpOworICB9CisKKyAgLyoqIEEgbm9uLW51bGwge0Bjb2RlIGFjY291bnRNYW5hZ2VyfSBpcyByZXF1aXJlZCB0byBoYW5kbGUgIm1hbmFnZWQiIHBhdGhzLiAqLworICBwdWJsaWMgc3RhdGljIEFuZHJvaWRVcmlBZGFwdGVyIGZvckNvbnRleHQoQ29udGV4dCBjb250ZXh0LCBBY2NvdW50TWFuYWdlciBhY2NvdW50TWFuYWdlcikgeworICAgIHJldHVybiBuZXcgQW5kcm9pZFVyaUFkYXB0ZXIoY29udGV4dCwgYWNjb3VudE1hbmFnZXIpOworICB9CisKKyAgLyogQHRocm93cyBNYWxmb3JtZWRVcmlFeGNlcHRpb24gaWYgdGhlIHVyaSBpcyBub3QgdmFsaWQuICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCB2YWxpZGF0ZShVcmkgdXJpKSB0aHJvd3MgTWFsZm9ybWVkVXJpRXhjZXB0aW9uIHsKKyAgICBpZiAoIXVyaS5nZXRTY2hlbWUoKS5lcXVhbHMoQW5kcm9pZFVyaS5TQ0hFTUVfTkFNRSkpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oIlNjaGVtZSBtdXN0IGJlICdhbmRyb2lkJyIpOworICAgIH0KKyAgICBpZiAodXJpLmdldFBhdGhTZWdtZW50cygpLmlzRW1wdHkoKSkgeworICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbigKKyAgICAgICAgICBTdHJpbmcuZm9ybWF0KCJQYXRoIG11c3Qgc3RhcnQgd2l0aCBhIHZhbGlkIGxvZ2ljYWwgbG9jYXRpb246ICVzIiwgdXJpKSk7CisgICAgfQorICAgIGlmICghVGV4dFV0aWxzLmlzRW1wdHkodXJpLmdldFF1ZXJ5KCkpKSB7CisgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVXJpRXhjZXB0aW9uKCJEaWQgbm90IGV4cGVjdCB1cmkgdG8gaGF2ZSBxdWVyeSIpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgRmlsZSB0b0ZpbGUoVXJpIHVyaSkgdGhyb3dzIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbiB7CisgICAgdmFsaWRhdGUodXJpKTsKKyAgICBBcnJheUxpc3Q8U3RyaW5nPiBwYXRoU2VnbWVudHMgPSBuZXcgQXJyYXlMaXN0PD4odXJpLmdldFBhdGhTZWdtZW50cygpKTsgLy8gYWxsb3cgbW9kaWZpY2F0aW9uCisgICAgRmlsZSByb290TG9jYXRpb247CisgICAgc3dpdGNoIChwYXRoU2VnbWVudHMuZ2V0KDApKSB7CisgICAgICBjYXNlIEFuZHJvaWRVcmkuRElSRUNUX0JPT1RfRklMRVNfTE9DQVRJT046CisgICAgICAgIGlmIChCdWlsZC5WRVJTSU9OLlNES19JTlQgPj0gQnVpbGQuVkVSU0lPTl9DT0RFUy5OKSB7CisgICAgICAgICAgcm9vdExvY2F0aW9uID0gY29udGV4dC5jcmVhdGVEZXZpY2VQcm90ZWN0ZWRTdG9yYWdlQ29udGV4dCgpLmdldEZpbGVzRGlyKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAgICAgICAgICJEaXJlY3QgYm9vdCBvbmx5IGV4aXN0cyBvbiBOIG9yIGdyZWF0ZXI6IGN1cnJlbnQgU0RLICVzIiwKKyAgICAgICAgICAgICAgICAgIEJ1aWxkLlZFUlNJT04uU0RLX0lOVCkpOworICAgICAgICB9CisKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEFuZHJvaWRVcmkuRElSRUNUX0JPT1RfQ0FDSEVfTE9DQVRJT046CisgICAgICAgIGlmIChCdWlsZC5WRVJTSU9OLlNES19JTlQgPj0gQnVpbGQuVkVSU0lPTl9DT0RFUy5OKSB7CisgICAgICAgICAgcm9vdExvY2F0aW9uID0gY29udGV4dC5jcmVhdGVEZXZpY2VQcm90ZWN0ZWRTdG9yYWdlQ29udGV4dCgpLmdldENhY2hlRGlyKCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAgICAgICAgICJEaXJlY3QgYm9vdCBvbmx5IGV4aXN0cyBvbiBOIG9yIGdyZWF0ZXI6IGN1cnJlbnQgU0RLICVzIiwKKyAgICAgICAgICAgICAgICAgIEJ1aWxkLlZFUlNJT04uU0RLX0lOVCkpOworICAgICAgICB9CisKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEFuZHJvaWRVcmkuRklMRVNfTE9DQVRJT046CisgICAgICAgIHJvb3RMb2NhdGlvbiA9IEFuZHJvaWRGaWxlRW52aXJvbm1lbnQuZ2V0RmlsZXNEaXJXaXRoUHJlTldvcmthcm91bmQoY29udGV4dCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBBbmRyb2lkVXJpLkNBQ0hFX0xPQ0FUSU9OOgorICAgICAgICByb290TG9jYXRpb24gPSBjb250ZXh0LmdldENhY2hlRGlyKCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBBbmRyb2lkVXJpLk1BTkFHRURfTE9DQVRJT046CisgICAgICAgIEZpbGUgZmlsZXNEaXIgPSBBbmRyb2lkRmlsZUVudmlyb25tZW50LmdldEZpbGVzRGlyV2l0aFByZU5Xb3JrYXJvdW5kKGNvbnRleHQpOworICAgICAgICByb290TG9jYXRpb24gPSBuZXcgRmlsZShmaWxlc0RpciwgQW5kcm9pZFVyaS5NQU5BR0VEX0ZJTEVTX0RJUl9TVUJESVJFQ1RPUlkpOworCisgICAgICAgIC8vIFRyYW5zZm9ybSBhY2NvdW50IHNlZ21lbnQgZnJvbSBsb2dpY2FsIChwbGFpbnRleHQpIHRvIHBoeXNpY2FsIChpbnRlZ2VyKSByZXByZXNlbnRhdGlvbi4KKyAgICAgICAgaWYgKHBhdGhTZWdtZW50cy5zaXplKCkgPj0gMykgeworICAgICAgICAgIEFjY291bnQgYWNjb3VudDsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgYWNjb3VudCA9IEFjY291bnRTZXJpYWxpemF0aW9uLmRlc2VyaWFsaXplKHBhdGhTZWdtZW50cy5nZXQoMikpOworICAgICAgICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVXJpRXhjZXB0aW9uKGUpOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoIUFjY291bnRTZXJpYWxpemF0aW9uLmlzU2hhcmVkQWNjb3VudChhY2NvdW50KSkgeworICAgICAgICAgICAgaWYgKGFjY291bnRNYW5hZ2VyID09IG51bGwpIHsKKyAgICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbigiQWNjb3VudE1hbmFnZXIgY2Fubm90IGJlIG51bGwiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIEJsb2NrcyBvbiBkaXNrIElPIHRvIHJlYWQgYWNjb3VudCB0YWJsZS4KKyAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgIGludCBhY2NvdW50SWQgPSBhY2NvdW50TWFuYWdlci5nZXRBY2NvdW50SWQoYWNjb3VudCkuZ2V0KCk7CisgICAgICAgICAgICAgIHBhdGhTZWdtZW50cy5zZXQoMiwgSW50ZWdlci50b1N0cmluZyhhY2NvdW50SWQpKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKKyAgICAgICAgICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbihlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKEV4ZWN1dGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgIC8vIFRPRE8oYi8xMTU5NDAzOTYpOiBzdXJmYWNlIGJhZCBhY2NvdW50IGFzIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiAoY2hhbmdlIHNpZ25hdHVyZT8pCisgICAgICAgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oZS5nZXRDYXVzZSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgQW5kcm9pZFVyaS5FWFRFUk5BTF9MT0NBVElPTjoKKyAgICAgICAgcm9vdExvY2F0aW9uID0gY29udGV4dC5nZXRFeHRlcm5hbEZpbGVzRGlyKG51bGwpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oCisgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KCJQYXRoIG11c3Qgc3RhcnQgd2l0aCBhIHZhbGlkIGxvZ2ljYWwgbG9jYXRpb246ICVzIiwgdXJpKSk7CisgICAgfQorICAgIHJldHVybiBuZXcgRmlsZSgKKyAgICAgICAgcm9vdExvY2F0aW9uLCBUZXh0VXRpbHMuam9pbihGaWxlLnNlcGFyYXRvciwgcGF0aFNlZ21lbnRzLnN1Ykxpc3QoMSwgcGF0aFNlZ21lbnRzLnNpemUoKSkpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0Fzc2V0RmlsZUJhY2tlbmQuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9Bc3NldEZpbGVCYWNrZW5kLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODY4OGIyNQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9Bc3NldEZpbGVCYWNrZW5kLmphdmEKQEAgLTAsMCArMSw5OSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kczsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5yZXMuQXNzZXRGaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQucmVzLkFzc2V0TWFuYWdlcjsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC51dGlsLlBhaXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5CYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuUHJlY29uZGl0aW9uczsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKiBCYWNrZW5kIGZvciBoYW5kbGluZyBBbmRyb2lkJ3MgQVBLIGVtYmVkZGVkIGFzc2V0cy4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBc3NldEZpbGVCYWNrZW5kIGltcGxlbWVudHMgQmFja2VuZCB7CisKKyAgcHJpdmF0ZSBmaW5hbCBBc3NldE1hbmFnZXIgYXNzZXRNYW5hZ2VyOworCisgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBidWlsZGVyKENvbnRleHQgY29udGV4dCkgeworICAgIHJldHVybiBuZXcgQnVpbGRlcihjb250ZXh0KTsKKyAgfQorCisgIC8qKiBCdWlsZHMgQXNzZXRGaWxlQmFja2VuZC4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIHsKKyAgICAvLyBSZXF1aXJlZCBwYXJhbWV0ZXJzCisgICAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisKKyAgICBwcml2YXRlIEJ1aWxkZXIoQ29udGV4dCBjb250ZXh0KSB7CisgICAgICBQcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoY29udGV4dCAhPSBudWxsLCAiQ29udGV4dCBjYW5ub3QgYmUgbnVsbCIpOworICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dC5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQXNzZXRGaWxlQmFja2VuZCBidWlsZCgpIHsKKyAgICAgIHJldHVybiBuZXcgQXNzZXRGaWxlQmFja2VuZCh0aGlzKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIEFzc2V0RmlsZUJhY2tlbmQoQnVpbGRlciBidWlsZGVyKSB7CisgICAgYXNzZXRNYW5hZ2VyID0gYnVpbGRlci5jb250ZXh0LmdldEFzc2V0cygpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgbmFtZSgpIHsKKyAgICByZXR1cm4gImFzc2V0IjsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgSW5wdXRTdHJlYW0gb3BlbkZvclJlYWQoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gYXNzZXRNYW5hZ2VyLm9wZW4oYXNzZXRQYXRoKHVyaSkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBQYWlyPFVyaSwgQ2xvc2VhYmxlPiBvcGVuRm9yTmF0aXZlUmVhZChVcmkgdXJpKSB0aHJvd3MgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbiB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oIk5hdGl2ZSByZWFkIG5vdCBzdXBwb3J0ZWQgKGIvMjEwNTQ2NDczKSIpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGV4aXN0cyhVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBvcGVuRm9yUmVhZCh1cmkpKSB7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgbG9uZyBmaWxlU2l6ZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSAoQXNzZXRGaWxlRGVzY3JpcHRvciBkZXNjcmlwdG9yID0gYXNzZXRNYW5hZ2VyLm9wZW5GZChhc3NldFBhdGgodXJpKSkpIHsKKyAgICAgIHJldHVybiBkZXNjcmlwdG9yLmdldExlbmd0aCgpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeShVcmkgdXJpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHJpdmF0ZSBTdHJpbmcgYXNzZXRQYXRoKFVyaSB1cmkpIHsKKyAgICBQcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoImFzc2V0Ii5lcXVhbHModXJpLmdldFNjaGVtZSgpKSwgInNjaGVtZSBtdXN0IGJlICdhc3NldCciKTsKKyAgICByZXR1cm4gdXJpLmdldFBhdGgoKS5zdWJzdHJpbmcoMSk7IC8vIHN0cmlwIGxlYWRpbmcgIi8iCisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZTkxOWU1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0JVSUxECkBAIC0wLDAgKzEsMjQzIEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9saWJyYXJ5IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbCisgICAgICAgICIvL3Zpc2liaWxpdHk6cHVibGljIiwKKyAgICBdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworIyBNb3N0IGNsaWVudHMgc2hvdWxkIGRlcGVuZCBvbiB0aGlzIHRhcmdldC4gSXQgZW5zdXJlcyB0aGF0IHRoZSAic3RhbmRhcmQiIHNjaGVtZXMKKyMgYXJlIGF2YWlsYWJsZS4gQ2FyZSB3aWxsIGJlIHRha2VuIHRvIGtlZXAgdGhlIHNpemUgc21hbGwuIEhvd2V2ZXIsIGlmIGEgY2xpZW50IHdhbnRzCisjIGV2ZW4gbW9yZSBncmFudWxhciBjb250cm9sIG9mIGRlcGVuZGVuY2llcywgaXQgY2FuIGRlcGVuZCBvbiBhIG5hcnJvd2VyIGJ1aWxkIHRhcmdldHMgYmVsb3cuCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJiYWNrZW5kcyIsCisgICAgZXhwb3J0cyA9IFsKKyAgICAgICAgIjphbmRyb2lkIiwKKyAgICAgICAgIjpmaWxlIiwKKyAgICAgICAgIjpmaWxlX2Rlc2NyaXB0b3IiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImFuZHJvaWQiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJBbmRyb2lkRmlsZUJhY2tlbmQuamF2YSIsCisgICAgICAgICJBbmRyb2lkVXJpLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjphY2NvdW50X21hbmFnZXIiLAorICAgICAgICAiOmFjY291bnRfc2VyaWFsaXphdGlvbiIsCisgICAgICAgICI6YW5kcm9pZF9hZGFwdGVyIiwKKyAgICAgICAgIjphbmRyb2lkX2ZpbGVfZW52aXJvbm1lbnQiLAorICAgICAgICAiOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpsaXRlX3RyYW5zZm9ybV9mcmFnbWVudHMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsOnByZWNvbmRpdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImJsb2JfdXJpIiwKKyAgICBzcmNzID0gWworICAgICAgICAiQmxvYlVyaS5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKKyMgSXQgbmVlZHMgdG8gYmUgYnVpbHQgYWdhaW5zdCBhIHN0YWJsZSBhbmRyb2lkIFNESywgZS5nLiAtLWFuZHJvaWRfc2RrPS8vdGhpcmRfcGFydHkvamF2YS9hbmRyb2lkL2FuZHJvaWRfc2RrX2xpbnV4L3BsYXRmb3Jtcy9zdGFibGU6YW5kcm9pZF9zZGtfdG9vbHMuCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJibG9ic3RvcmVfYmFja2VuZCIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkJsb2JTdG9yZUJhY2tlbmQuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOmJsb2JfdXJpIiwKKyAgICAgICAgIjpmaWxlX2Rlc2NyaXB0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiY29udGVudF9yZXNvbHZlciIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkNvbnRlbnRSZXNvbHZlckJhY2tlbmQuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOmZpbGVfZGVzY3JpcHRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsOnByZWNvbmRpdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJmaWxlX2Rlc2NyaXB0b3IiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJGaWxlRGVzY3JpcHRvclVyaS5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAjIE5PVEU6IGRlcGVuZGVuY3kgb2YgZ21zY29yZSBjbGllbnQgbGliIDxpbnRlcm5hbD4KKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJmaWxlIiwKKyAgICBzcmNzID0gWworICAgICAgICAiRmlsZVVyaS5qYXZhIiwKKyAgICAgICAgIkphdmFGaWxlQmFja2VuZC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6ZmlsZV9hZGFwdGVyIiwKKyAgICAgICAgIjpmaWxlX2Rlc2NyaXB0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpiYWNrZW5kX3N0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6bGl0ZV90cmFuc2Zvcm1fZnJhZ21lbnRzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOnByb3RvIiwKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAibWVtb3J5IiwKKyAgICBzcmNzID0gWworICAgICAgICAiTWVtb3J5QmFja2VuZC5qYXZhIiwKKyAgICAgICAgIk1lbW9yeVVyaS5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsOmxpdGVfdHJhbnNmb3JtX2ZyYWdtZW50cyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtczpwcm90byIsCisgICAgICAgICIvL3Byb3RvOnRyYW5zZm9ybV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImFzc2V0IiwKKyAgICBzcmNzID0gWworICAgICAgICAiQXNzZXRGaWxlQmFja2VuZC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJhbmRyb2lkX2FkYXB0ZXIiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJBbmRyb2lkVXJpLmphdmEiLAorICAgICAgICAiQW5kcm9pZFVyaUFkYXB0ZXIuamF2YSIsCisgICAgICAgICJVcmlBZGFwdGVyLmphdmEiLAorICAgIF0sCisgICAgdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjphY2NvdW50X21hbmFnZXIiLAorICAgICAgICAiOmFjY291bnRfc2VyaWFsaXphdGlvbiIsCisgICAgICAgICI6YW5kcm9pZF9maWxlX2Vudmlyb25tZW50IiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6bGl0ZV90cmFuc2Zvcm1fZnJhZ21lbnRzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpwcmVjb25kaXRpb25zIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJnZW5lcmljX2FkYXB0ZXIiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJHZW5lcmljVXJpQWRhcHRlci5qYXZhIiwKKyAgICAgICAgIlVyaUFkYXB0ZXIuamF2YSIsCisgICAgXSwKKyAgICB2aXNpYmlsaXR5ID0gWyIvLzpfX3N1YnBhY2thZ2VzX18iXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOmFuZHJvaWRfYWRhcHRlciIsCisgICAgICAgICI6ZmlsZSIsCisgICAgICAgICI6ZmlsZV9hZGFwdGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiZmlsZV9hZGFwdGVyIiwKKyAgICBzcmNzID0gWworICAgICAgICAiRmlsZVVyaUFkYXB0ZXIuamF2YSIsCisgICAgICAgICJVcmlBZGFwdGVyLmphdmEiLAorICAgIF0sCisgICAgdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgXSwKKykKKworIyBTaGFyZWQgbGlicmFyeSBjb2RlIHJlc3RyaWN0ZWQgdG8gdGhlIGludGVybmFsIHBhY2thZ2UgZ3JvdXAKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImFjY291bnRfc2VyaWFsaXphdGlvbiIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkFjY291bnRTZXJpYWxpemF0aW9uLmphdmEiLAorICAgIF0sCisgICAgdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpwcmVjb25kaXRpb25zIiwKKyAgICAgICAgIyBOT1RFOiBkZXBlbmRlbmN5IG9mIGdtc2NvcmUgY2xpZW50IGxpYiA8aW50ZXJuYWw+CisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiYWNjb3VudF9tYW5hZ2VyIiwKKyAgICBzcmNzID0gWworICAgICAgICAiQWNjb3VudE1hbmFnZXIuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKKyMgU2hhcmVkIGxpYnJhcnkgY29kZSByZXN0cmljdGVkIHRvIHRoZSBpbnRlcm5hbCBwYWNrYWdlIGdyb3VwCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJhbmRyb2lkX2ZpbGVfZW52aXJvbm1lbnQiLAorICAgIHNyY3MgPSBbIkFuZHJvaWRGaWxlRW52aXJvbm1lbnQuamF2YSJdLAorICAgIHZpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJ1cmlfbm9ybWFsaXplciIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlVyaU5vcm1hbGl6ZXIuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQmxvYlN0b3JlQmFja2VuZC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0Jsb2JTdG9yZUJhY2tlbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40OTdlZmMwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0Jsb2JTdG9yZUJhY2tlbmQuamF2YQpAQCAtMCwwICsxLDI0OSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kczsKKworaW1wb3J0IHN0YXRpYyBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdC5TRUNPTkRTOworCitpbXBvcnQgYW5kcm9pZC5hbm5vdGF0aW9uLlN1cHByZXNzTGludDsKK2ltcG9ydCBhbmRyb2lkLmFwcC5ibG9iLkJsb2JIYW5kbGU7CitpbXBvcnQgYW5kcm9pZC5hcHAuYmxvYi5CbG9iU3RvcmVNYW5hZ2VyOworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLm9zLlBhcmNlbEZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkxpbWl0RXhjZWVkZWRFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29tcGxldGFibGVGdXR1cmU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworCisvKioKKyAqIEJhY2tlbmQgZm9yIGFjY2Vzc2luZyB0aGUgQW5kcm9pZCBibG9iIFNoYXJpbmcgU2VydmljZS4KKyAqCisgKiA8cD5Gb3IgbW9yZSBkZXRhaWxzIHNlZSB7QGxpbmsgPGludGVybmFsPn0uCisgKgorICogPHA+U3VwcG9ydHMgcmVhZGluZywgd3JpdGluZywgZGVsZXRpbmcgYW5kIGV4aXN0czsgZXZlcnkgb3RoZXIgb3BlcmF0aW9uIHByb3ZpZGVkIGJ5IHRoZSB7QGxpbmsKKyAqIEJhY2tlbmR9IGludGVyZmFjZSB3aWxsIHRocm93IHtAbGluayBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9ufS4KKyAqCisgKiA8cD5Pbmx5IGF2YWlsYWJsZSB0byBBbmRyb2lkIFNESyA+PSBSLgorICovCitAU3VwcHJlc3NMaW50KHsiTmV3QXBpIiwgIldyb25nQ29uc3RhbnQifSkKK0BTdXBwcmVzc1dhcm5pbmdzKCJBbmRyb2lkSmRrTGlic0NoZWNrZXIiKQorcHVibGljIGZpbmFsIGNsYXNzIEJsb2JTdG9yZUJhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNRSA9ICJibG9ic3RvcmUiOworICAvLyBUT0RPKGIvMTQ5MjYwNDk2KTogYWNjZXB0IGEgY3VzdG9tIGxhYmVsIG9uY2UgYXZhaWxhYmxlIGluIHRoZSBmaWxlIGNvbmZpZy4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIExBQkVMID0gIlRoZSBmaWxlIGlzIHNoYXJlZCB0byBwcm92aWRlIGEgYmV0dGVyIHVzZXIgZXhwZXJpZW5jZSI7CisgIC8vIFRPRE8oYi8xNDkyNjA0OTYpOiBhY2NlcHQgYSBjdXN0b20gdGFnIG9uY2UgYXZhaWxhYmxlIGluIHRoZSBmaWxlIGNvbmZpZy4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJGaWxlIGRvd25sb2FkZWQgdGhyb3VnaCBNRERMaWIiOworICAvLyBFeHBpcnlEYXRlIHNldCB0byAwIHdpbGwgYmUgdHJlYXRlZCBhcyBleHBpcnlEYXRlIG5vbi1leGlzdGVudC4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBFWFBJUllfREFURSA9IDA7CisKKyAgcHJpdmF0ZSBmaW5hbCBCbG9iU3RvcmVNYW5hZ2VyIGJsb2JTdG9yZU1hbmFnZXI7CisKKyAgcHVibGljIEJsb2JTdG9yZUJhY2tlbmQoQ29udGV4dCBjb250ZXh0KSB7CisgICAgdGhpcy5ibG9iU3RvcmVNYW5hZ2VyID0gKEJsb2JTdG9yZU1hbmFnZXIpIGNvbnRleHQuZ2V0U3lzdGVtU2VydmljZShDb250ZXh0LkJMT0JfU1RPUkVfU0VSVklDRSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgIHJldHVybiBTQ0hFTUU7CisgIH0KKworICAvKiogVGhlIHVyaSBzaG91bGQgYmU6ICJibG9ic3RvcmU6Ly88cGFja2FnZV9uYW1lPi88bm9uX2VtcHR5X2NoZWNrc3VtPiIuICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBib29sZWFuIGV4aXN0cyA9IGZhbHNlOworICAgIHRyeSAoUGFyY2VsRmlsZURlc2NyaXB0b3IgcGZkID0gb3BlbkZvclJlYWRJbnRlcm5hbCh1cmkpKSB7CisgICAgICBpZiAocGZkICE9IG51bGwgJiYgcGZkLmdldEZpbGVEZXNjcmlwdG9yKCkudmFsaWQoKSkgeworICAgICAgICBleGlzdHMgPSB0cnVlOworICAgICAgfQorICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIEEgU2VjdXJpdHlFeGNlcHRpb24gaXMgdGhyb3duIHdoZW4gdGhlIGJsb2IgZG9lcyBub3QgZXhpc3Qgb3IgdGhlIGNhbGxlciBkb2VzIG5vdCBoYXZlCisgICAgICAvLyBhY2Nlc3MgdG8gaXQuCisgICAgfQorICAgIHJldHVybiBleGlzdHM7CisgIH0KKworICAvKiogVGhlIHVyaSBzaG91bGQgYmU6ICJibG9ic3RvcmU6Ly88cGFja2FnZV9uYW1lPi88bm9uX2VtcHR5X2NoZWNrc3VtPiIuICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgSW5wdXRTdHJlYW0gb3BlbkZvclJlYWQoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gbmV3IFBhcmNlbEZpbGVEZXNjcmlwdG9yLkF1dG9DbG9zZUlucHV0U3RyZWFtKG9wZW5Gb3JSZWFkSW50ZXJuYWwodXJpKSk7CisgIH0KKworICAvKiogVGhlIHVyaSBzaG91bGQgYmU6ICJibG9ic3RvcmU6Ly88cGFja2FnZV9uYW1lPi88bm9uX2VtcHR5X2NoZWNrc3VtPiIuICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgUGFpcjxVcmksIENsb3NlYWJsZT4gb3BlbkZvck5hdGl2ZVJlYWQoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gRmlsZURlc2NyaXB0b3JVcmkuZnJvbVBhcmNlbEZpbGVEZXNjcmlwdG9yKG9wZW5Gb3JSZWFkSW50ZXJuYWwodXJpKSk7CisgIH0KKworICBwcml2YXRlIFBhcmNlbEZpbGVEZXNjcmlwdG9yIG9wZW5Gb3JSZWFkSW50ZXJuYWwoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCbG9iVXJpLnZhbGlkYXRlVXJpKHVyaSk7CisgICAgYnl0ZVtdIGNoZWNrc3VtID0gQmxvYlVyaS5nZXRDaGVja3N1bSh1cmkuZ2V0UGF0aCgpKTsKKyAgICAvLyBUT0RPKGIvMTQ5MjYwNDk2KTogYWRkIG9wdGlvbiB0byBzZXQgYSBjdXN0b20gZXhwaXJ5RGF0ZSBpbiB0aGUgdXJpLgorICAgIEJsb2JIYW5kbGUgYmxvYkhhbmRsZSA9IEJsb2JIYW5kbGUuY3JlYXRlV2l0aFNoYTI1NihjaGVja3N1bSwgTEFCRUwsIEVYUElSWV9EQVRFLCBUQUcpOworICAgIHJldHVybiBibG9iU3RvcmVNYW5hZ2VyLm9wZW5CbG9iKGJsb2JIYW5kbGUpOworICB9CisKKyAgLyoqCisgICAqIFR3byBwb3NzaWJsZSBVUklzIGFyZSBhY2NlcHRlZDoKKyAgICoKKyAgICogPHVsPgorICAgKiAgIDxsaT4iYmxvYnN0b3JlOi8vPHBhY2thZ2VfbmFtZT4vPG5vbl9lbXB0eV9jaGVja3N1bT4iLiBBIG5ldyBibG9iIHdpbGwgYmUgd3JpdHRlbiBpbiB0aGUgYmxvYgorICAgKiAgICAgICBzdG9yYWdlLgorICAgKiAgIDxsaT4iYmxvYnN0b3JlOi8vPHBhY2thZ2VfbmFtZT4vPG5vbl9lbXB0eV9jaGVja3N1bT4ubGVhc2U/ZXhwaXJ5RGF0ZVNlY3M9PGV4cGlyeURhdGVTZWNzPi4iLgorICAgKiAgICAgICBBIGxlYXNlIHdpbGwgYmUgYWNxdWlyZWQgb24gdGhlIGJsb2Igc3BlY2lmaWVkIGJ5IHRoZSBlbmNvZGVkIGNoZWNrc3VtLgorICAgKiA8L3VsPgorICAgKgorICAgKiBAdGhyb3dzIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbiB3aGVuIHRoZSB7QGNvZGUgdXJpfSBpcyBtYWxmb3JtZWQuCisgICAqIEB0aHJvd3MgTGltaXRFeGNlZWRlZEV4Y2VwdGlvbiB3aGVuIHRoZSBjYWxsZXIgaXMgdHJ5aW5nIHRvIGNyZWF0ZSB0b28gbWFueSBzZXNzaW9ucywgYWNxdWlyZQorICAgKiAgICAgdG9vIG1hbnkgbGVhc2VzIG9yIGFjcXVpcmUgbGVhc2VzIG9uIHRvbyBtdWNoIGRhdGEuCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gd2hlbiB0aGVyZSBpcyBhbiBJL08gZXJyb3Igd2hpbGUgd3JpdGluZyB0aGUgYmxvYi9sZWFzZS4KKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3V0cHV0U3RyZWFtIG9wZW5Gb3JXcml0ZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEJsb2JVcmkudmFsaWRhdGVVcmkodXJpKTsKKyAgICBieXRlW10gY2hlY2tzdW0gPSBCbG9iVXJpLmdldENoZWNrc3VtKHVyaS5nZXRQYXRoKCkpOworICAgIHRyeSB7CisgICAgICBpZiAoQmxvYlVyaS5pc0xlYXNlVXJpKHVyaS5nZXRQYXRoKCkpKSB7CisgICAgICAgIC8vIFRPRE8oYi8xNDkyNjA0OTYpOiBwYXNzIGJsb2Igc2l6ZSBmcm9tIE1ERCB0byB0aGUgYmFja2VuZCBzbyB0aGF0IHRoZSBiYWNrZW5kIGNhbiBjaGVjaworICAgICAgICAvLyBpdCBhZ2FpbnN0IHRoZSByZW1haW5pbmcgcXVvdGEuCisgICAgICAgIGlmIChibG9iU3RvcmVNYW5hZ2VyLmdldFJlbWFpbmluZ0xlYXNlUXVvdGFCeXRlcygpIDw9IDApIHsKKyAgICAgICAgICB0aHJvdyBuZXcgTGltaXRFeGNlZWRlZEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgIlRoZSBjYWxsZXIgaXMgdHJ5aW5nIHRvIGFjcXVpcmUgYSBsZWFzZSBvbiB0b28gbXVjaCBkYXRhLiIpOworICAgICAgICB9CisgICAgICAgIGxvbmcgZXhwaXJ5RGF0ZU1pbGxpcyA9IFNFQ09ORFMudG9NaWxsaXMoQmxvYlVyaS5nZXRFeHBpcnlEYXRlU2Vjcyh1cmkpKTsKKyAgICAgICAgYWNxdWlyZUxlYXNlKGNoZWNrc3VtLCBleHBpcnlEYXRlTWlsbGlzKTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisKKyAgICAgIEJsb2JIYW5kbGUgYmxvYkhhbmRsZSA9IEJsb2JIYW5kbGUuY3JlYXRlV2l0aFNoYTI1NihjaGVja3N1bSwgTEFCRUwsIEVYUElSWV9EQVRFLCBUQUcpOworICAgICAgbG9uZyBzZXNzaW9uSWQgPSBibG9iU3RvcmVNYW5hZ2VyLmNyZWF0ZVNlc3Npb24oYmxvYkhhbmRsZSk7CisgICAgICBCbG9iU3RvcmVNYW5hZ2VyLlNlc3Npb24gc2Vzc2lvbiA9IGJsb2JTdG9yZU1hbmFnZXIub3BlblNlc3Npb24oc2Vzc2lvbklkKTsKKyAgICAgIHNlc3Npb24uYWxsb3dQdWJsaWNBY2Nlc3MoKTsKKyAgICAgIHJldHVybiBuZXcgU3VwZXJGaXJzdEF1dG9DbG9zZU91dHB1dFN0cmVhbShzZXNzaW9uLm9wZW5Xcml0ZSgwLCAtMSksIHNlc3Npb24pOworICAgIH0gY2F0Y2ggKGFuZHJvaWQub3MuTGltaXRFeGNlZWRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgTGltaXRFeGNlZWRlZEV4Y2VwdGlvbihlKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJGYWlsZWQgdG8gd3JpdGUgaW50byBCbG9iU3RvcmVNYW5hZ2VyIiwgZSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIFJlbGVhc2VzIHRoZSBsZWFzZShzKSBvbiB0aGUgYmxvYihzKSBzcGVjaWZpZWQgdGhyb3VnaCB0aGUge0Bjb2RlIHVyaX0uCisgICAqCisgICAqIDxwPlR3byBwb3NzaWJsZSBVUklzIGFyZSBhY2NlcHRlZDoKKyAgICoKKyAgICogPHVsPgorICAgKiAgIDxsaT4iYmxvYnN0b3JlOi8vPHBhY2thZ2VfbmFtZT4vPG5vbl9lbXB0eV9jaGVja3N1bT4iLiBUaGUgbGVhc2Ugb24gdGhlIGJsb2Igd2l0aCBjaGVja3N1bQorICAgKiAgICAgICA8bm9uX2VtcHR5X2NoZWNrc3VtPiB3aWxsIGJlIHJlbGVhc2VkLgorICAgKiAgIDxsaT4iYmxvYnN0b3JlOi8vPHBhY2thZ2VfbmFtZT4vKi5sZWFzZS4iLiBBbGwgbGVhc2VzIG93bmVkIGJ5IGNhbGxpbmcgcGFja2FnZSBpbiB0aGUgYmxvYgorICAgKiAgICAgICBzaGFyZWQgc3RvcmFnZSB3aWxsIGJlIHJlbGVhc2VkLgorICAgKiA8L3VsPgorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUZpbGUoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCbG9iVXJpLnZhbGlkYXRlVXJpKHVyaSk7CisgICAgaWYgKEJsb2JVcmkuaXNBbGxMZWFzZXNVcmkodXJpLmdldFBhdGgoKSkpIHsKKyAgICAgIHJlbGVhc2VBbGxMZWFzZXMoKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgYnl0ZVtdIGNoZWNrc3VtID0gQmxvYlVyaS5nZXRDaGVja3N1bSh1cmkuZ2V0UGF0aCgpKTsKKyAgICByZWxlYXNlTGVhc2UoY2hlY2tzdW0pOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHJlbGVhc2VBbGxMZWFzZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIExpc3Q8QmxvYkhhbmRsZT4gYmxvYkhhbmRsZXMgPSBibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCk7CisgICAgZm9yIChCbG9iSGFuZGxlIGJsb2JIYW5kbGUgOiBibG9iSGFuZGxlcykgeworICAgICAgcmVsZWFzZUxlYXNlKGJsb2JIYW5kbGUuZ2V0U2hhMjU2RGlnZXN0KCkpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeShVcmkgdXJpKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGFjcXVpcmVMZWFzZShieXRlW10gY2hlY2tzdW0sIGxvbmcgZXhwaXJ5RGF0ZU1pbGxpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBCbG9iSGFuZGxlIGJsb2JIYW5kbGUgPSBCbG9iSGFuZGxlLmNyZWF0ZVdpdGhTaGEyNTYoY2hlY2tzdW0sIExBQkVMLCBFWFBJUllfREFURSwgVEFHKTsKKyAgICAvLyBUT0RPKGIvMTQ5MjYwNDk2KTogcmVtb3ZlIGhhcmRjb2RlZCBkZXNjcmlwdGlvbi4KKyAgICAvLyBOT1RFOiBUaGUgbGVhc2UgZGVzY3JpcHRpb24gaXMgbWVhbnQgZm9yIHNwZWNpZnlpbmcgd2h5IHRoZSBhcHAgbmVlZHMgdGhlIGRhdGEgYmxvYiBhbmQKKyAgICAvLyBzaG91bGQgYmUgZ2VhcmVkIHRvd2FyZHMgZW5kIHVzZXJzLgorICAgIGJsb2JTdG9yZU1hbmFnZXIuYWNxdWlyZUxlYXNlKAorICAgICAgICBibG9iSGFuZGxlLAorICAgICAgICAiU3RyaW5nIGRlc2NyaXB0aW9uIG5lZWRlZCBmb3IgcHJvdmlkaW5nIGEgYmV0dGVyIHVzZXIgZXhwZXJpZW5jZSIsCisgICAgICAgIGV4cGlyeURhdGVNaWxsaXMpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHJlbGVhc2VMZWFzZShieXRlW10gY2hlY2tzdW0pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgQmxvYkhhbmRsZSBibG9iSGFuZGxlID0gQmxvYkhhbmRsZS5jcmVhdGVXaXRoU2hhMjU2KGNoZWNrc3VtLCBMQUJFTCwgRVhQSVJZX0RBVEUsIFRBRyk7CisgICAgdHJ5IHsKKyAgICAgIGJsb2JTdG9yZU1hbmFnZXIucmVsZWFzZUxlYXNlKGJsb2JIYW5kbGUpOworICAgIH0gY2F0Y2ggKFNlY3VyaXR5RXhjZXB0aW9uIHwgSWxsZWdhbFN0YXRlRXhjZXB0aW9uIHwgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRmFpbGVkIHRvIHJlbGVhc2UgdGhlIGxlYXNlIiwgZSk7CisgICAgfQorICB9CisKKyAgLy8gTk9URTogUGFyY2VsRmlsZURlc2NyaXB0b3IuQXV0b0Nsb3NlT3V0cHV0fElucHV0U3RyZWFtIGFyZSBhZmZlY3RlZCBieSBidWcgYi8xMTgzMTY5NTYuIFRoaXMKKyAgLy8gd2FzIGZpeGVkIGluIEFuZHJvaWQgUSBhbmQgdGhpcyBjbGFzcyByZXF1aXJlcyBBbmRyb2lkIFIsIHNvIHRoZXkgYXJlIHNhZmUgdG8gdXNlLgorICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTdXBlckZpcnN0QXV0b0Nsb3NlT3V0cHV0U3RyZWFtCisgICAgICBleHRlbmRzIFBhcmNlbEZpbGVEZXNjcmlwdG9yLkF1dG9DbG9zZU91dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBmaW5hbCBCbG9iU3RvcmVNYW5hZ2VyLlNlc3Npb24gc2Vzc2lvbjsKKyAgICBwcml2YXRlIGJvb2xlYW4gY29tbWl0QXR0ZW1wdGVkID0gZmFsc2U7CisKKyAgICBwdWJsaWMgU3VwZXJGaXJzdEF1dG9DbG9zZU91dHB1dFN0cmVhbSgKKyAgICAgICAgUGFyY2VsRmlsZURlc2NyaXB0b3IgcGZkLCBCbG9iU3RvcmVNYW5hZ2VyLlNlc3Npb24gc2Vzc2lvbikgeworICAgICAgc3VwZXIocGZkKTsKKyAgICAgIHRoaXMuc2Vzc2lvbiA9IHNlc3Npb247CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdHJ5IHsKKyAgICAgICAgc3VwZXIuY2xvc2UoKTsKKyAgICAgIH0gZmluYWxseSB7CisgICAgICAgIGNsb3NlRXZlcnl0aGluZygpOworICAgICAgfQorICAgIH0KKworICAgIHByaXZhdGUgdm9pZCBjbG9zZUV2ZXJ5dGhpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaW50IHJlc3VsdCA9IDA7CisgICAgICBFeGNlcHRpb24gY2F1c2UgPSBudWxsOworICAgICAgaWYgKCFjb21taXRBdHRlbXB0ZWQpIHsKKyAgICAgICAgLy8gQ29tbWl0IHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaWYgdGhlIHNlc3Npb24gd2FzIGFscmVhZHkgZmluYWxpemVkLCBzbyBhdm9pZAorICAgICAgICAvLyBjYWxsaW5nIGl0IG1vcmUgdGhhbiBvbmNlLiBXZSBjYW4gYXNzdW1lIENsb3NlYWJsZSBjbG9zZXMgYXJlIGlkZW1wb3RlbnQuCisgICAgICAgIGNvbW1pdEF0dGVtcHRlZCA9IHRydWU7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgQ29tcGxldGFibGVGdXR1cmU8SW50ZWdlcj4gY2FsbGJhY2sgPSBuZXcgQ29tcGxldGFibGVGdXR1cmU8PigpOworICAgICAgICAgIHNlc3Npb24uY29tbWl0KE1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3IoKSwgY2FsbGJhY2s6OmNvbXBsZXRlKTsKKyAgICAgICAgICByZXN1bHQgPSBjYWxsYmFjay5nZXQoKTsKKyAgICAgICAgfSBjYXRjaCAoRXhlY3V0aW9uRXhjZXB0aW9uIHwgSW50ZXJydXB0ZWRFeGNlcHRpb24gfCBSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICByZXN1bHQgPSAtMTsKKyAgICAgICAgICBjYXVzZSA9IGU7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHRyeSAoc2Vzc2lvbikgeworICAgICAgICBpZiAocmVzdWx0ICE9IDApIHsKKyAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNvbW1pdCBvcGVyYXRpb24gZmFpbGVkIiwgY2F1c2UpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQmxvYlVyaS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0Jsb2JVcmkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yOGIxNGU1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0Jsb2JVcmkuamF2YQpAQCAtMCwwICsxLDE4MCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kczsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnRleHQuVGV4dFV0aWxzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLk1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlNwbGl0dGVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmlvLkJhc2VFbmNvZGluZzsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqIEhlbHBlciBjbGFzcyBmb3IgImJsb2JzdG9yZSIgVVJJcy4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBCbG9iVXJpIHsKKyAgLy8gVXJpIHBhdGggY29uc3RhbnRzCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFNDSEVNRSA9ICJibG9ic3RvcmUiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTEVBU0VfVVJJX1NVRkZJWCA9ICIubGVhc2UiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0hFQ0tTVU1fU0VQQVJBVE9SID0gIi4iOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQUxMX0xFQVNFU19QQVRIID0gIioiICsgTEVBU0VfVVJJX1NVRkZJWDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFBBVEhfU0laRSA9IDE7CisgIC8vIFVyaSBxdWVyeSBjb25zdGFudHMKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFFVRVJZX1BBUkFNRVRFUlMgPSAxOyAvLyBBIHNpbmdsZSBxdWVyeSBlbGVtZW50IGNhbGxlZCBleHBpcnlEYXRlU2VjcworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhQSVJZX0RBVEVfUVVFUllfS0VZID0gImV4cGlyeURhdGVTZWNzIjsKKyAgLy8gTWFsZm9ybWVkRXhjZXB0aW9uIG1lc3NhZ2Ugc3RyaW5ncworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVhQRUNURURfQkxPQl9VUklfUEFUSCA9ICI8bm9uX2VtcHR5X2NoZWNrc3VtPiI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFWFBFQ1RFRF9MRUFTRV9VUklfUEFUSCA9ICI8bm9uX2VtcHR5X2NoZWNrc3VtPi5sZWFzZSI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFWFBFQ1RFRF9MRUFTRV9VUklfUVVFUlkgPSAiZXhwaXJ5RGF0ZVNlY3M9PGV4cGlyeURhdGVTZWNzPiI7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3BsaXR0ZXIgU1BMSVRURVIgPSBTcGxpdHRlci5vbihDSEVDS1NVTV9TRVBBUkFUT1IpOworCisgIC8qKiBSZXR1cm5zIGEgImJsb2JzdG9yZSIgc2NoZW1lIFVSSS4gKi8KKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIGJ1aWxkZXIoQ29udGV4dCBjb250ZXh0KSB7CisgICAgcmV0dXJuIG5ldyBCdWlsZGVyKGNvbnRleHQpOworICB9CisKKyAgcHJpdmF0ZSBCbG9iVXJpKCkge30KKworICBzdGF0aWMgdm9pZCB2YWxpZGF0ZVVyaShVcmkgdXJpKSB0aHJvd3MgTWFsZm9ybWVkVXJpRXhjZXB0aW9uIHsKKyAgICB2YWxpZGF0ZVBhdGgodXJpKTsKKyAgICB2YWxpZGF0ZVF1ZXJ5KHVyaSk7CisgIH0KKworICAvKioKKyAgICogVmFsaWRhdGVzIHRoZSBwYXRoIG9mIHRoZSAiYmxvYnN0b3JlIiBzY2hlbWUgVVJJLgorICAgKgorICAgKiA8cD5UaGVhcmUgb25seSB0d28gcGVybWl0dGVkIHBhdGhzOgorICAgKgorICAgKiA8dWw+CisgICAqICAgPGxpPjxub25fZW1wdHlfY2hlY2tzdW0+CisgICAqICAgPGxpPjxub25fZW1wdHlfY2hlY2tzdW0+LmxlYXNlCisgICAqIDwvdWw+CisgICAqLworICBwcml2YXRlIHN0YXRpYyB2b2lkIHZhbGlkYXRlUGF0aChVcmkgdXJpKSB0aHJvd3MgTWFsZm9ybWVkVXJpRXhjZXB0aW9uIHsKKyAgICBMaXN0PFN0cmluZz4gcGF0aFNlZ21lbnRzID0gdXJpLmdldFBhdGhTZWdtZW50cygpOworICAgIGlmIChwYXRoU2VnbWVudHMuc2l6ZSgpICE9IFBBVEhfU0laRSB8fCAhaGFzVmFsaWRDaGVja3N1bUV4dGVuc2lvbihwYXRoU2VnbWVudHMuZ2V0KDApKSkgeworICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbigKKyAgICAgICAgICBTdHJpbmcuZm9ybWF0KAorICAgICAgICAgICAgICAiVGhlIHVyaSBpcyBtYWxmb3JtZWQsIGV4cGVjdGVkICVzIG9yICVzIGJ1dCBmb3VuZCAlcyIsCisgICAgICAgICAgICAgIEVYUEVDVEVEX0JMT0JfVVJJX1BBVEgsIEVYUEVDVEVEX0xFQVNFX1VSSV9QQVRILCB1cmkuZ2V0UGF0aCgpKSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBoYXNWYWxpZENoZWNrc3VtRXh0ZW5zaW9uKFN0cmluZyBwYXRoKSB7CisgICAgcmV0dXJuIFNQTElUVEVSLnNwbGl0VG9MaXN0KHBhdGgpLnNpemUoKSA9PSAxCisgICAgICAgIHx8IChpc0xlYXNlVXJpKHBhdGgpICYmICFUZXh0VXRpbHMuZXF1YWxzKHBhdGgsIExFQVNFX1VSSV9TVUZGSVgpKTsKKyAgfQorCisgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIHBhdGggaXMgb2YgdHlwZSAiPGNoZWNrc3VtPi5sZWFzZSIuICovCisgIHN0YXRpYyBib29sZWFuIGlzTGVhc2VVcmkoU3RyaW5nIHBhdGgpIHsKKyAgICByZXR1cm4gcGF0aC5lbmRzV2l0aChMRUFTRV9VUklfU1VGRklYKTsKKyAgfQorCisgIC8qKiBSZXR1cm5zIHRydWUgaWYgdGhlIHBhdGggbWF0Y2hlcyAiKi5sZWFzZSIuICovCisgIHN0YXRpYyBib29sZWFuIGlzQWxsTGVhc2VzVXJpKFN0cmluZyBwYXRoKSB7CisgICAgaWYgKHBhdGguc3RhcnRzV2l0aCgiLyIpKSB7CisgICAgICBwYXRoID0gcGF0aC5zdWJzdHJpbmcoMSk7CisgICAgfQorICAgIHJldHVybiBUZXh0VXRpbHMuZXF1YWxzKHBhdGgsIEFMTF9MRUFTRVNfUEFUSCk7CisgIH0KKworICAvKioKKyAgICogSWYgYXZhaWxhYmxlLCB2YWxpZGF0ZXMgdGhlIHF1ZXJ5IHBhcnQgb2YgdGhlICJibG9ic3RvcmUiIHNjaGVtZSBVUkkuCisgICAqCisgICAqIDxwPlRoZXJlIGlzIG9uZSBwZXJtaXR0ZWQgcXVlcnkgcGFyYW1ldGVyOiBleHBpcnlEYXRlU2Vjcz08ZXhwaXJ5RGF0ZVNlY3M+LgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCB2YWxpZGF0ZVF1ZXJ5KFVyaSB1cmkpIHRocm93cyBNYWxmb3JtZWRVcmlFeGNlcHRpb24geworICAgIGlmIChUZXh0VXRpbHMuaXNFbXB0eSh1cmkuZ2V0UXVlcnkoKSkpIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWYgKHVyaS5nZXRRdWVyeVBhcmFtZXRlck5hbWVzKCkuc2l6ZSgpICE9IFFVRVJZX1BBUkFNRVRFUlMKKyAgICAgICAgfHwgdXJpLmdldFF1ZXJ5UGFyYW1ldGVyKEVYUElSWV9EQVRFX1FVRVJZX0tFWSkgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbigKKyAgICAgICAgICBTdHJpbmcuZm9ybWF0KAorICAgICAgICAgICAgICAiVGhlIHVyaSBxdWVyeSBpcyBtYWxmb3JtZWQsIGV4cGVjdGVkICVzIGJ1dCBmb3VuZCBxdWVyeSAlcyIsCisgICAgICAgICAgICAgIEVYUEVDVEVEX0xFQVNFX1VSSV9RVUVSWSwgdXJpLmdldFF1ZXJ5KCkpKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB0aGUgY2hlY2tzdW0gYnl0ZXMgZW5jb2RlZCBpbiB0aGUge0Bjb2RlIHBhdGh9LgorICAgKgorICAgKiA8cD5UbyBkZWNvZGUgdGhlIGJ5dGVzIGZyb20gdGhlIHBhdGgsIGl0IHVzZXMgdGhlIHNhbWUgZW5jb2RpbmcgdXNlZCBieSB7QGNvZGUgLy8KKyAgICogY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZG93bmxvYWRlci5GaWxlVmFsaWRhdG9yfS4KKyAgICovCisgIHN0YXRpYyBieXRlW10gZ2V0Q2hlY2tzdW0oU3RyaW5nIHBhdGgpIHsKKyAgICBpZiAocGF0aC5zdGFydHNXaXRoKCIvIikpIHsKKyAgICAgIHBhdGggPSBwYXRoLnN1YnN0cmluZygxKTsKKyAgICB9CisgICAgcmV0dXJuIEJhc2VFbmNvZGluZy5iYXNlMTYoKS5sb3dlckNhc2UoKS5kZWNvZGUoU1BMSVRURVIuc3BsaXRUb0xpc3QocGF0aCkuZ2V0KDApKTsKKyAgfQorCisgIC8qIFBhcnNlcyB0aGUge0Bjb2RlIHF1ZXJ5fSBhbmQgcmV0dXJucyB0aGUgZW5jb2RlZCB7QGNvZGUgZXhwaXJ5RGF0ZVNlY3N9LiAqLworICBzdGF0aWMgbG9uZyBnZXRFeHBpcnlEYXRlU2VjcyhVcmkgdXJpKSB0aHJvd3MgTWFsZm9ybWVkVXJpRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgcXVlcnkgPSB1cmkuZ2V0UXVlcnkoKTsKKyAgICBpZiAoVGV4dFV0aWxzLmlzRW1wdHkocXVlcnkpKSB7CisgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVXJpRXhjZXB0aW9uKAorICAgICAgICAgIFN0cmluZy5mb3JtYXQoIlRoZSB1cmkgcXVlcnkgaXMgbnVsbCBvciBlbXB0eSwgZXhwZWN0ZWQgJXMiLCBFWFBFQ1RFRF9MRUFTRV9VUklfUVVFUlkpKTsKKyAgICB9CisgICAgU3RyaW5nIGV4cGlyeURhdGVTZWNzU3RyaW5nID0gdXJpLmdldFF1ZXJ5UGFyYW1ldGVyKEVYUElSWV9EQVRFX1FVRVJZX0tFWSk7CisgICAgaWYgKGV4cGlyeURhdGVTZWNzU3RyaW5nID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oCisgICAgICAgICAgU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAgICAgIlRoZSB1cmkgcXVlcnkgaXMgbWFsZm9ybWVkLCBleHBlY3RlZCAlcyBidXQgZm91bmQgJXMiLAorICAgICAgICAgICAgICBFWFBFQ1RFRF9MRUFTRV9VUklfUVVFUlksIHF1ZXJ5KSk7CisgICAgfQorICAgIGxvbmcgZXhwaXJ5RGF0ZVNlY3MgPSBMb25nLnBhcnNlTG9uZyhleHBpcnlEYXRlU2Vjc1N0cmluZyk7CisgICAgcmV0dXJuIGV4cGlyeURhdGVTZWNzOworICB9CisKKyAgLyoqIEEgYnVpbGRlciBmb3IgImJsb2JzdG9yZSIgc2NoZW1lIFVyaXMuICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQnVpbGRlciB7CisgICAgcHJpdmF0ZSBTdHJpbmcgcGF0aCA9ICIiOworICAgIHByaXZhdGUgU3RyaW5nIHBhY2thZ2VOYW1lID0gIiI7CisgICAgcHJpdmF0ZSBsb25nIGV4cGlyeURhdGVTZWNzOworCisgICAgcHJpdmF0ZSBCdWlsZGVyKENvbnRleHQgY29udGV4dCkgeworICAgICAgLy8gVE9ETyhiLzE0OTI2MDQ5Nik6IHJlbW92ZS9jaGFuZ2UgbWVhbmluZyB0byBwYWNrYWdlTmFtZQorICAgICAgdGhpcy5wYWNrYWdlTmFtZSA9IGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBzZXRCbG9iUGFyYW1ldGVycyhTdHJpbmcgY2hlY2tzdW0pIHsKKyAgICAgIHBhdGggPSBjaGVja3N1bTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyIHNldExlYXNlUGFyYW1ldGVycyhTdHJpbmcgY2hlY2tzdW0sIGxvbmcgZXhwaXJ5RGF0ZVNlY3MpIHsKKyAgICAgIHBhdGggPSBjaGVja3N1bSArIExFQVNFX1VSSV9TVUZGSVg7CisgICAgICB0aGlzLmV4cGlyeURhdGVTZWNzID0gZXhwaXJ5RGF0ZVNlY3M7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBzZXRBbGxMZWFzZXNQYXJhbWV0ZXJzKCkgeworICAgICAgcGF0aCA9IEFMTF9MRUFTRVNfUEFUSDsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBVcmkgYnVpbGQoKSB0aHJvd3MgTWFsZm9ybWVkVXJpRXhjZXB0aW9uIHsKKyAgICAgIFVyaS5CdWlsZGVyIHVyaUJ1aWxkZXIgPSBuZXcgVXJpLkJ1aWxkZXIoKS5zY2hlbWUoU0NIRU1FKS5hdXRob3JpdHkocGFja2FnZU5hbWUpLnBhdGgocGF0aCk7CisgICAgICBpZiAoaXNMZWFzZVVyaShwYXRoKSAmJiAhaXNBbGxMZWFzZXNVcmkocGF0aCkpIHsKKyAgICAgICAgdXJpQnVpbGRlci5hcHBlbmRRdWVyeVBhcmFtZXRlcihFWFBJUllfREFURV9RVUVSWV9LRVksIFN0cmluZy52YWx1ZU9mKGV4cGlyeURhdGVTZWNzKSk7CisgICAgICB9CisgICAgICBVcmkgdXJpID0gdXJpQnVpbGRlci5idWlsZCgpOworICAgICAgdmFsaWRhdGVVcmkodXJpKTsKKyAgICAgIHJldHVybiB1cmk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQ29udGVudFJlc29sdmVyQmFja2VuZC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0NvbnRlbnRSZXNvbHZlckJhY2tlbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YzMxNzQ3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0NvbnRlbnRSZXNvbHZlckJhY2tlbmQuamF2YQpAQCAtMCwwICsxLDExMyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kczsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLm9zLlBhcmNlbEZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLk1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbC5QcmVjb25kaXRpb25zOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworCisvKioKKyAqIEEgYmFja2VuZCBmb3IgYWNjZXNzaW5nIHJlbW90ZSBjb250ZW50IHRoYXQgdXNlcyB0aGUgQW5kcm9pZCBwbGF0Zm9ybSBjb250ZW50IHJlc29sdmVyIGZyYW1ld29yay4KKyAqIEl0IGNhbiBiZSB1c2VkIHN0YW5kYWxvbmUgb3IgYXMgYSByZW1vdGUgVVJJIHJlc29sdmVyIHdpdGhpbiB0aGUge0BsaW5rIEFuZHJvaWRGaWxlQmFja2VuZH0uCisgKgorICogPHA+VXNhZ2U6IDxjb2RlPgorICogQW5kcm9pZEZpbGVCYWNrZW5kIGJhY2tlbmQgPQorICogICAgIEFuZHJvaWRGaWxlQmFja2VuZC5idWlsZGVyKGNvbnRleHQpCisgKiAgICAgICAgIC5zZXRSZW1vdGVCYWNrZW5kKENvbnRlbnRSZXNvbHZlckJhY2tlbmQuYnVpbGRlcihjb250ZXh0KS5zZXRFbWJlZGRlZCh0cnVlKS5idWlsZCgpKQorICogICAgICAgICAuYnVpbGQoKTsKKyAqIDwvY29kZT4KKyAqCisgKiA8cD5OT1RFOiBJbiBtb3N0IGNhc2VzLCB5b3UnbGwgd2FudCB0byB1c2UgdGhlIEdtc0NsaWVudEJhY2tlbmQgZm9yIGFjY2Vzc2luZyBmaWxlcyBmcm9tIEdNUworICogY29yZS4gVGhpcyBiYWNrZW5kIGlzIHVzZWQgdG8gYWNjZXNzIGZpbGVzIGZyb20gb3RoZXIgQXBwcy4gU2luY2UgdGhlcmUgYXJlIHBvc3NpYmxlIHNlY3VyaXR5CisgKiBjb25jZXJucyB3aXRoIGRvaW5nIHNvLCBDb250ZW50UmVzb2x2ZXJCYWNrZW5kIGlzIHJlc3RyaWN0ZWQgdG8gdGhlICJjb250ZW50X3Jlc29sdmVyX2FsbG93bGlzdCIuCisgKiBTZWUgPGludGVybmFsPiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIENvbnRlbnRSZXNvbHZlckJhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVEVOVF9TQ0hFTUUgPSAiY29udGVudCI7CisKKyAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBpc0VtYmVkZGVkOworCisgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBidWlsZGVyKENvbnRleHQgY29udGV4dCkgeworICAgIHJldHVybiBuZXcgQnVpbGRlcihjb250ZXh0KTsKKyAgfQorCisgIC8qKiBCdWlsZGVyIGZvciB7QGNvZGUgQ29udGVudFJlc29sdmVyQmFja2VuZH0uICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgQnVpbGRlciB7CisgICAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisgICAgcHJpdmF0ZSBib29sZWFuIGlzRW1iZWRkZWQgPSBmYWxzZTsKKworICAgIC8qKiBDb25zdHJ1Y3QgYSBuZXcgYnVpbGRlciBpbnN0YW5jZS4gKi8KKyAgICBwcml2YXRlIEJ1aWxkZXIoQ29udGV4dCBjb250ZXh0KSB7CisgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OworICAgIH0KKworICAgIC8qKgorICAgICAqIFRlbGxzIHdoZXRoZXIgdGhpcyBiYWNrZW5kIGlzIGV4cGVjdGVkIHRvIGJlIGVtYmVkZGVkIGluIGFub3RoZXIgYmFja2VuZC4gSWYgc28sIHJld3JpdGVzIHRoZQorICAgICAqIHNjaGVtZSB0byAiY29udGVudCI7IGlmIG5vdCwgcmVxdWlyZXMgdGhhdCB0aGUgc2NoZW1lIGJlICJjb250ZW50Ii4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVpbGRlciBzZXRFbWJlZGRlZChib29sZWFuIGlzRW1iZWRkZWQpIHsKKyAgICAgIHRoaXMuaXNFbWJlZGRlZCA9IGlzRW1iZWRkZWQ7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgQ29udGVudFJlc29sdmVyQmFja2VuZCBidWlsZCgpIHsKKyAgICAgIHJldHVybiBuZXcgQ29udGVudFJlc29sdmVyQmFja2VuZChjb250ZXh0LCBpc0VtYmVkZGVkKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIENvbnRlbnRSZXNvbHZlckJhY2tlbmQoQ29udGV4dCBjb250ZXh0LCBib29sZWFuIGlzRW1iZWRkZWQpIHsKKyAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0LmdldEFwcGxpY2F0aW9uQ29udGV4dCgpOworICAgIHRoaXMuaXNFbWJlZGRlZCA9IGlzRW1iZWRkZWQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgIFByZWNvbmRpdGlvbnMuY2hlY2tTdGF0ZSghaXNFbWJlZGRlZCwgIk1pc2NvbmZpZ3VyZWQgZW1iZWRkZWQgYmFja2VuZC4iKTsKKyAgICByZXR1cm4gQ09OVEVOVF9TQ0hFTUU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIG9wZW5Gb3JSZWFkKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgVXJpIGNvbnRlbnRVcmkgPSByZXdyaXRlQW5kQ2hlY2tVcmkodXJpKTsKKyAgICByZXR1cm4gY29udGV4dC5nZXRDb250ZW50UmVzb2x2ZXIoKS5vcGVuSW5wdXRTdHJlYW0oY29udGVudFVyaSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFBhaXI8VXJpLCBDbG9zZWFibGU+IG9wZW5Gb3JOYXRpdmVSZWFkKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgVXJpIGNvbnRlbnRVcmkgPSByZXdyaXRlQW5kQ2hlY2tVcmkodXJpKTsKKyAgICBQYXJjZWxGaWxlRGVzY3JpcHRvciBwZmQgPSBjb250ZXh0LmdldENvbnRlbnRSZXNvbHZlcigpLm9wZW5GaWxlRGVzY3JpcHRvcihjb250ZW50VXJpLCAiciIpOworICAgIHJldHVybiBGaWxlRGVzY3JpcHRvclVyaS5mcm9tUGFyY2VsRmlsZURlc2NyaXB0b3IocGZkKTsKKyAgfQorCisgIHByaXZhdGUgVXJpIHJld3JpdGVBbmRDaGVja1VyaShVcmkgdXJpKSB0aHJvd3MgTWFsZm9ybWVkVXJpRXhjZXB0aW9uIHsKKyAgICBpZiAoaXNFbWJlZGRlZCkgeworICAgICAgcmV0dXJuIHVyaS5idWlsZFVwb24oKS5zY2hlbWUoQ09OVEVOVF9TQ0hFTUUpLmJ1aWxkKCk7CisgICAgfQorICAgIGlmICghQ09OVEVOVF9TQ0hFTUUuZXF1YWxzKHVyaS5nZXRTY2hlbWUoKSkpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oIkV4cGVjdGVkIHNjaGVtZSB0byBiZSAiICsgQ09OVEVOVF9TQ0hFTUUpOworICAgIH0KKyAgICByZXR1cm4gdXJpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvRmlsZURlc2NyaXB0b3JVcmkuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9GaWxlRGVzY3JpcHRvclVyaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjNTA0MWEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvRmlsZURlc2NyaXB0b3JVcmkuamF2YQpAQCAtMCwwICsxLDU5IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuUGFyY2VsRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgYW5kcm9pZC51dGlsLlBhaXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uTWFsZm9ybWVkVXJpRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworCisvKioKKyAqIEhlbHBlciBjbGFzcyBmb3IgImZkOiIgVVJJcyB0aGF0IHJlZmVyIHRvIGZpbGUgZGVzY3JpcHRvcnMuIFRoZSBvcGFxdWUgcGFydCBvZiB0aGVzZSBVUklzIGlzCisgKiBzaW1wbHkgdGhlIGZpbGUgZGVzY3JpcHRvciBpbnQgdmFsdWUgc3RyaW5naWZpZWQuIFRoZXNlIFVSSXMgYXJlIHRyYW5zaWVudCBhbmQgc2hvdWxkIG5ldmVyIGJlCisgKiBzdG9yZWQuCisgKgorICogPHA+VGhlIHByaW1hcnkgdXNlIGNhc2UgaXMgZmV0Y2hpbmcgYSBQYXJjZWxGaWxlRGVzY3JpcHRvciBmcm9tIEphdmEgYW5kIHBhc3NpbmcgdGhhdCBkb3duIHRvCisgKiBuYXRpdmUgY29kZS4gVGhlIFVSSSBpcyBwYWlyZWQgd2l0aCBhIGNsb3NlciB3aGljaCBtdXN0IGJlIGNhbGxlZCB0byBmcmVlIHN5c3RlbSByZXNvdXJjZXMuIEphdmEKKyAqIGNhbiBkbyBzbyBpbW1lZGlhdGVseSBhZnRlciBwYXNzaW5nIHRoZSBVUkkgdG8gbmF0aXZlOyBpZiB0aGUgbmF0aXZlIGZkIGJhY2tlbmQgbmVlZHMgdG8ga2VlcCB0aGUKKyAqIGZpbGUgZGVzY3JpcHRvciBmb3IgbG9uZ2VyLCBpdCB3aWxsIG1ha2UgYSBkdXBsaWNhdGUuCisgKgorICogPHA+VE9ETzogSmF2YSBpbXBsZW1lbnRhdGlvbiBvZiBmaWxlIGRlc2NyaXB0b3IgYmFja2VuZC4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEZpbGVEZXNjcmlwdG9yVXJpIHsKKworICAvKiogQ3JlYXRlIGEgcGFpciBvZiBVUkkgYW5kIGNsb3NlciBmb3IgdW5kZXJseWluZyByZXNvdXJjZXMgZnJvbSBhIFBhcmNlbEZpbGVEZXNjcmlwdG9yLiAqLworICBwdWJsaWMgc3RhdGljIFBhaXI8VXJpLCBDbG9zZWFibGU+IGZyb21QYXJjZWxGaWxlRGVzY3JpcHRvcihQYXJjZWxGaWxlRGVzY3JpcHRvciBwZmQpIHsKKyAgICBpbnQgZmQgPSBwZmQuZ2V0RmQoKTsKKyAgICBVcmkgdXJpID0gbmV3IFVyaS5CdWlsZGVyKCkuc2NoZW1lKCJmZCIpLm9wYXF1ZVBhcnQoU3RyaW5nLnZhbHVlT2YoZmQpKS5idWlsZCgpOworICAgIC8vIE5PVEU6IFBhcmNlbEZpbGVEZXNjcmlwdG9yIGRvZXNuJ3QgaW1wbGVtZW50IENsb3NlYWJsZSBvbiBTREsgMTUsIHNvIHdlIG5lZWQgdG8gd3JhcAorICAgIHJldHVybiBQYWlyLmNyZWF0ZSh1cmksICgpIC0+IHBmZC5jbG9zZSgpKTsKKyAgfQorCisgIC8qKiBHZXRzIHRoZSBpbnRlZ2VyIGZpbGUgZGVzY3JpcHRvciBmcm9tIHRoaXMgVVJJLiAqLworICBwdWJsaWMgc3RhdGljIGludCBnZXRGZChVcmkgdXJpKSB0aHJvd3MgTWFsZm9ybWVkVXJpRXhjZXB0aW9uIHsKKyAgICBpZiAoIXVyaS5nZXRTY2hlbWUoKS5lcXVhbHMoImZkIikpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oIlNjaGVtZSBtdXN0IGJlICdmZCciKTsKKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KHVyaS5nZXRTY2hlbWVTcGVjaWZpY1BhcnQoKSk7CisgICAgfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBGaWxlRGVzY3JpcHRvclVyaSgpIHt9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvRmlsZVVyaS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0ZpbGVVcmkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OGY5NTA4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0ZpbGVVcmkuamF2YQpAQCAtMCwwICsxLDc0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLkxpdGVUcmFuc2Zvcm1GcmFnbWVudHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLlRyYW5zZm9ybVByb3RvczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuVHJhbnNmb3JtUHJvdG87CitpbXBvcnQgamF2YS5pby5GaWxlOworCisvKiogSGVscGVyIGNsYXNzIGZvciAiZmlsZToiIFVyaXMuIFRPRE8oYi82MjEwNjU2NCkgUmVuYW1lIHRvICJsb2NhbGZpbGUiLiAqLworcHVibGljIGZpbmFsIGNsYXNzIEZpbGVVcmkgeworCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0NIRU1FX05BTUUgPSAiZmlsZSI7CisKKyAgLyoqIENyZWF0ZXMgYSBmaWxlOiBzY2hlbWUgVVJJIGJ1aWxkZXIuICovCisgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBidWlsZGVyKCkgeworICAgIHJldHVybiBuZXcgQnVpbGRlcigpOworICB9CisKKyAgLyoqIEJ1aWxkcyBhIFVSSSBmcm9tIGEgRmlsZS4gKi8KKyAgcHVibGljIHN0YXRpYyBVcmkgZnJvbUZpbGUoRmlsZSBmaWxlKSB7CisgICAgcmV0dXJuIGJ1aWxkZXIoKS5mcm9tRmlsZShmaWxlKS5idWlsZCgpOworICB9CisKKyAgcHJpdmF0ZSBGaWxlVXJpKCkge30KKworICAvKiogQSBidWlsZGVyIGZvciBmaWxlOiBzY2hlbWUgVVJJcy4gKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBCdWlsZGVyIHsKKyAgICBwcml2YXRlIFVyaS5CdWlsZGVyIHVyaSA9IG5ldyBVcmkuQnVpbGRlcigpLnNjaGVtZSgiZmlsZSIpLmF1dGhvcml0eSgiIikucGF0aCgiLyIpOworICAgIHByaXZhdGUgZmluYWwgSW1tdXRhYmxlTGlzdC5CdWlsZGVyPFN0cmluZz4gZW5jb2RlZFNwZWNzID0gSW1tdXRhYmxlTGlzdC5idWlsZGVyKCk7CisKKyAgICBwcml2YXRlIEJ1aWxkZXIoKSB7fQorCisgICAgcHVibGljIEJ1aWxkZXIgc2V0UGF0aChTdHJpbmcgcGF0aCkgeworICAgICAgdXJpLnBhdGgocGF0aCk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciBmcm9tRmlsZShGaWxlIGZpbGUpIHsKKyAgICAgIHVyaS5wYXRoKGZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIEJ1aWxkZXIgYXBwZW5kUGF0aChTdHJpbmcgc2VnbWVudCkgeworICAgICAgdXJpLmFwcGVuZFBhdGgoc2VnbWVudCk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgQnVpbGRlciB3aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybSBzcGVjKSB7CisgICAgICBlbmNvZGVkU3BlY3MuYWRkKFRyYW5zZm9ybVByb3Rvcy50b0VuY29kZWRTcGVjKHNwZWMpKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBVcmkgYnVpbGQoKSB7CisgICAgICBTdHJpbmcgZnJhZ21lbnQgPSBMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLmpvaW5UcmFuc2Zvcm1TcGVjcyhlbmNvZGVkU3BlY3MuYnVpbGQoKSk7CisgICAgICByZXR1cm4gdXJpLmVuY29kZWRGcmFnbWVudChmcmFnbWVudCkuYnVpbGQoKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9GaWxlVXJpQWRhcHRlci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0ZpbGVVcmlBZGFwdGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWE3M2YwNgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9GaWxlVXJpQWRhcHRlci5qYXZhCkBAIC0wLDAgKzEsNTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC50ZXh0LlRleHRVdGlsczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5NYWxmb3JtZWRVcmlFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5GaWxlOworCisvKioKKyAqIEFkYXB0ZXIgZm9yIGNvbnZlcnRpbmcgImZpbGU6IiBVUklzIGludG8gamF2YS5pby5GaWxlLiBUaGlzIGlzIGNvbnNpZGVyZWQgZGFuZ2Vyb3VzIHNpbmNlIGl0CisgKiBpZ25vcmVzIHBhcnRzIG9mIHRoZSBVcmkgYXQgdGhlIGNhbGxlcidzIHBlcmlsLCBhbmQgdGh1cyBpcyBvbmx5IGF2YWlsYWJsZSB0byBhbGxvd2xpc3RlZCBjbGllbnRzCisgKiAobW9zdGx5IGludGVybmFsKS4KKyAqLworcHVibGljIGNsYXNzIEZpbGVVcmlBZGFwdGVyIGltcGxlbWVudHMgVXJpQWRhcHRlciB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmlsZVVyaUFkYXB0ZXIgSU5TVEFOQ0UgPSBuZXcgRmlsZVVyaUFkYXB0ZXIoKTsKKworICBwcml2YXRlIEZpbGVVcmlBZGFwdGVyKCkge30KKworICBwdWJsaWMgc3RhdGljIEZpbGVVcmlBZGFwdGVyIGluc3RhbmNlKCkgeworICAgIHJldHVybiBJTlNUQU5DRTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgRmlsZSB0b0ZpbGUoVXJpIHVyaSkgdGhyb3dzIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbiB7CisgICAgaWYgKCF1cmkuZ2V0U2NoZW1lKCkuZXF1YWxzKCJmaWxlIikpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oIlNjaGVtZSBtdXN0IGJlICdmaWxlJyIpOworICAgIH0KKyAgICBpZiAoIVRleHRVdGlscy5pc0VtcHR5KHVyaS5nZXRRdWVyeSgpKSkgeworICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbigiRGlkIG5vdCBleHBlY3QgdXJpIHRvIGhhdmUgcXVlcnkiKTsKKyAgICB9CisgICAgaWYgKCFUZXh0VXRpbHMuaXNFbXB0eSh1cmkuZ2V0QXV0aG9yaXR5KCkpKSB7CisgICAgICB0aHJvdyBuZXcgTWFsZm9ybWVkVXJpRXhjZXB0aW9uKCJEaWQgbm90IGV4cGVjdCB1cmkgdG8gaGF2ZSBhdXRob3JpdHkiKTsKKyAgICB9CisgICAgcmV0dXJuIG5ldyBGaWxlKHVyaS5nZXRQYXRoKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvR2VuZXJpY1VyaUFkYXB0ZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9HZW5lcmljVXJpQWRhcHRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVlMjQ0ZjIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvR2VuZXJpY1VyaUFkYXB0ZXIuamF2YQpAQCAtMCwwICsxLDUzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLk1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CisKKy8qKgorICogQWRhcHRlciBmb3IgY29udmVydGluZyAiYW5kcm9pZDoiIFVSSXMgaW50byBqYXZhLmlvLkZpbGUuIFRoaXMgaXMgY29uc2lkZXJlZCBkYW5nZXJvdXMgc2luY2UgaXQKKyAqIGlnbm9yZXMgcGFydHMgb2YgdGhlIFVyaSBhdCB0aGUgY2FsbGVyJ3MgcGVyaWwsIGFuZCB0aHVzIGlzIG9ubHkgYXZhaWxhYmxlIHRvIGFsbG93bGlzdGVkIGNsaWVudHMKKyAqIChtb3N0bHkgaW50ZXJuYWwpLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgR2VuZXJpY1VyaUFkYXB0ZXIgaW1wbGVtZW50cyBVcmlBZGFwdGVyIHsKKworICBwcml2YXRlIGZpbmFsIEFuZHJvaWRVcmlBZGFwdGVyIGFuZHJvaWRVcmlBZGFwdGVyOworICBwcml2YXRlIGZpbmFsIEZpbGVVcmlBZGFwdGVyIGZpbGVVcmlBZGFwdGVyOworCisgIHByaXZhdGUgR2VuZXJpY1VyaUFkYXB0ZXIoQ29udGV4dCBjb250ZXh0KSB7CisgICAgYW5kcm9pZFVyaUFkYXB0ZXIgPSBBbmRyb2lkVXJpQWRhcHRlci5mb3JDb250ZXh0KGNvbnRleHQpOworICAgIGZpbGVVcmlBZGFwdGVyID0gRmlsZVVyaUFkYXB0ZXIuaW5zdGFuY2UoKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgR2VuZXJpY1VyaUFkYXB0ZXIgZm9yQ29udGV4dChDb250ZXh0IGNvbnRleHQpIHsKKyAgICByZXR1cm4gbmV3IEdlbmVyaWNVcmlBZGFwdGVyKGNvbnRleHQpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBGaWxlIHRvRmlsZShVcmkgdXJpKSB0aHJvd3MgTWFsZm9ybWVkVXJpRXhjZXB0aW9uIHsKKyAgICBzd2l0Y2ggKHVyaS5nZXRTY2hlbWUoKSkgeworICAgICAgY2FzZSBBbmRyb2lkVXJpLlNDSEVNRV9OQU1FOgorICAgICAgICByZXR1cm4gYW5kcm9pZFVyaUFkYXB0ZXIudG9GaWxlKHVyaSk7CisgICAgICBjYXNlIEZpbGVVcmkuU0NIRU1FX05BTUU6CisgICAgICAgIHJldHVybiBmaWxlVXJpQWRhcHRlci50b0ZpbGUodXJpKTsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oIkNvdWxkbid0IGNvbnZlcnQgVVJJIHRvIHBhdGg6ICIgKyB1cmkpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0phdmFGaWxlQmFja2VuZC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0phdmFGaWxlQmFja2VuZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjZDQzYTIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvSmF2YUZpbGVCYWNrZW5kLmphdmEKQEAgLTAsMCArMSwxODEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5QYXJjZWxGaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5Mb2NrU2NvcGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuQmFja2VuZElucHV0U3RyZWFtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLkJhY2tlbmRPdXRwdXRTdHJlYW07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5GaWxlczsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKiBBIGJhY2tlbmQgdGhhdCBpbXBsZW1lbnRzICJmaWxlOiIgc2NoZW1lIHVzaW5nIGphdmEuaW8uRmlsZUlucHV0L091dHB1dFN0cmVhbS4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBKYXZhRmlsZUJhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHsKKworICBwcml2YXRlIGZpbmFsIExvY2tTY29wZSBsb2NrU2NvcGU7CisKKyAgcHVibGljIEphdmFGaWxlQmFja2VuZCgpIHsKKyAgICB0aGlzKG5ldyBMb2NrU2NvcGUoKSk7CisgIH0KKworICAvKioKKyAgICogT3ZlcnJpZGVzIHRoZSBkZWZhdWx0IGJhY2tlbmQtc2NvcGVkIHtAbGluayBMb2NrU2NvcGV9IHdpdGggdGhlIGdpdmVuIHtAY29kZSBsb2NrU2NvcGV9LiBUaGlzCisgICAqIGluamVjdGlvbiBpcyBvbmx5IG5lY2Vzc2FyeSBpZiB0aGVyZSBhcmUgbXVsdGlwbGUgYmFja2VuZCBpbnN0YW5jZXMgaW4gdGhlIHNhbWUgcHJvY2VzcyBhbmQKKyAgICogdGhlcmUncyBhIHJpc2sgb2YgdGhlbSBhY3F1aXJpbmcgYSBsb2NrIG9uIHRoZSBzYW1lIHVuZGVybHlpbmcgZmlsZS4KKyAgICovCisgIHB1YmxpYyBKYXZhRmlsZUJhY2tlbmQoTG9ja1Njb3BlIGxvY2tTY29wZSkgeworICAgIHRoaXMubG9ja1Njb3BlID0gbG9ja1Njb3BlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgbmFtZSgpIHsKKyAgICByZXR1cm4gImZpbGUiOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBJbnB1dFN0cmVhbSBvcGVuRm9yUmVhZChVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZpbGUgZmlsZSA9IEZpbGVVcmlBZGFwdGVyLmluc3RhbmNlKCkudG9GaWxlKHVyaSk7CisgICAgcmV0dXJuIEJhY2tlbmRJbnB1dFN0cmVhbS5jcmVhdGUoZmlsZSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFBhaXI8VXJpLCBDbG9zZWFibGU+IG9wZW5Gb3JOYXRpdmVSZWFkKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZSBmaWxlID0gRmlsZVVyaUFkYXB0ZXIuaW5zdGFuY2UoKS50b0ZpbGUodXJpKTsKKyAgICBQYXJjZWxGaWxlRGVzY3JpcHRvciBwZmQgPSBQYXJjZWxGaWxlRGVzY3JpcHRvci5vcGVuKGZpbGUsIFBhcmNlbEZpbGVEZXNjcmlwdG9yLk1PREVfUkVBRF9PTkxZKTsKKyAgICByZXR1cm4gRmlsZURlc2NyaXB0b3JVcmkuZnJvbVBhcmNlbEZpbGVEZXNjcmlwdG9yKHBmZCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE91dHB1dFN0cmVhbSBvcGVuRm9yV3JpdGUoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZpbGUgPSBGaWxlVXJpQWRhcHRlci5pbnN0YW5jZSgpLnRvRmlsZSh1cmkpOworICAgIEZpbGVzLmNyZWF0ZVBhcmVudERpcnMoZmlsZSk7CisgICAgcmV0dXJuIEJhY2tlbmRPdXRwdXRTdHJlYW0uY3JlYXRlRm9yV3JpdGUoZmlsZSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE91dHB1dFN0cmVhbSBvcGVuRm9yQXBwZW5kKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZSBmaWxlID0gRmlsZVVyaUFkYXB0ZXIuaW5zdGFuY2UoKS50b0ZpbGUodXJpKTsKKyAgICBGaWxlcy5jcmVhdGVQYXJlbnREaXJzKGZpbGUpOworICAgIHJldHVybiBCYWNrZW5kT3V0cHV0U3RyZWFtLmNyZWF0ZUZvckFwcGVuZChmaWxlKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBkZWxldGVGaWxlKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZSBmaWxlID0gRmlsZVVyaUFkYXB0ZXIuaW5zdGFuY2UoKS50b0ZpbGUodXJpKTsKKyAgICBpZiAoZmlsZS5pc0RpcmVjdG9yeSgpKSB7CisgICAgICB0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKFN0cmluZy5mb3JtYXQoIiVzIGlzIGEgZGlyZWN0b3J5IiwgdXJpKSk7CisgICAgfQorICAgIGlmICghZmlsZS5kZWxldGUoKSkgeworICAgICAgaWYgKCFmaWxlLmV4aXN0cygpKSB7CisgICAgICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFeGNlcHRpb24oU3RyaW5nLmZvcm1hdCgiJXMgZG9lcyBub3QgZXhpc3QiLCB1cmkpKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihTdHJpbmcuZm9ybWF0KCIlcyBjb3VsZCBub3QgYmUgZGVsZXRlZCIsIHVyaSkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBkZWxldGVEaXJlY3RvcnkoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlIGRpciA9IEZpbGVVcmlBZGFwdGVyLmluc3RhbmNlKCkudG9GaWxlKHVyaSk7CisgICAgaWYgKCFkaXIuaXNEaXJlY3RvcnkoKSkgeworICAgICAgdGhyb3cgbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbihTdHJpbmcuZm9ybWF0KCIlcyBpcyBub3QgYSBkaXJlY3RvcnkiLCB1cmkpKTsKKyAgICB9CisgICAgaWYgKCFkaXIuZGVsZXRlKCkpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihTdHJpbmcuZm9ybWF0KCIlcyBjb3VsZCBub3QgYmUgZGVsZXRlZCIsIHVyaSkpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCByZW5hbWUoVXJpIGZyb20sIFVyaSB0bykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZyb21GaWxlID0gRmlsZVVyaUFkYXB0ZXIuaW5zdGFuY2UoKS50b0ZpbGUoZnJvbSk7CisgICAgRmlsZSB0b0ZpbGUgPSBGaWxlVXJpQWRhcHRlci5pbnN0YW5jZSgpLnRvRmlsZSh0byk7CisgICAgRmlsZXMuY3JlYXRlUGFyZW50RGlycyh0b0ZpbGUpOworICAgIGlmICghZnJvbUZpbGUucmVuYW1lVG8odG9GaWxlKSkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKFN0cmluZy5mb3JtYXQoIiVzIGNvdWxkIG5vdCBiZSByZW5hbWVkIHRvICVzIiwgZnJvbSwgdG8pKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXhpc3RzKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZSBmaWxlID0gRmlsZVVyaUFkYXB0ZXIuaW5zdGFuY2UoKS50b0ZpbGUodXJpKTsKKyAgICByZXR1cm4gZmlsZS5leGlzdHMoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZpbGUgZmlsZSA9IEZpbGVVcmlBZGFwdGVyLmluc3RhbmNlKCkudG9GaWxlKHVyaSk7CisgICAgcmV0dXJuIGZpbGUuaXNEaXJlY3RvcnkoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBjcmVhdGVEaXJlY3RvcnkoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZpbGUgPSBGaWxlVXJpQWRhcHRlci5pbnN0YW5jZSgpLnRvRmlsZSh1cmkpOworICAgIGlmICghZmlsZS5ta2RpcnMoKSkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKFN0cmluZy5mb3JtYXQoIiVzIGNvdWxkIG5vdCBiZSBjcmVhdGVkIiwgdXJpKSk7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBsb25nIGZpbGVTaXplKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZSBmaWxlID0gRmlsZVVyaUFkYXB0ZXIuaW5zdGFuY2UoKS50b0ZpbGUodXJpKTsKKyAgICBpZiAoZmlsZS5pc0RpcmVjdG9yeSgpKSB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgcmV0dXJuIGZpbGUubGVuZ3RoKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEl0ZXJhYmxlPFVyaT4gY2hpbGRyZW4oVXJpIHBhcmVudFVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlIHBhcmVudCA9IEZpbGVVcmlBZGFwdGVyLmluc3RhbmNlKCkudG9GaWxlKHBhcmVudFVyaSk7CisgICAgaWYgKCFwYXJlbnQuaXNEaXJlY3RvcnkoKSkgeworICAgICAgdGhyb3cgbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbihTdHJpbmcuZm9ybWF0KCIlcyBpcyBub3QgYSBkaXJlY3RvcnkiLCBwYXJlbnRVcmkpKTsKKyAgICB9CisgICAgRmlsZVtdIGNoaWxkcmVuID0gcGFyZW50Lmxpc3RGaWxlcygpOworICAgIGlmIChjaGlsZHJlbiA9PSBudWxsKSB7CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oCisgICAgICAgICAgU3RyaW5nLmZvcm1hdCgiTm90IGEgZGlyZWN0b3J5IG9yIEkvTyBlcnJvciAodW5leHBlY3RlZCk6ICVzIiwgcGFyZW50VXJpKSk7CisgICAgfQorICAgIExpc3Q8VXJpPiByZXN1bHQgPSBuZXcgQXJyYXlMaXN0PFVyaT4oKTsKKyAgICBmb3IgKEZpbGUgY2hpbGQgOiBjaGlsZHJlbikgeworICAgICAgU3RyaW5nIHBhdGggPSBjaGlsZC5nZXRBYnNvbHV0ZVBhdGgoKTsKKyAgICAgIGlmIChjaGlsZC5pc0RpcmVjdG9yeSgpICYmICFwYXRoLmVuZHNXaXRoKCIvIikpIHsKKyAgICAgICAgcGF0aCArPSAiLyI7CisgICAgICB9CisgICAgICByZXN1bHQuYWRkKEZpbGVVcmkuYnVpbGRlcigpLnNldFBhdGgocGF0aCkuYnVpbGQoKSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEZpbGUgdG9GaWxlKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIEZpbGVVcmlBZGFwdGVyLmluc3RhbmNlKCkudG9GaWxlKHVyaSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExvY2tTY29wZSBsb2NrU2NvcGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBsb2NrU2NvcGU7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9NZW1vcnlCYWNrZW5kLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvTWVtb3J5QmFja2VuZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2NGUyNmMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvTWVtb3J5QmFja2VuZC5qYXZhCkBAIC0wLDAgKzEsMTI3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudGV4dC5UZXh0VXRpbHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uTWFsZm9ybWVkVXJpRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworCisvKioKKyAqIEEge0BsaW5rIEJhY2tlbmR9IHdob3NlIGZpbGVzIGV4aXN0IG9ubHkgaW4gbWVtb3J5LiBGaWxlcyBhcmUgbmV2ZXIgY2FjaGVkIHRvIGRpc2sgYW5kIGV4aXN0IG9ubHkKKyAqIGZvciB0aGUgZHVyYXRpb24gb2YgdGhlIGJhY2tlbmQgaXRzZWxmLiBJdCBoYXMgdGhlIGZvbGxvd2luZyBsaW1pdGF0aW9uczoKKyAqCisgKiA8dWw+CisgKiAgIDxsaT5UaGUgYmFja2VuZCBpcyBmbGF0OyBkaXJlY3Rvcnkgb3BlcmF0aW9ucyBhcmUgdW5zdXBwb3J0ZWQKKyAqICAgPGxpPntAbGluayBCYWNrZW5kI29wZW5Gb3JBcHBlbmR9IGlzIHVuc3VwcG9ydGVkCisgKiAgIDxsaT5OYXRpdmUgZmlsZXN5dGVtIGZlYXR1cmVzIHN1Y2ggYXMgRkQncyBhbmQgc3luY2luZyBhcmUgdW5zdXBwb3J0ZWQKKyAqIDwvdWw+CisgKgorICogPHA+U2VlIDxpbnRlcm5hbD4gZm9yIGZ1cnRoZXIgZG9jdW1lbnRhdGlvbi4KKyAqLworLy8gVE9ETyhiLzExMTY5NDM0OCk6IGNvbnNpZGVyIGFkZGluZyBkaXJlY3Rvcnkgc3VwcG9ydAorcHVibGljIGZpbmFsIGNsYXNzIE1lbW9yeUJhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHsKKworICAvLyBVcmkgc2NoZW1lIHRoZSBiYWNrZW5kIGlzIHJlZ2lzdGVyZWQgdW5kZXIgKHBhY2thZ2UtcHJpdmF0ZSBmb3IgdXNlIGluIHtAbGluayBNZW1vcnlVcml9KQorICBzdGF0aWMgZmluYWwgU3RyaW5nIFVSSV9TQ0hFTUUgPSAibWVtb3J5IjsKKworICBwcml2YXRlIGZpbmFsIE1hcDxVcmksIEJ5dGVCdWZmZXI+IGZpbGVzID0gbmV3IEhhc2hNYXA8PigpOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIG5hbWUoKSB7CisgICAgcmV0dXJuIFVSSV9TQ0hFTUU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIG9wZW5Gb3JSZWFkKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdmFsaWRhdGUodXJpKTsKKyAgICBCeXRlQnVmZmVyIGJ1ZiA9IGZpbGVzLmdldCh1cmkpOworICAgIGlmIChidWYgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbihTdHJpbmcuZm9ybWF0KCIlcyAoTm8gc3VjaCBmaWxlKSIsIHVyaSkpOworICAgIH0KKyAgICBCeXRlQnVmZmVyIHNsaWNlID0gYnVmLnNsaWNlKCk7IC8vIFBvaW50cyB0byB0aGUgc2FtZSBkYXRhIGJ1dCBoYXMgYW4gaW5kZXBlbmRlbnQgcmVhZCBwb3NpdGlvbgorICAgIHJldHVybiBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oc2xpY2UuYXJyYXkoKSwgc2xpY2UuYXJyYXlPZmZzZXQoKSwgc2xpY2UubGltaXQoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE91dHB1dFN0cmVhbSBvcGVuRm9yV3JpdGUoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB2YWxpZGF0ZSh1cmkpOworICAgIC8vIE5vdGUgdGhhdCB0aGlzIGlzIGF0b21pYyBpbiB0aGUgc2Vuc2UgdGhhdCB0aGUgZGF0YSBpc24ndCBmbHVzaGVkIHVudGlsIGNsb3NpbmcgdGhlIHN0cmVhbQorICAgIHJldHVybiBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCkgeworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIGZpbGVzLnB1dCh1cmksIEJ5dGVCdWZmZXIud3JhcCh0aGlzLmJ1ZiwgMCwgdGhpcy5jb3VudCkpOworICAgICAgfQorICAgIH07CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgZGVsZXRlRmlsZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHZhbGlkYXRlKHVyaSk7CisgICAgaWYgKGZpbGVzLnJlbW92ZSh1cmkpID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBGaWxlTm90Rm91bmRFeGNlcHRpb24oU3RyaW5nLmZvcm1hdCgiJXMgZG9lcyBub3QgZXhpc3QiLCB1cmkpKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcmVuYW1lKFVyaSBmcm9tLCBVcmkgdG8pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdmFsaWRhdGUoZnJvbSk7CisgICAgdmFsaWRhdGUodG8pOworICAgIEJ5dGVCdWZmZXIgYnVmID0gZmlsZXMucmVtb3ZlKGZyb20pOworICAgIGlmIChidWYgPT0gbnVsbCkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKFN0cmluZy5mb3JtYXQoIiVzIGNvdWxkIG5vdCBiZSByZW5hbWVkIHRvICVzIiwgZnJvbSwgdG8pKTsKKyAgICB9CisgICAgZmlsZXMucHV0KHRvLCBidWYpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGV4aXN0cyhVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHZhbGlkYXRlKHVyaSk7CisgICAgcmV0dXJuIGZpbGVzLmNvbnRhaW5zS2V5KHVyaSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGxvbmcgZmlsZVNpemUoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB2YWxpZGF0ZSh1cmkpOworICAgIEJ5dGVCdWZmZXIgYnVmID0gZmlsZXMuZ2V0KHVyaSk7CisgICAgcmV0dXJuIGJ1ZiAhPSBudWxsID8gYnVmLmxpbWl0KCkgOiAwOworICB9CisKKyAgLyoqIFZhbGlkYXRlcyB0aGF0IHtAY29kZSB1cml9IGlzIGEgbm9uLWVtcHR5IG1lbW9yeTogVXJpIHdpdGggbm8gYXV0aG9yaXR5IG9yIHF1ZXJ5LiAqLworICBwcml2YXRlIHN0YXRpYyB2b2lkIHZhbGlkYXRlKFVyaSB1cmkpIHRocm93cyBNYWxmb3JtZWRVcmlFeGNlcHRpb24geworICAgIGlmICghVVJJX1NDSEVNRS5lcXVhbHModXJpLmdldFNjaGVtZSgpKSkgeworICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbigiRXhwZWN0ZWQgc2NoZW1lIHRvIGJlICIgKyBVUklfU0NIRU1FKTsKKyAgICB9CisgICAgaWYgKFRleHRVdGlscy5pc0VtcHR5KHVyaS5nZXRTY2hlbWVTcGVjaWZpY1BhcnQoKSkpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oIkV4cGVjdGVkIGEgbm9uLWVtcHR5IGZpbGUgaWRlbnRpZmllciIpOworICAgIH0KKyAgICBpZiAoIVRleHRVdGlscy5pc0VtcHR5KHVyaS5nZXRBdXRob3JpdHkoKSkpIHsKKyAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oIkRpZCBub3QgZXhwZWN0IGFuIGF1dGhvcml0eSIpOworICAgIH0KKyAgICBpZiAoIVRleHRVdGlscy5pc0VtcHR5KHVyaS5nZXRRdWVyeSgpKSkgeworICAgICAgdGhyb3cgbmV3IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbigiRGlkIG5vdCBleHBlY3QgYSBxdWVyeSIpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL01lbW9yeVVyaS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL01lbW9yeVVyaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJkNjlkNzIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvTWVtb3J5VXJpLmphdmEKQEAgLTAsMCArMSw3MyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kczsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnRleHQuVGV4dFV0aWxzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLk1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbC5MaXRlVHJhbnNmb3JtRnJhZ21lbnRzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5UcmFuc2Zvcm1Qcm90b3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLlRyYW5zZm9ybVByb3RvOworCisvKioKKyAqIEhlbHBlciBjbGFzcyBmb3IgIm1lbW9yeSIgc2NoZW1lIFVyaXMuIFRoZSBzY2hlbWUgaXMgb3BhcXVlLCB3aXRoIHRoZSBvcGFxdWUgcGFydCBzaW1wbHkgdXNlZCBhcworICogYSBrZXkgdG8gaWRlbnRpZnkgdGhlIGZpbGU7IGl0IGlzIG5vbi1oaWVyYXJjaGljYWwuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNZW1vcnlVcmkgeworCisgIC8qKiBSZXR1cm5zIGFuIGVtcHR5ICJtZW1vcnkiIHNjaGVtZSBVcmkgYnVpbGRlci4gKi8KKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIGJ1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ldyBCdWlsZGVyKCk7CisgIH0KKworICBwcml2YXRlIE1lbW9yeVVyaSgpIHt9CisKKyAgLyoqIEEgYnVpbGRlciBmb3IgIm1lbW9yeSIgc2NoZW1lIFVyaXMuICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciB7CisKKyAgICBwcml2YXRlIFN0cmluZyBrZXkgPSAiIjsKKyAgICBwcml2YXRlIGZpbmFsIEltbXV0YWJsZUxpc3QuQnVpbGRlcjxTdHJpbmc+IGVuY29kZWRTcGVjcyA9IEltbXV0YWJsZUxpc3QuYnVpbGRlcigpOworCisgICAgcHJpdmF0ZSBCdWlsZGVyKCkge30KKworICAgIC8qKiBTZXRzIHRoZSBub24tZW1wdHkga2V5IHRvIGJlIHVzZWQgYXMgYSBmaWxlIGlkZW50aWZpZXIuICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0S2V5KFN0cmluZyBrZXkpIHsKKyAgICAgIHRoaXMua2V5ID0ga2V5OworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQXBwZW5kcyBhIHRyYW5zZm9ybSB0byB0aGUgVXJpLiBDYWxsaW5nIHR3aWNlIHdpdGggdGhlIHNhbWUgdHJhbnNmb3JtIHJlcGxhY2VzIHRoZSBvcmlnaW5hbC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVpbGRlciB3aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybSBzcGVjKSB7CisgICAgICBlbmNvZGVkU3BlY3MuYWRkKFRyYW5zZm9ybVByb3Rvcy50b0VuY29kZWRTcGVjKHNwZWMpKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBVcmkgYnVpbGQoKSB0aHJvd3MgTWFsZm9ybWVkVXJpRXhjZXB0aW9uIHsKKyAgICAgIGlmIChUZXh0VXRpbHMuaXNFbXB0eShrZXkpKSB7CisgICAgICAgIHRocm93IG5ldyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oIktleSBtdXN0IGJlIG5vbi1lbXB0eSIpOworICAgICAgfQorICAgICAgU3RyaW5nIGZyYWdtZW50ID0gTGl0ZVRyYW5zZm9ybUZyYWdtZW50cy5qb2luVHJhbnNmb3JtU3BlY3MoZW5jb2RlZFNwZWNzLmJ1aWxkKCkpOworICAgICAgcmV0dXJuIG5ldyBVcmkuQnVpbGRlcigpCisgICAgICAgICAgLnNjaGVtZShNZW1vcnlCYWNrZW5kLlVSSV9TQ0hFTUUpCisgICAgICAgICAgLm9wYXF1ZVBhcnQoa2V5KQorICAgICAgICAgIC5lbmNvZGVkRnJhZ21lbnQoZnJhZ21lbnQpCisgICAgICAgICAgLmJ1aWxkKCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvVXJpQWRhcHRlci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL1VyaUFkYXB0ZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOWE3M2FhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL1VyaUFkYXB0ZXIuamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLk1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CisKKy8qKgorICogSW50ZXJmYWNlIGZvciBjb252ZXJ0aW5nIGNlcnRhaW4gVVJJIHNjaGVtZXMgdG8gcmF3IGphdmEuaW8uRmlsZXMuIEltcGxlbWVudGF0aW9ucyBvZiB0aGlzIGFyZQorICogY29uc2lkZXJlZCBkYW5nZXJvdXMgc2luY2UgdGhleSBpZ25vcmUgcGFydHMgb2YgdGhlIFVSSSBpbmNsdWdpbmcgdGhlIGZyYWdtZW50IGF0IHRoZSBjYWxsZXIncworICogcGVyaWwsIGFuZCB0aHVzIGlzIG9ubHkgYXZhaWxhYmxlIHRvIGFsbG93bGlzdGVkIGNsaWVudHMgKG1vc3RseSBpbnRlcm5hbCkuCisgKi8KK2ludGVyZmFjZSBVcmlBZGFwdGVyIHsKKyAgLyoqCisgICAqIEFkYXB0cyB0aGlzIHVyaSBpbnRvIGEgRmlsZSByZWZlcnJpbmcgdG8gdGhlIHNhbWUgdW5kZXJseWluZyBzeXN0ZW0gb2JqZWN0LiBTb21lIGNvbXBvbmVudHMgb2YKKyAgICogdGhlIFVSSSBpbmNsdWRpbmcgdGhlIGZyYWdtZW50IGFyZSBpZ25vcmVkLgorICAgKi8KKyAgRmlsZSB0b0ZpbGUoVXJpIHVyaSkgdGhyb3dzIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9VcmlOb3JtYWxpemVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvVXJpTm9ybWFsaXplci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU3OTJhMzYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvVXJpTm9ybWFsaXplci5qYXZhCkBAIC0wLDAgKzEsMzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24uaW8uRmlsZXMuc2ltcGxpZnlQYXRoOworCitpbXBvcnQgYW5kcm9pZC5hbm5vdGF0aW9uLlRhcmdldEFwaTsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZDsKKworLyoqIFV0aWxpdHkgY2xhc3MgdG8gbm9ybWFsaXplIFVSSXMgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBVcmlOb3JtYWxpemVyIHsKKworICBwcml2YXRlIFVyaU5vcm1hbGl6ZXIoKSB7fQorCisgIC8qKiBOb3JtYWxpemVzIHRoZSBVUkkgdG8gcHJldmVudCBwYXRoIHRyYXZlcnNhbCBhdHRhY2tzLiBSZXF1aXJlcyBTREsgMTYrLiAqLworICBAVGFyZ2V0QXBpKEJ1aWxkLlZFUlNJT05fQ09ERVMuSkVMTFlfQkVBTikgLy8gZm9yIFVyaS5ub3JtYWxpemVTY2hlbWUoKQorICBwdWJsaWMgc3RhdGljIFVyaSBub3JtYWxpemVVcmkoVXJpIHVyaSkgeworICAgIHJldHVybiB1cmkubm9ybWFsaXplU2NoZW1lKCkuYnVpbGRVcG9uKCkucGF0aChzaW1wbGlmeVBhdGgodXJpLmdldFBhdGgoKSkpLmJ1aWxkKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iZWhhdmlvcnMvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkMjE5NWEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzL0JVSUxECkBAIC0wLDAgKzEsNDYgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsKKyAgICAgICAgIi8vdmlzaWJpbGl0eTpwdWJsaWMiLAorICAgIF0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJjb21wdXRlX3VyaSIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkNvbXB1dGVkVXJpRnV0dXJlLmphdmEiLAorICAgICAgICAiVXJpQ29tcHV0aW5nQmVoYXZpb3IuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uOmZyYWdtZW50IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJzeW5jaW5nIiwKKyAgICBzcmNzID0gWworICAgICAgICAiU3luY2luZ0JlaGF2aW9yLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iZWhhdmlvcnMvQ29tcHV0ZWRVcmlGdXR1cmUuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iZWhhdmlvcnMvQ29tcHV0ZWRVcmlGdXR1cmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMzQwMTk1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JlaGF2aW9ycy9Db21wdXRlZFVyaUZ1dHVyZS5qYXZhCkBAIC0wLDAgKzEsOTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmVoYXZpb3JzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkZyYWdtZW50OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlBhcmFtQ29tcHV0ZXI7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ291bnREb3duTGF0Y2g7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkZ1dHVyZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lb3V0RXhjZXB0aW9uOworCisvKioKKyAqIENvbXB1dGVkIFVyaXMgYXJlIGF2YWlsYWJsZSBvbmx5IGFmdGVyIHRoZSBzdHJlYW0gaGFzIGJlZW4gZnVsbHkgY29uc3VtZWQgb3IgY2xvc2VkLiBUaGlzIGNsYXNzCisgKiBlbmZvcmNlcyB0aGF0IGJlaGF2aW9yLCBhbmQgcHJldmVudHMgYW55IHJhY2UgY29uZGl0aW9ucyB0aGF0IGNvdWxkIG90aGVyd2lzZSBoYXBwZW4gaWYgYSBjbGllbnQKKyAqIHRyaWVkIHRvIGZldGNoIHRoZSBjb21wdXRlZCB1cmkgd2hpbGUgYW5vdGhlciB0aHJlYWQgd2FzIHN0aWxsIHByb2Nlc3NpbmcgdGhlIHN0cmVhbS4KKyAqLworLy8gVE9ETzogU2hvdWxkTm90U3ViY2xhc3MgRnV0dXJlCitAU3VwcHJlc3NXYXJuaW5ncygiU2hvdWxkTm90U3ViY2xhc3MiKQorZmluYWwgY2xhc3MgQ29tcHV0ZWRVcmlGdXR1cmUgaW1wbGVtZW50cyBGdXR1cmU8VXJpPiwgUGFyYW1Db21wdXRlci5DYWxsYmFjayB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0ZPUk1fUEFSQU0gPSAidHJhbnNmb3JtIjsKKworICBwcml2YXRlIGZpbmFsIFVyaSB1cmk7CisgIHByaXZhdGUgZmluYWwgRnJhZ21lbnQgZnJhZ21lbnQ7CisgIHByaXZhdGUgZmluYWwgQ291bnREb3duTGF0Y2ggY291bnREb3duTGF0Y2g7CisgIHByaXZhdGUgZmluYWwgRnJhZ21lbnQuUGFyYW0uQnVpbGRlciB0cmFuc2Zvcm1zUGFyYW1CdWlsZGVyOworCisgIC8qKiBDb25zdHJ1Y3QgYSBuZXcgaW5zdGFuY2Ugd2l0aCB0aGUgb3JpZ2luYWwgdXJpLCBhbmQgcGFyYW0gY29tcHV0ZXJzLiAqLworICBDb21wdXRlZFVyaUZ1dHVyZShVcmkgdXJpLCBMaXN0PFBhcmFtQ29tcHV0ZXI+IHBhcmFtQ29tcHV0ZXJzKSB7CisgICAgdGhpcy51cmkgPSB1cmk7CisgICAgdGhpcy5mcmFnbWVudCA9IEZyYWdtZW50LnBhcnNlKHVyaSk7CisgICAgY291bnREb3duTGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2gocGFyYW1Db21wdXRlcnMuc2l6ZSgpKTsKKyAgICBmb3IgKFBhcmFtQ29tcHV0ZXIgcGFyYW1Db21wdXRlciA6IHBhcmFtQ29tcHV0ZXJzKSB7CisgICAgICBwYXJhbUNvbXB1dGVyLnNldENhbGxiYWNrKHRoaXMpOworICAgIH0KKyAgICBGcmFnbWVudC5QYXJhbSB0cmFuc2Zvcm1QYXJhbSA9IGZyYWdtZW50LmZpbmRQYXJhbShUUkFOU0ZPUk1fUEFSQU0pOworICAgIHRoaXMudHJhbnNmb3Jtc1BhcmFtQnVpbGRlciA9CisgICAgICAgICh0cmFuc2Zvcm1QYXJhbSAhPSBudWxsKQorICAgICAgICAgICAgPyB0cmFuc2Zvcm1QYXJhbS50b0J1aWxkZXIoKQorICAgICAgICAgICAgOiBGcmFnbWVudC5QYXJhbS5idWlsZGVyKFRSQU5TRk9STV9QQVJBTSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgb25QYXJhbVZhbHVlQ29tcHV0ZWQoRnJhZ21lbnQuUGFyYW1WYWx1ZSB2YWx1ZSkgeworICAgIHRyYW5zZm9ybXNQYXJhbUJ1aWxkZXIuYWRkVmFsdWUodmFsdWUpOworICAgIGNvdW50RG93bkxhdGNoLmNvdW50RG93bigpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGNhbmNlbChib29sZWFuIG1heUludGVycnVwdElmUnVubmluZykgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBpc0NhbmNlbGxlZCgpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gaXNEb25lKCkgeworICAgIHJldHVybiAoY291bnREb3duTGF0Y2guZ2V0Q291bnQoKSA9PSAwKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgVXJpIGdldCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICBjb3VudERvd25MYXRjaC5hd2FpdCgpOworICAgIEZyYWdtZW50IGNvbXB1dGVkRnJhZ21lbnQgPSBmcmFnbWVudC50b0J1aWxkZXIoKS5hZGRQYXJhbSh0cmFuc2Zvcm1zUGFyYW1CdWlsZGVyKS5idWlsZCgpOworICAgIHJldHVybiB1cmkuYnVpbGRVcG9uKCkuZW5jb2RlZEZyYWdtZW50KGNvbXB1dGVkRnJhZ21lbnQudG9TdHJpbmcoKSkuYnVpbGQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgVXJpIGdldChsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQpCisgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbiwgVGltZW91dEV4Y2VwdGlvbiB7CisgICAgaWYgKCFjb3VudERvd25MYXRjaC5hd2FpdCh0aW1lb3V0LCB1bml0KSkgeworICAgICAgdGhyb3cgbmV3IFRpbWVvdXRFeGNlcHRpb24oKTsKKyAgICB9CisgICAgcmV0dXJuIGdldCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzL1N5bmNpbmdCZWhhdmlvci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JlaGF2aW9ycy9TeW5jaW5nQmVoYXZpb3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNjNjNzBmCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JlaGF2aW9ycy9TeW5jaW5nQmVoYXZpb3IuamF2YQpAQCAtMCwwICsxLDU4IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJlaGF2aW9yczsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuQmVoYXZpb3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uU3luY2FibGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0Lkl0ZXJhYmxlczsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIFRoaXMgQmVoYXZpb3IgY2FuIGJlIHVzZWQgdG8gZW5zdXJlIHRoYXQgYWxsIGFwcGxpY2F0aW9uIGJ1ZmZlcnMgYW5kIE9TIGJ1ZmZlcnMgYXJlIGZsdXNoZWQgdG8KKyAqIHBlcnNpc3RlbnQgc3RvcmFnZS4KKyAqCisgKiA8cD5OT1RFOiBub3QgZmluYWwgZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seS4KKyAqLworcHVibGljIGNsYXNzIFN5bmNpbmdCZWhhdmlvciBpbXBsZW1lbnRzIEJlaGF2aW9yIHsKKworICBwcml2YXRlIE91dHB1dFN0cmVhbSBoZWFkU3RyZWFtOworICBwcml2YXRlIFN5bmNhYmxlIHN5bmNhYmxlOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBmb3JPdXRwdXRDaGFpbihMaXN0PE91dHB1dFN0cmVhbT4gY2hhaW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgT3V0cHV0U3RyZWFtIGJhY2tlbmRTdHJlYW0gPSBJdGVyYWJsZXMuZ2V0TGFzdChjaGFpbik7CisgICAgaWYgKGJhY2tlbmRTdHJlYW0gaW5zdGFuY2VvZiBTeW5jYWJsZSkgeworICAgICAgc3luY2FibGUgPSAoKFN5bmNhYmxlKSBiYWNrZW5kU3RyZWFtKTsKKyAgICAgIGhlYWRTdHJlYW0gPSBjaGFpbi5nZXQoMCk7CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgc3luYygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHN5bmNhYmxlID09IG51bGwpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJDYW5ub3Qgc3luYyB1bmRlcmx5aW5nIHN0cmVhbSIpOworICAgIH0KKyAgICBoZWFkU3RyZWFtLmZsdXNoKCk7CisgICAgc3luY2FibGUuc3luYygpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGNvbW1pdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgc3luYygpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzL1VyaUNvbXB1dGluZ0JlaGF2aW9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzL1VyaUNvbXB1dGluZ0JlaGF2aW9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjU2MTM3MwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iZWhhdmlvcnMvVXJpQ29tcHV0aW5nQmVoYXZpb3IuamF2YQpAQCAtMCwwICsxLDc3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJlaGF2aW9yczsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLkJlaGF2aW9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlBhcmFtQ29tcHV0ZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5GbHVlbnRJdGVyYWJsZTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkZ1dHVyZTsKKworLyoqCisgKiBCZWhhdmlvciB0aGF0IHN1cHBvcnRzIGNvbXB1dGluZyBhIFVSSSBiYXNlZCBvbiB0aGUgY29udGVudHMgb2YgdGhlIHN0cmVhbS4gVGhpcyBpcyB1c2VmdWwsIGVnLAorICogZm9yIGdlbmVyYXRpbmcgYSBzZWN1cmUgaGFzaC4KKyAqCisgKiA8cD5TZWUgPGludGVybmFsPiBmb3IgZG9jdW1lbnRhdGlvbi4KKyAqLworcHVibGljIGNsYXNzIFVyaUNvbXB1dGluZ0JlaGF2aW9yIGltcGxlbWVudHMgQmVoYXZpb3IgeworCisgIHByaXZhdGUgZmluYWwgVXJpIHVyaTsKKyAgcHJpdmF0ZSBDb21wdXRlZFVyaUZ1dHVyZSBmdXR1cmU7CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCBhIG5ldyBVUkkgY29tcHV0aW5nIGJlaGF2aW9yIGZvciB0aGUgcHJvdmlkZWQgVVJJLiBUaGUgVVJJIHdpbGwgZm9ybSBhcyB0aGUgYmFzZSB0aGF0CisgICAqIGlzIG1vZGlmaWVkIHdpdGggdGhlIG5ldyBjb21wdXRlZCBmcmFnbWVudCB2YWx1ZXMsIGFuZCBtYWtlIGF2YWlsYWJsZSB2aWEgPGNvZGU+dXJpRnV0dXJlKCkKKyAgICogPC9jb2RlPiBtZXRob2QuIEl0IGlzIGV4cGVjdGVkIHRvIGJlIHRoZSBzYW1lIFVSSSBhcyBpcyBwYXNzZWQgdG8gdGhlIEZpbGVTdG9yYWdlIDxjb2RlPm9wZW4oKQorICAgKiA8L2NvZGU+IG1ldGhvZC4KKyAgICovCisgIHB1YmxpYyBVcmlDb21wdXRpbmdCZWhhdmlvcihVcmkgdXJpKSB7CisgICAgdGhpcy51cmkgPSB1cmk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgZm9ySW5wdXRDaGFpbihMaXN0PElucHV0U3RyZWFtPiBjaGFpbikgeworICAgIGZ1dHVyZSA9CisgICAgICAgIG5ldyBDb21wdXRlZFVyaUZ1dHVyZSgKKyAgICAgICAgICAgIHVyaSwKKyAgICAgICAgICAgIEZsdWVudEl0ZXJhYmxlLmZyb20oY2hhaW4pCisgICAgICAgICAgICAgICAgLmZpbHRlcigoSW5wdXRTdHJlYW0gaW4pIC0+IChpbiBpbnN0YW5jZW9mIFBhcmFtQ29tcHV0ZXIpKQorICAgICAgICAgICAgICAgIC50cmFuc2Zvcm0oKElucHV0U3RyZWFtIGluKSAtPiAoUGFyYW1Db21wdXRlcikgaW4pCisgICAgICAgICAgICAgICAgLnRvTGlzdCgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBmb3JPdXRwdXRDaGFpbihMaXN0PE91dHB1dFN0cmVhbT4gY2hhaW4pIHsKKyAgICBmdXR1cmUgPQorICAgICAgICBuZXcgQ29tcHV0ZWRVcmlGdXR1cmUoCisgICAgICAgICAgICB1cmksCisgICAgICAgICAgICBGbHVlbnRJdGVyYWJsZS5mcm9tKGNoYWluKQorICAgICAgICAgICAgICAgIC5maWx0ZXIoKE91dHB1dFN0cmVhbSBvdXQpIC0+IChvdXQgaW5zdGFuY2VvZiBQYXJhbUNvbXB1dGVyKSkKKyAgICAgICAgICAgICAgICAudHJhbnNmb3JtKChPdXRwdXRTdHJlYW0gb3V0KSAtPiAoUGFyYW1Db21wdXRlcikgb3V0KQorICAgICAgICAgICAgICAgIC50b0xpc3QoKSk7CisgIH0KKworICAvKioKKyAgICogR2V0cyBhIGZ1dHVyZSB0byB0aGUgVVJJIHdpdGggdGhlIGZyYWdtZW50IHVwZGF0ZWQgdG8gaW5jbHVkZSB0aGUgY29tcHV0ZWQgbWV0YWRhdGEuIFRoaXMKKyAgICogZnV0dXJlIHdpbGwgYmxvY2sgdW50aWwgdGhlIHN0cmVhbSBoYXMgYmVlbiBmdWxseSBjb25zdW1lZCwgb3IsIHdoZW4gd3JpdGluZywgY2xvc2VkLgorICAgKi8KKyAgcHVibGljIEZ1dHVyZTxVcmk+IHVyaUZ1dHVyZSgpIHsKKyAgICByZXR1cm4gZnV0dXJlOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0JVSUxEIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMTgzMjQzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9CVUlMRApAQCAtMCwwICsxLDU5IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9saWJyYXJ5IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbCisgICAgICAgICIvL3Zpc2liaWxpdHk6cHVibGljIiwKKyAgICBdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiY29tbW9uIiwKKyAgICBzcmNzID0gWworICAgICAgICAiRmlsZUNoYW5uZWxDb252ZXJ0aWJsZS5qYXZhIiwKKyAgICAgICAgIkZpbGVDb252ZXJ0aWJsZS5qYXZhIiwKKyAgICAgICAgIkZpbGVTdG9yYWdlVW5hdmFpbGFibGVFeGNlcHRpb24uamF2YSIsCisgICAgICAgICJHY1BhcmFtLmphdmEiLAorICAgICAgICAiSW52YWxpZEFjY291bnRFeGNlcHRpb24uamF2YSIsCisgICAgICAgICJMYXp5SW5pdGlhbGl6YWJsZS5qYXZhIiwKKyAgICAgICAgIkxpbWl0RXhjZWVkZWRFeGNlcHRpb24uamF2YSIsCisgICAgICAgICJMb2NrLmphdmEiLAorICAgICAgICAiTG9ja1Njb3BlLmphdmEiLAorICAgICAgICAiTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmphdmEiLAorICAgICAgICAiUmVsZWFzYWJsZVJlc291cmNlLmphdmEiLAorICAgICAgICAiU2l6YWJsZS5qYXZhIiwKKyAgICAgICAgIlN5bmNhYmxlLmphdmEiLAorICAgICAgICAiVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbi5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICMgTk9URTogZGVwZW5kZW5jeSBvZiBnbXNjb3JlIGNsaWVudCBsaWIgPGludGVybmFsPgorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImZyYWdtZW50IiwKKyAgICBzcmNzID0gWworICAgICAgICAiRnJhZ21lbnQuamF2YSIsCisgICAgICAgICJQYXJhbUNvbXB1dGVyLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpjaGFyc2V0cyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6cHJlY29uZGl0aW9ucyIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICMgTk9URTogZGVwZW5kZW5jeSBvZiBnbXNjb3JlIGNsaWVudCBsaWIgPGludGVybmFsPgorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0ZpbGVDaGFubmVsQ29udmVydGlibGUuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vRmlsZUNoYW5uZWxDb252ZXJ0aWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5NDRmYjYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0ZpbGVDaGFubmVsQ29udmVydGlibGUuamF2YQpAQCAtMCwwICsxLDIzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbjsKKworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworCisvKiogU29tZXRoaW5nIHRoYXQgY2FuIGJlIGNvbnZlcnRlZCB0byBhIEZpbGVDaGFubmVsLiAqLworcHVibGljIGludGVyZmFjZSBGaWxlQ2hhbm5lbENvbnZlcnRpYmxlIHsKKyAgRmlsZUNoYW5uZWwgdG9GaWxlQ2hhbm5lbCgpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9GaWxlQ29udmVydGlibGUuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vRmlsZUNvbnZlcnRpYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjU2Y2JjNgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vRmlsZUNvbnZlcnRpYmxlLmphdmEKQEAgLTAsMCArMSwyMyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb247CisKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CisKKy8qKiBTb21ldGhpbmcgdGhhdCBjYW4gYmUgY29udmVydGVkIHRvIGEgRmlsZS4gKi8KK3B1YmxpYyBpbnRlcmZhY2UgRmlsZUNvbnZlcnRpYmxlIHsKKyAgRmlsZSB0b0ZpbGUoKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vRmlsZVN0b3JhZ2VVbmF2YWlsYWJsZUV4Y2VwdGlvbi5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9GaWxlU3RvcmFnZVVuYXZhaWxhYmxlRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2I0OTIwMQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vRmlsZVN0b3JhZ2VVbmF2YWlsYWJsZUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqIFRoZSBvcGVyYXRpb24gY2Fubm90IGJlIGNvbXBsZXRlZCBiZWNhdXNlIGJhY2tlbmQgSU8gaXMgaW4gYW4gdW5yZWFjaGFibGUgc3RhdGUuICovCisvLyBUT0RPKGIvNjM5MDIxNzcpOiBtaXRpZ2F0ZSBleHBlbnNpdmUgdGhyb3dhYmxlIGNvbnN0cnVjdG9yCitwdWJsaWMgZmluYWwgY2xhc3MgRmlsZVN0b3JhZ2VVbmF2YWlsYWJsZUV4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKyAgcHVibGljIEZpbGVTdG9yYWdlVW5hdmFpbGFibGVFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICBzdXBlcihtZXNzYWdlKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9GcmFnbWVudC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9GcmFnbWVudC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkMDI4ODUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0ZyYWdtZW50LmphdmEKQEAgLTAsMCArMSw2MTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLkNoYXJzZXRzLlVURl84OworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudGV4dC5UZXh0VXRpbHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuUHJlY29uZGl0aW9uczsKK2ltcG9ydCBqYXZhLmlvLlVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb247CitpbXBvcnQgamF2YS5uZXQuVVJMRGVjb2RlcjsKK2ltcG9ydCBqYXZhLm5ldC5VUkxFbmNvZGVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKgorICogQSBVUkkgZnJhZ21lbnQgcGFyc2VyIGFuZCBidWlsZGVyLiBQYXJzZXMgZnJhZ21lbnQgcGFyYW1zIGlzIHNpbWlsYXIgdG8gcGFyc2luZyBvZiBxdWVyeSBwYXJhbXMsCisgKiBhbmQgYXJlIGRlbGltaXRlZCBieSAiJiIuIEZvciBleGFtcGxlLCA8Y29kZT4jZm9vPWJhciZ1cz10aGVtPC9jb2RlPgorICoKKyAqIDxwPnByb2R1Y2VzIHR3byBwYXJhbXM6IG9uZSAiZm9vIiB3aXRoIHZhbHVlICJiYXIiLCBhbmQgYW5vdGhlciAidXMiIHdpdGggdmFsdWUgInRoZW0iLgorICoKKyAqIDxwPkVhY2ggZnJhZ21lbnQgcGFyYW0gbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSB2YWx1ZTsgbXVsdGlwbGUgdmFsdWVzIGFyZSBkZWxpbWl0ZWQgYnkgIisiLiBGb3IKKyAqIGV4YW1wbGUsIDxjb2RlPiNmb289YmFyK2JhejwvY29kZT4KKyAqCisgKiA8cD5wcm9kdWNlcyBvbmUgcGFyYW0sICJmb28iLCB3aXRoIHR3byB2YWx1ZXMgImJhciIgYW5kICJiYXoiLgorICoKKyAqIDxwPkZ1cnRoZXJtb3JlLCBmcmFnbWVudCB2YWx1ZXMgY2FuIGhhdmUgc3VicGFyYW1zLCB3aGljaCBhcmUgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBzY29wZWQgdG8KKyAqIHRoZSB2YWx1ZS4gU3VicGFyYW1zIGhhdmUga2V5cyBhbmQgb3B0aW9uYWwgdmFsdWVzLCBhbmQgYXJlIGRlbGltaXRlZCBieSAiLCIuIEZvciBleGFtcGxlLCA8Y29kZT4KKyAqICNmb289YmFyKHg9MSkrYmF6KHRoaXM9dGhhdCx3aGVuKTwvY29kZT4KKyAqCisgKiA8cD5wcm9kdWNlcyBvbmUgcGFyYW0sICJmb28iLCB3aXRoIHR3byB2YWx1ZXMgImJhciIgYW5kICJiYXoiIHdoZXJlICJiYXIiIGhhcyBzdWJwYXJhbSAieCIgc2V0IGF0CisgKiAxLCBiYXogaGFzIHN1YnBhcmFtICJ0aGlzIiBzZXQgYXQgInRoYXQiLCBhbmQgIndoZW4iIGlzIHVuc2V0LgorICoKKyAqIDxwPldoaWxlIHRoZSA8aW50ZXJuYWw+IHNwZWMgcmVxdWlyZXMgdGhhdCBrZXlzIGFuZCB2YWx1ZXMgYXJlIFswLTlhLXpBLVotX10rLCB0aGlzIGNsYXNzCisgKiBlbmNvZGVzL2RlY29kZXMga2V5cy92YWx1ZXMsIGluY2x1ZGluZyBzdWJwYXJhbXMgdXNpbmcgamF2YS5uZXQuVVJMRW5jb2Rlci9kZWNvZGVyLiBJbgorICogcGFydGljdWxhciwgdGhpcyBjbGFzcyBpcyByZXNwb25zaWJsZSBmb3IgcHJvZHVjaW5nIHN0cmluZ3Mgc3VpdGFibGUgZm9yIGJlaW5nIGFwcGVuZGVkIHZlcmJhdGltCisgKiB0byB0aGUgZnJhZ21lbnQgcGFydCBvZiBhbiBSRkMzOTg2IFVSSS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEZyYWdtZW50IHsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBGcmFnbWVudCBFTVBUWV9GUkFHTUVOVCA9IG5ldyBGcmFnbWVudChudWxsKTsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBGcmFnbWVudC5QYXJhbVZhbHVlIEVNUFRZX0ZSQUdNRU5UX1BBUkFNX1ZBTFVFID0gbmV3IFBhcmFtVmFsdWUobnVsbCwgbnVsbCk7CisKKyAgcHJpdmF0ZSBmaW5hbCBMaXN0PFBhcmFtPiBwYXJhbXMgPSBuZXcgQXJyYXlMaXN0PFBhcmFtPigpOworCisgIHByaXZhdGUgRnJhZ21lbnQoQE51bGxhYmxlIExpc3Q8UGFyYW0+IHBhcmFtcykgeworICAgIGlmIChwYXJhbXMgIT0gbnVsbCkgeworICAgICAgdGhpcy5wYXJhbXMuYWRkQWxsKHBhcmFtcyk7CisgICAgfQorICB9CisKKyAgLyoqIENyZWF0ZSBhIG5ldywgZW1wdHkgYnVpbGRlci4gKi8KKyAgcHVibGljIHN0YXRpYyBGcmFnbWVudC5CdWlsZGVyIGJ1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ldyBGcmFnbWVudC5CdWlsZGVyKG51bGwpOworICB9CisKKyAgLyoqIFJldHVybiBhIGJ1aWxkZXIgYmFzZWQgb24gdGhpcyBGcmFnbWVudC4gKi8KKyAgcHVibGljIEZyYWdtZW50LkJ1aWxkZXIgdG9CdWlsZGVyKCkgeworICAgIEZyYWdtZW50LkJ1aWxkZXIgYnVpbGRlciA9IGJ1aWxkZXIoKTsKKyAgICBmb3IgKFBhcmFtIHBhcmFtIDogcGFyYW1zKSB7CisgICAgICBidWlsZGVyLmFkZFBhcmFtKHBhcmFtLnRvQnVpbGRlcigpKTsKKyAgICB9CisgICAgcmV0dXJuIGJ1aWxkZXI7CisgIH0KKworICAvKiogSXRlcmF0ZSBvdmVyIHRoZSBwYXJhbXMuICovCisgIHB1YmxpYyBMaXN0PFBhcmFtPiBwYXJhbXMoKSB7CisgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocGFyYW1zKTsKKyAgfQorCisgIC8qKiBGaW5kcyB0aGUgcGFyYW0gd2l0aCB0aGUgZ2l2ZW4ga2V5LiBSZXR1cm5zIG51bGwgaWYgbm90IGZvdW5kLiAqLworICBATnVsbGFibGUKKyAgcHVibGljIFBhcmFtIGZpbmRQYXJhbShTdHJpbmcga2V5KSB7CisgICAgZm9yIChQYXJhbSBwYXJhbSA6IHBhcmFtcykgeworICAgICAgaWYgKHBhcmFtLmtleS5lcXVhbHMoa2V5KSkgeworICAgICAgICByZXR1cm4gcGFyYW07CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBudWxsOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgcmV0dXJuIFRleHRVdGlscy5qb2luKCImIiwgcGFyYW1zKTsKKyAgfQorCisgIC8qKiBCdWlsZGVyIGZvciB0aGUgd2hvbGUgVVJJIGZyYWdtZW50LiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgeworICAgIHByaXZhdGUgZmluYWwgTGlzdDxQYXJhbS5CdWlsZGVyPiBwYXJhbXMgPSBuZXcgQXJyYXlMaXN0PFBhcmFtLkJ1aWxkZXI+KCk7CisKKyAgICBwcml2YXRlIEJ1aWxkZXIoQE51bGxhYmxlIExpc3Q8UGFyYW0uQnVpbGRlcj4gcGFyYW1zKSB7CisgICAgICBpZiAocGFyYW1zID09IG51bGwpIHsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgZm9yIChQYXJhbS5CdWlsZGVyIHBhcmFtIDogcGFyYW1zKSB7CisgICAgICAgIGFkZFBhcmFtKHBhcmFtKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogR2V0IGFsbCBvZiB0aGUgcGFyYW1zIGFzIGEgbGlzdC4gKi8KKyAgICBwdWJsaWMgTGlzdDxQYXJhbS5CdWlsZGVyPiBwYXJhbXMoKSB7CisgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChwYXJhbXMpOworICAgIH0KKworICAgIC8qKiBGaW5kcyB0aGUgcGFyYW0gd2l0aCB0aGUgZ2l2ZW4ga2V5LiBSZXR1cm5zIG51bGwgaWYgbm90IGZvdW5kLiAqLworICAgIEBOdWxsYWJsZQorICAgIHB1YmxpYyBQYXJhbS5CdWlsZGVyIGZpbmRQYXJhbShTdHJpbmcga2V5KSB7CisgICAgICBmb3IgKFBhcmFtLkJ1aWxkZXIgcGFyYW0gOiBwYXJhbXMpIHsKKyAgICAgICAgaWYgKHBhcmFtLmtleS5lcXVhbHMoa2V5KSkgeworICAgICAgICAgIHJldHVybiBwYXJhbTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgLyoqIEFkZHMgYSBwYXJhbS4gSWYgYSBwYXJhbSB3aXRoIHNhbWUga2V5IGFscmVhZHkgZXhpc3RzLCB0aGlzIHJlcGxhY2VzIGl0LiAqLworICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhcmFtKFBhcmFtIHBhcmFtKSB7CisgICAgICBhZGRQYXJhbShwYXJhbS50b0J1aWxkZXIoKSk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKiogQWRkcyBhIHBhcmFtLiBJZiBhIHBhcmFtIHdpdGggdGhlIHNhbWUga2V5IGFscmVhZHkgZXhpc3QsIHRoaXMgcmVwbGFjZXMgaXQuICovCisgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFyYW0oUGFyYW0uQnVpbGRlciBwYXJhbSkgeworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJhbXMuc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgaWYgKHBhcmFtcy5nZXQoaSkua2V5LmVxdWFscyhwYXJhbS5rZXkpKSB7CisgICAgICAgICAgcGFyYW1zLnNldChpLCBwYXJhbSk7CisgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHBhcmFtcy5hZGQocGFyYW0pOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqIEFkZHMgYSBzaW1wbGUgcGFyYW0gd2l0aCBubyB2YWx1ZS4gKi8KKyAgICBwdWJsaWMgQnVpbGRlciBhZGRQYXJhbShTdHJpbmcga2V5KSB7CisgICAgICByZXR1cm4gYWRkUGFyYW0oUGFyYW0uYnVpbGRlcihrZXkpKTsKKyAgICB9CisKKyAgICAvKiogUmV0dXJuIGFuIGltbXV0YWJsZSBGcmFnbWVudC4gVW5zZXQgcGFyYW1zIGFyZSBpZ25vcmVkLiAqLworICAgIHB1YmxpYyBGcmFnbWVudCBidWlsZCgpIHsKKyAgICAgIExpc3Q8UGFyYW0+IHBhcmFtcyA9IG5ldyBBcnJheUxpc3Q8UGFyYW0+KCk7CisgICAgICBmb3IgKFBhcmFtLkJ1aWxkZXIgYnVpbGRlciA6IHRoaXMucGFyYW1zKSB7CisgICAgICAgIFBhcmFtIHBhcmFtID0gYnVpbGRlci5idWlsZCgpOworICAgICAgICBpZiAocGFyYW0gIT0gbnVsbCkgeworICAgICAgICAgIHBhcmFtcy5hZGQocGFyYW0pOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gbmV3IEZyYWdtZW50KHBhcmFtcyk7CisgICAgfQorICB9CisKKyAgLyoqIEEgZnJhZ21lbnQgcGFyYW0uICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUGFyYW0geworICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIGtleTsKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8UGFyYW1WYWx1ZT4gdmFsdWVzID0gbmV3IEFycmF5TGlzdDxQYXJhbVZhbHVlPigpOworCisgICAgLyoqCisgICAgICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYge0Bjb2RlIHZhbHVlc30gaXMgZW1wdHkuCisgICAgICovCisgICAgcHJpdmF0ZSBQYXJhbShTdHJpbmcga2V5LCBMaXN0PFBhcmFtVmFsdWU+IHZhbHVlcykgeworICAgICAgUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KCF2YWx1ZXMuaXNFbXB0eSgpLCAiTWlzc2luZyBwYXJhbSB2YWx1ZXMiKTsKKyAgICAgIHRoaXMua2V5ID0ga2V5OworICAgICAgdGhpcy52YWx1ZXMuYWRkQWxsKHZhbHVlcyk7CisgICAgfQorCisgICAgLyoqIEdldHMgdGhlIGtleSBmb3IgdGhlIHBhcmFtLiAqLworICAgIHB1YmxpYyBTdHJpbmcga2V5KCkgeworICAgICAgcmV0dXJuIGtleTsKKyAgICB9CisKKyAgICAvKiogSXRlcmF0ZSBvdmVyIHRoZSB2YWx1ZXMuICovCisgICAgcHVibGljIExpc3Q8UGFyYW1WYWx1ZT4gdmFsdWVzKCkgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QodmFsdWVzKTsKKyAgICB9CisKKyAgICAvKiogRmluZCBhIHZhbHVlIGJ5IG5hbWUuIFJldHVybnMgbnVsbCBpZiBub3QgZm91bmQuICovCisgICAgQE51bGxhYmxlCisgICAgcHVibGljIFBhcmFtVmFsdWUgZmluZFZhbHVlKFN0cmluZyBuYW1lKSB7CisgICAgICBmb3IgKFBhcmFtVmFsdWUgdmFsdWUgOiB2YWx1ZXMpIHsKKyAgICAgICAgaWYgKHZhbHVlLm5hbWUuZXF1YWxzKG5hbWUpKSB7CisgICAgICAgICAgcmV0dXJuIHZhbHVlOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDcmVhdGUgYSBuZXcgcGFyYW0gaWRlbnRpZmllZCB3aXRoIGEga2V5LgorICAgICAqCisgICAgICogQHBhcmFtIGtleSBUaGUgdW5pcXVlIGtleS4KKyAgICAgKiBAcmV0dXJuIFRoZSBwYXJhbS4KKyAgICAgKi8KKyAgICBwdWJsaWMgc3RhdGljIFBhcmFtLkJ1aWxkZXIgYnVpbGRlcihTdHJpbmcga2V5KSB7CisgICAgICByZXR1cm4gbmV3IFBhcmFtLkJ1aWxkZXIoa2V5LCBudWxsKTsKKyAgICB9CisKKyAgICAvKiogUmV0dXJuIGEgYnVpbGRlciBiYXNlZCBvbiB0aGlzIFBhcmFtLiAqLworICAgIHB1YmxpYyBQYXJhbS5CdWlsZGVyIHRvQnVpbGRlcigpIHsKKyAgICAgIFBhcmFtLkJ1aWxkZXIgYnVpbGRlciA9IGJ1aWxkZXIoa2V5KTsKKyAgICAgIGZvciAoUGFyYW1WYWx1ZSB2YWx1ZSA6IHZhbHVlcykgeworICAgICAgICBidWlsZGVyLmFkZFZhbHVlKHZhbHVlLnRvQnVpbGRlcigpKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBidWlsZGVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CisgICAgICBTdHJpbmdCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOworICAgICAgYnVpbGRlci5hcHBlbmQodXJsRW5jb2RlKGtleSkpOworICAgICAgYnVpbGRlci5hcHBlbmQoIj0iKTsKKyAgICAgIGJ1aWxkZXIuYXBwZW5kKFRleHRVdGlscy5qb2luKCIrIiwgdmFsdWVzKSk7CisgICAgICByZXR1cm4gYnVpbGRlci50b1N0cmluZygpOworICAgIH0KKworICAgIC8qKiBCdWlsZGVyIGZvciBhIGZyYWdtZW50IHBhcmFtLiAqLworICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciB7CisgICAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBrZXk7CisgICAgICBwcml2YXRlIGZpbmFsIExpc3Q8UGFyYW1WYWx1ZS5CdWlsZGVyPiB2YWx1ZXMgPSBuZXcgQXJyYXlMaXN0PFBhcmFtVmFsdWUuQnVpbGRlcj4oKTsKKworICAgICAgcHJpdmF0ZSBCdWlsZGVyKFN0cmluZyBrZXksIEBOdWxsYWJsZSBMaXN0PFBhcmFtVmFsdWUuQnVpbGRlcj4gdmFsdWVzKSB7CisgICAgICAgIHRoaXMua2V5ID0ga2V5OworICAgICAgICBpZiAodmFsdWVzID09IG51bGwpIHsKKyAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZm9yIChQYXJhbVZhbHVlLkJ1aWxkZXIgdmFsdWUgOiB2YWx1ZXMpIHsKKyAgICAgICAgICBhZGRWYWx1ZSh2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgLyoqIEdldHMgdGhlIGtleSBmb3IgdGhlIHBhcmFtLiAqLworICAgICAgcHVibGljIFN0cmluZyBrZXkoKSB7CisgICAgICAgIHJldHVybiBrZXk7CisgICAgICB9CisKKyAgICAgIC8qKiBHZXQgYWxsIG9mIHRoZSBwYXJhbSB2YWx1ZXMgYXMgYSBsaXN0LiAqLworICAgICAgcHVibGljIExpc3Q8UGFyYW1WYWx1ZS5CdWlsZGVyPiB2YWx1ZXMoKSB7CisgICAgICAgIHJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHZhbHVlcyk7CisgICAgICB9CisKKyAgICAgIC8qKiBGaW5kIGEgdmFsdWUgYnkgbmFtZS4gUmV0dXJucyBudWxsIGlmIG5vdCBmb3VuZC4gKi8KKyAgICAgIEBOdWxsYWJsZQorICAgICAgcHVibGljIFBhcmFtVmFsdWUuQnVpbGRlciBmaW5kVmFsdWUoU3RyaW5nIG5hbWUpIHsKKyAgICAgICAgZm9yIChQYXJhbVZhbHVlLkJ1aWxkZXIgdmFsdWUgOiB2YWx1ZXMpIHsKKyAgICAgICAgICBpZiAodmFsdWUubmFtZS5lcXVhbHMobmFtZSkpIHsKKyAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisKKyAgICAgIC8qKgorICAgICAgICogQWRkcyBhIHZhbHVlIHRvIHRoaXMgcGFyYW0uIElmIGEgdmFsdWUgYWxyZWFkeSBleGlzdHMgd2l0aCB0aGUgc2FtZSBuYW1lLCB0aGlzIHdpbGwgcmVwbGFjZQorICAgICAgICogaXQuCisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFZhbHVlKFBhcmFtVmFsdWUgdmFsdWUpIHsKKyAgICAgICAgYWRkVmFsdWUodmFsdWUudG9CdWlsZGVyKCkpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgLyoqCisgICAgICAgKiBBZGRzIGEgdmFsdWUgdG8gdGhpcyBwYXJhbS4gSWYgYSB2YWx1ZSBhbHJlYWR5IGV4aXN0cyB3aXRoIHRoZSBzYW1lIG5hbWUsIHRoaXMgd2lsbCByZXBsYWNlCisgICAgICAgKiBpdC4KKyAgICAgICAqLworICAgICAgcHVibGljIEJ1aWxkZXIgYWRkVmFsdWUoUGFyYW1WYWx1ZS5CdWlsZGVyIHZhbHVlKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsdWVzLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgaWYgKHZhbHVlcy5nZXQoaSkubmFtZS5lcXVhbHModmFsdWUubmFtZSkpIHsKKyAgICAgICAgICAgIHZhbHVlcy5zZXQoaSwgdmFsdWUpOworICAgICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHZhbHVlcy5hZGQodmFsdWUpOworICAgICAgICByZXR1cm4gdGhpczsKKyAgICAgIH0KKworICAgICAgLyoqIEFkZHMgYSB2YWx1ZSB0aGF0IGhhcyBubyBzdWJwYXJhbXMuIEFsc28gcmVwbGFjZXMgZXhpc3RpbmcgdmFsdWUgaWYgcHJlc2VudC4gKi8KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFZhbHVlKFN0cmluZyBuYW1lKSB7CisgICAgICAgIHJldHVybiBhZGRWYWx1ZShuZXcgUGFyYW1WYWx1ZS5CdWlsZGVyKG5hbWUsIG51bGwpKTsKKyAgICAgIH0KKworICAgICAgLyoqIFJldHVybiBhIG5ldyBpbW11dGFibGUgUGFyYW0gZnJvbSB0aGlzIGJ1aWxkZXIsIG9yIG51bGwgaWYgdGhlIHBhcmFtIGlzIHVuc2V0LiAqLworICAgICAgQE51bGxhYmxlCisgICAgICBwdWJsaWMgUGFyYW0gYnVpbGQoKSB7CisgICAgICAgIGlmICh0aGlzLnZhbHVlcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfQorICAgICAgICBMaXN0PFBhcmFtVmFsdWU+IHZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8UGFyYW1WYWx1ZT4oKTsKKyAgICAgICAgZm9yIChQYXJhbVZhbHVlLkJ1aWxkZXIgdmFsdWUgOiB0aGlzLnZhbHVlcykgeworICAgICAgICAgIHZhbHVlcy5hZGQodmFsdWUuYnVpbGQoKSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG5ldyBQYXJhbShrZXksIHZhbHVlcyk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqIEEgdmFsdWUgb2YgYSBmcmFnbWVudCBwYXJhbS4gRWFjaCBmcmFnbWVudCBwYXJhbSBjYW4gaGF2ZSBtdWx0aXBsZSB2YWx1ZXMuICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUGFyYW1WYWx1ZSB7CisKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBuYW1lOworICAgIHByaXZhdGUgZmluYWwgTGlzdDxTdWJQYXJhbT4gc3VicGFyYW1zID0gbmV3IEFycmF5TGlzdDxTdWJQYXJhbT4oKTsKKworICAgIHByaXZhdGUgUGFyYW1WYWx1ZShTdHJpbmcgbmFtZSwgQE51bGxhYmxlIExpc3Q8U3ViUGFyYW0+IHN1YnBhcmFtcykgeworICAgICAgdGhpcy5uYW1lID0gbmFtZTsKKyAgICAgIGlmIChzdWJwYXJhbXMgIT0gbnVsbCkgeworICAgICAgICB0aGlzLnN1YnBhcmFtcy5hZGRBbGwoc3VicGFyYW1zKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvKiogQ3JlYXRlcyBhIG5ldyBwYXJhbSB2YWx1ZSB3aXRoIHRoZSBnaXZlbiBuYW1lLiAqLworICAgIHB1YmxpYyBzdGF0aWMgUGFyYW1WYWx1ZS5CdWlsZGVyIGJ1aWxkZXIoU3RyaW5nIG5hbWUpIHsKKyAgICAgIHJldHVybiBuZXcgUGFyYW1WYWx1ZS5CdWlsZGVyKG5hbWUsIG51bGwpOworICAgIH0KKworICAgIC8qKiBSZXR1cm4gYSBidWlsZGVyIGJhc2VkIG9uIHRoaXMgUGFyYW1WYWx1ZS4gKi8KKyAgICBwdWJsaWMgUGFyYW1WYWx1ZS5CdWlsZGVyIHRvQnVpbGRlcigpIHsKKyAgICAgIFBhcmFtVmFsdWUuQnVpbGRlciBidWlsZGVyID0gYnVpbGRlcihuYW1lKTsKKyAgICAgIGZvciAoU3ViUGFyYW0gc3VicGFyYW0gOiBzdWJwYXJhbXMpIHsKKyAgICAgICAgYnVpbGRlci5hZGRTdWJQYXJhbShzdWJwYXJhbSk7CisgICAgICB9CisgICAgICByZXR1cm4gYnVpbGRlcjsKKyAgICB9CisKKyAgICAvKiogVGhlIG5hbWUgb2YgdGhlIHBhcmFtIHZhbHVlLiAqLworICAgIHB1YmxpYyBTdHJpbmcgbmFtZSgpIHsKKyAgICAgIHJldHVybiBuYW1lOworICAgIH0KKworICAgIC8qKiBJdGVyYXRlIG92ZXIgdGhlIHN1YnBhcmFtcy4gKi8KKyAgICBwdWJsaWMgTGlzdDxTdWJQYXJhbT4gc3ViUGFyYW1zKCkgeworICAgICAgcmV0dXJuIENvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3Qoc3VicGFyYW1zKTsKKyAgICB9CisKKyAgICAvKiogRmluZHMgYSBzdWJwYXJhbSB3aXRoIHRoZSBnaXZlbiBrZXkuIElmIG5vdCBmb3VuZCwgcmV0dXJucyBudWxsLiAqLworICAgIEBOdWxsYWJsZQorICAgIHB1YmxpYyBTdWJQYXJhbSBmaW5kU3ViUGFyYW0oU3RyaW5nIGtleSkgeworICAgICAgZm9yIChTdWJQYXJhbSBzdWJwYXJhbSA6IHN1YnBhcmFtcykgeworICAgICAgICBpZiAoc3VicGFyYW0ua2V5LmVxdWFscyhrZXkpKSB7CisgICAgICAgICAgcmV0dXJuIHN1YnBhcmFtOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBGaW5kcyB0aGUgc3VicGFyYW0gdmFsdWUgd2l0aCB0aGUgZ2l2ZW4ga2V5LiBJZiB0aGUgc3VicGFyYW0gb3IgdmFsdWUgaXMgbnVsbCwgcmV0dXJucyBudWxsLgorICAgICAqCisgICAgICogQHBhcmFtIGtleQorICAgICAqIEByZXR1cm4gVGhlIHZhbHVlIG9mIHRoZSBzdWJwYXJhbSBvciBudWxsLgorICAgICAqLworICAgIEBOdWxsYWJsZQorICAgIHB1YmxpYyBTdHJpbmcgZmluZFN1YlBhcmFtVmFsdWUoU3RyaW5nIGtleSkgeworICAgICAgU3ViUGFyYW0gc3VicGFyYW0gPSBmaW5kU3ViUGFyYW0oa2V5KTsKKyAgICAgIHJldHVybiAoc3VicGFyYW0gPT0gbnVsbCkgPyBudWxsIDogc3VicGFyYW0udmFsdWU7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgICBidWlsZGVyLmFwcGVuZCh1cmxFbmNvZGUobmFtZSkpOworICAgICAgaWYgKHN1YnBhcmFtcy5pc0VtcHR5KCkpIHsKKyAgICAgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgICAgIH0KKyAgICAgIGJ1aWxkZXIuYXBwZW5kKCIoIik7CisgICAgICBidWlsZGVyLmFwcGVuZChUZXh0VXRpbHMuam9pbigiLCIsIHN1YnBhcmFtcykpOworICAgICAgYnVpbGRlci5hcHBlbmQoIikiKTsKKyAgICAgIHJldHVybiBidWlsZGVyLnRvU3RyaW5nKCk7CisgICAgfQorCisgICAgLyoqIEJ1aWxkZXIgZm9yIGEgZnJhZ21lbnQgcGFyYW0gdmFsdWUuICovCisgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIHsKKyAgICAgIHByaXZhdGUgZmluYWwgU3RyaW5nIG5hbWU7CisgICAgICBwcml2YXRlIGZpbmFsIExpc3Q8U3ViUGFyYW0+IHN1YnBhcmFtcyA9IG5ldyBBcnJheUxpc3Q8U3ViUGFyYW0+KCk7CisKKyAgICAgIHByaXZhdGUgQnVpbGRlcihTdHJpbmcgbmFtZSwgQE51bGxhYmxlIExpc3Q8U3ViUGFyYW0+IHN1YnBhcmFtcykgeworICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOworICAgICAgICBpZiAoc3VicGFyYW1zID09IG51bGwpIHsKKyAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZm9yIChTdWJQYXJhbSBzdWJwYXJhbSA6IHN1YnBhcmFtcykgeworICAgICAgICAgIGFkZFN1YlBhcmFtKHN1YnBhcmFtKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICAvKiogVGhlIG5hbWUgb2YgdGhlIHBhcmFtIHZhbHVlLiAqLworICAgICAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgICAgICByZXR1cm4gbmFtZTsKKyAgICAgIH0KKworICAgICAgLyoqIEdldCBhbGwgb2YgdGhlIHN1YnBhcmFtcyBhcyBhIGxpc3QuICovCisgICAgICBwdWJsaWMgTGlzdDxTdWJQYXJhbT4gc3VicGFyYW1zKCkgeworICAgICAgICByZXR1cm4gQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChzdWJwYXJhbXMpOworICAgICAgfQorCisgICAgICAvKiogRmluZHMgYSBzdWJwYXJhbSB3aXRoIHRoZSBnaXZlbiBrZXkuIElmIG5vdCBmb3VuZCwgcmV0dXJucyBudWxsLiAqLworICAgICAgQE51bGxhYmxlCisgICAgICBwdWJsaWMgU3ViUGFyYW0gZmluZFN1YlBhcmFtKFN0cmluZyBrZXkpIHsKKyAgICAgICAgZm9yIChTdWJQYXJhbSBzdWJwYXJhbSA6IHN1YnBhcmFtcykgeworICAgICAgICAgIGlmIChzdWJwYXJhbS5rZXkuZXF1YWxzKGtleSkpIHsKKyAgICAgICAgICAgIHJldHVybiBzdWJwYXJhbTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisKKyAgICAgIC8qKgorICAgICAgICogRmluZHMgdGhlIHN1YnBhcmFtIHZhbHVlIHdpdGggdGhlIGdpdmVuIGtleS4gSWYgdGhlIHN1YnBhcmFtIG9yIHZhbHVlIGlzIG51bGwsIHJldHVybnMKKyAgICAgICAqIG51bGwuCisgICAgICAgKgorICAgICAgICogQHBhcmFtIGtleQorICAgICAgICogQHJldHVybiBUaGUgdmFsdWUgb2YgdGhlIHN1YnBhcmFtIG9yIG51bGwuCisgICAgICAgKi8KKyAgICAgIEBOdWxsYWJsZQorICAgICAgcHVibGljIFN0cmluZyBmaW5kU3ViUGFyYW1WYWx1ZShTdHJpbmcga2V5KSB7CisgICAgICAgIFN1YlBhcmFtIHN1YnBhcmFtID0gZmluZFN1YlBhcmFtKGtleSk7CisgICAgICAgIHJldHVybiAoc3VicGFyYW0gPT0gbnVsbCkgPyBudWxsIDogc3VicGFyYW0udmFsdWU7CisgICAgICB9CisKKyAgICAgIC8qKgorICAgICAgICogQWRkcyBhIHN1YnBhcmFtLiBJZiBhbiBleGlzdGluZyBzdWJwYXJhbSBleGlzdHMgd2l0aCB0aGUgc2FtZSBrZXksIHRoaXMgd2lsbCByZXBsYWNlIGl0LgorICAgICAgICoKKyAgICAgICAqIEBwYXJhbSBzdWJwYXJhbQorICAgICAgICogQHJldHVybiBUaGUgc3VicGFyYW0gb3IgbnVsbCBpZiBub3QgZm91bmQuCisgICAgICAgKi8KKyAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFN1YlBhcmFtKFN1YlBhcmFtIHN1YnBhcmFtKSB7CisgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3VicGFyYW1zLnNpemUoKTsgaSsrKSB7CisgICAgICAgICAgaWYgKHN1YnBhcmFtcy5nZXQoaSkua2V5LmVxdWFscyhzdWJwYXJhbS5rZXkpKSB7CisgICAgICAgICAgICBzdWJwYXJhbXMuc2V0KGksIHN1YnBhcmFtKTsKKyAgICAgICAgICAgIHJldHVybiB0aGlzOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBzdWJwYXJhbXMuYWRkKHN1YnBhcmFtKTsKKyAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICB9CisKKyAgICAgIC8qKgorICAgICAgICogU2hvcnRjdXQgdG8gYWRkIGEgc3VicGFyYW0gd2l0aCB0aGlzIGtleSBhbmQgdmFsdWUuIFJlcGxhY2VzIGV4aXN0aW5nIHN1YnBhcmFtIHdpdGggc2FtZQorICAgICAgICoga2V5IGlmIHByZXNlbnQuCisgICAgICAgKgorICAgICAgICogQHBhcmFtIGtleSBUaGUgc3VicGFyYW0ga2V5LgorICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdWJwYXJhbSB2YWx1ZS4KKyAgICAgICAqLworICAgICAgcHVibGljIEJ1aWxkZXIgYWRkU3ViUGFyYW0oU3RyaW5nIGtleSwgU3RyaW5nIHZhbHVlKSB7CisgICAgICAgIHJldHVybiBhZGRTdWJQYXJhbShuZXcgU3ViUGFyYW0oa2V5LCB2YWx1ZSkpOworICAgICAgfQorCisgICAgICAvKiogQnVpbGQgYW4gaW1tdXRhYmxlIFBhcmFtVmFsdWUgZnJvbSB0aGlzIGJ1aWxkZXIuICovCisgICAgICBwdWJsaWMgUGFyYW1WYWx1ZSBidWlsZCgpIHsKKyAgICAgICAgcmV0dXJuIG5ldyBQYXJhbVZhbHVlKG5hbWUsIHN1YnBhcmFtcyk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqIEEgZnJhZ21lbnQgcGFyYW0gdmFsdWUgc3VicGFyYW0uICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU3ViUGFyYW0geworCisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcga2V5OworICAgIEBOdWxsYWJsZSBwcml2YXRlIGZpbmFsIFN0cmluZyB2YWx1ZTsKKworICAgIC8qKiBDcmVhdGVzIGEgbmV3IHN1YnBhcmFtIHdpdGggdGhlIGdpdmVuIGtleSBhbmQgdmFsdWUuICovCisgICAgcHVibGljIHN0YXRpYyBTdWJQYXJhbSBidWlsZChTdHJpbmcga2V5LCBTdHJpbmcgdmFsdWUpIHsKKyAgICAgIHJldHVybiBuZXcgU3ViUGFyYW0oa2V5LCB2YWx1ZSk7CisgICAgfQorCisgICAgLyoqIENyZWF0ZXMgYSBuZXcgc3VicGFyYW0gd2l0aCB0aGUgZ2l2ZW4ga2V5IGFuZCBubyB2YWx1ZS4gKi8KKyAgICBwdWJsaWMgc3RhdGljIFN1YlBhcmFtIGJ1aWxkKFN0cmluZyBrZXkpIHsKKyAgICAgIHJldHVybiBuZXcgU3ViUGFyYW0oa2V5LCBudWxsKTsKKyAgICB9CisKKyAgICBwcml2YXRlIFN1YlBhcmFtKFN0cmluZyBrZXksIEBOdWxsYWJsZSBTdHJpbmcgdmFsdWUpIHsKKyAgICAgIHRoaXMua2V5ID0ga2V5OworICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOworICAgIH0KKworICAgIC8qKiBSZXR1cm5zIHRoZSBzdWJwYXJhbSBrZXkuICovCisgICAgcHVibGljIFN0cmluZyBrZXkoKSB7CisgICAgICByZXR1cm4ga2V5OworICAgIH0KKworICAgIC8qKiBSZXR1cm5zIHRoZSBzdWJwYXJhbSB2YWx1ZSwgb3IgbnVsbCBpZiBub3Qgc2V0LiAqLworICAgIEBOdWxsYWJsZQorICAgIHB1YmxpYyBTdHJpbmcgdmFsdWUoKSB7CisgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorCisgICAgLyoqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3VicGFyYW0gaGFzIGEgdmFsdWUgc2V0LiAqLworICAgIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgeworICAgICAgcmV0dXJuIHZhbHVlICE9IG51bGw7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKKyAgICAgIGlmIChoYXNWYWx1ZSgpKSB7CisgICAgICAgIHJldHVybiB1cmxFbmNvZGUoa2V5KSArICI9IiArIHVybEVuY29kZSh2YWx1ZSk7CisgICAgICB9IGVsc2UgeworICAgICAgICByZXR1cm4gdXJsRW5jb2RlKGtleSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqIFBhcnNlcyBhIGZyYWdtZW50IGZyb20gdGhlIHVyaSBhcyBkZXNjcmliZWQgaW4ge0BsaW5rIEZyYWdtZW50fS4gKi8KKyAgcHVibGljIHN0YXRpYyBGcmFnbWVudCBwYXJzZShVcmkgdXJpKSB7CisgICAgcmV0dXJuIHBhcnNlKHVyaS5nZXRFbmNvZGVkRnJhZ21lbnQoKSk7CisgIH0KKworICAvKiogUGFyc2VzIGEgZnJhZ21lbnQgZnJvbSBhbiBlbmNvZGVkIHN0cmluZyBhcyBkZXNjcmliZWQgaW4ge0BsaW5rIEZyYWdtZW50fS4gKi8KKyAgcHVibGljIHN0YXRpYyBGcmFnbWVudCBwYXJzZShATnVsbGFibGUgU3RyaW5nIGVuY29kZWRGcmFnbWVudCkgeworICAgIGlmIChUZXh0VXRpbHMuaXNFbXB0eShlbmNvZGVkRnJhZ21lbnQpKSB7CisgICAgICByZXR1cm4gRU1QVFlfRlJBR01FTlQ7CisgICAgfQorICAgIExpc3Q8UGFyYW0uQnVpbGRlcj4gcGFyYW1zID0gbmV3IEFycmF5TGlzdDxQYXJhbS5CdWlsZGVyPigpOworICAgIGZvciAoU3RyaW5nIGt2UGFpciA6IGVuY29kZWRGcmFnbWVudC5zcGxpdCgiJiIpKSB7CisgICAgICBTdHJpbmdbXSBrdiA9IGt2UGFpci5zcGxpdCgiPSIsIDIpOworICAgICAgTGlzdDxQYXJhbVZhbHVlLkJ1aWxkZXI+IHZhbHVlcyA9IG5ldyBBcnJheUxpc3Q8UGFyYW1WYWx1ZS5CdWlsZGVyPigpOworICAgICAgU3RyaW5nIGtleSA9IGt2WzBdOworICAgICAgUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KCFUZXh0VXRpbHMuaXNFbXB0eShrZXkpLCAibWFsZm9ybWVkIGtleTogJXMiLCBlbmNvZGVkRnJhZ21lbnQpOworICAgICAgUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KAorICAgICAgICAgIGt2Lmxlbmd0aCA9PSAyICYmICFUZXh0VXRpbHMuaXNFbXB0eShrdlsxXSksICJtaXNzaW5nIHBhcmFtIHZhbHVlOiAlcyIsIGVuY29kZWRGcmFnbWVudCk7CisgICAgICBTdHJpbmcgcmF3VmFsdWVzID0ga3ZbMV07CisgICAgICBTdHJpbmdbXSBzcGxpdFZhbHVlcyA9IHJhd1ZhbHVlcy5zcGxpdCgiXFwrIik7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNwbGl0VmFsdWVzLmxlbmd0aDsgaSsrKSB7CisgICAgICAgIFN0cmluZyB2YWx1ZSA9IHNwbGl0VmFsdWVzW2ldOworICAgICAgICBpZiAodmFsdWUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgTGlzdDxTdWJQYXJhbT4gc3VicGFyYW1zID0gbnVsbDsKKyAgICAgICAgaW50IGxwYXJlbiA9IHZhbHVlLmluZGV4T2YoIigiKTsKKyAgICAgICAgaWYgKGxwYXJlbiAhPSAtMSkgeworICAgICAgICAgIFN0cmluZyByYXdTdWJwYXJhbXMgPSB2YWx1ZS5zdWJzdHJpbmcobHBhcmVuKTsKKyAgICAgICAgICBQcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoCisgICAgICAgICAgICAgIHJhd1N1YnBhcmFtcy5jaGFyQXQoMCkgPT0gJygnCisgICAgICAgICAgICAgICAgICAmJiByYXdTdWJwYXJhbXMuY2hhckF0KHJhd1N1YnBhcmFtcy5sZW5ndGgoKSAtIDEpID09ICcpJywKKyAgICAgICAgICAgICAgIm1hbGZvcm1lZCBmcmFnbWVudCBzdWJwYXJhbXM6ICVzIiwKKyAgICAgICAgICAgICAgZW5jb2RlZEZyYWdtZW50KTsKKyAgICAgICAgICBzdWJwYXJhbXMgPSBwYXJzZVN1YlBhcmFtcyhyYXdTdWJwYXJhbXMuc3Vic3RyaW5nKDEsIHJhd1N1YnBhcmFtcy5sZW5ndGgoKSAtIDEpKTsKKyAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cmluZygwLCBscGFyZW4pOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIFByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudCgKKyAgICAgICAgICAgICAgIXZhbHVlLmNvbnRhaW5zKCIpIiksICJtYWxmb3JtZWQgZnJhZ21lbnQgc3VicGFyYW1zOiAlcyIsIGVuY29kZWRGcmFnbWVudCk7CisgICAgICAgIH0KKyAgICAgICAgdmFsdWVzLmFkZChuZXcgUGFyYW1WYWx1ZS5CdWlsZGVyKHVybERlY29kZSh2YWx1ZSksIHN1YnBhcmFtcykpOworICAgICAgfQorICAgICAgcGFyYW1zLmFkZChuZXcgUGFyYW0uQnVpbGRlcih1cmxEZWNvZGUoa2V5KSwgdmFsdWVzKSk7CisgICAgfQorICAgIHJldHVybiBuZXcgRnJhZ21lbnQuQnVpbGRlcihwYXJhbXMpLmJ1aWxkKCk7CisgIH0KKworICAvLyBUT0RPOiBUaGlzIG1ldGhvZCBwcm9iYWJseSBzaG91bGQgYmUgZWxzZXdoZXJlLCBwZXJoYXBzIGluIGEgbGl0ZSBmcmFnbWVudCBoZWxwZXIgY2xhc3MuCisgIEBOdWxsYWJsZQorICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRUcmFuc2Zvcm1TdWJQYXJhbShVcmkgdXJpLCBTdHJpbmcgdHJhbnNmb3JtTmFtZSwgU3RyaW5nIHN1YlBhcmFtS2V5KSB7CisgICAgRnJhZ21lbnQuUGFyYW1WYWx1ZSB2YWx1ZSA9IGdldFRyYW5zZm9ybVBhcmFtVmFsdWUodXJpLCB0cmFuc2Zvcm1OYW1lKTsKKyAgICBpZiAodmFsdWUgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIFN0cmluZyByZXN1bHQgPSB2YWx1ZS5maW5kU3ViUGFyYW1WYWx1ZShzdWJQYXJhbUtleSk7CisgICAgcmV0dXJuICFUZXh0VXRpbHMuaXNFbXB0eShyZXN1bHQpID8gcmVzdWx0IDogbnVsbDsKKyAgfQorCisgIEBOdWxsYWJsZQorICBwdWJsaWMgc3RhdGljIEZyYWdtZW50LlBhcmFtVmFsdWUgZ2V0VHJhbnNmb3JtUGFyYW1WYWx1ZShVcmkgdXJpLCBTdHJpbmcgdHJhbnNmb3JtTmFtZSkgeworICAgIEZyYWdtZW50LlBhcmFtIHBhcmFtID0gRnJhZ21lbnQucGFyc2UodXJpKS5maW5kUGFyYW0oInRyYW5zZm9ybSIpOworICAgIGlmIChwYXJhbSA9PSBudWxsKSB7CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgICAgcmV0dXJuIHBhcmFtLmZpbmRWYWx1ZSh0cmFuc2Zvcm1OYW1lKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIExpc3Q8U3ViUGFyYW0+IHBhcnNlU3ViUGFyYW1zKFN0cmluZyByYXdTdWJwYXJhbXMpIHsKKyAgICBMaXN0PFN1YlBhcmFtPiBzdWJwYXJhbXMgPSBuZXcgQXJyYXlMaXN0PFN1YlBhcmFtPigpOworICAgIFN0cmluZ1tdIHBhaXJzID0gcmF3U3VicGFyYW1zLnNwbGl0KCIsIik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWlycy5sZW5ndGg7IGkrKykgeworICAgICAgU3RyaW5nW10ga3YgPSBwYWlyc1tpXS5zcGxpdCgiPSIsIDIpOworICAgICAgU3RyaW5nIGtleSA9IGt2WzBdOworICAgICAgUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KAorICAgICAgICAgICFUZXh0VXRpbHMuaXNFbXB0eShrZXkpLCAibWlzc2luZyBmcmFnbWVudCBzdWJwYXJhbSBrZXk6ICVzIiwgcmF3U3VicGFyYW1zKTsKKyAgICAgIGlmIChrdi5sZW5ndGggPT0gMiAmJiAhVGV4dFV0aWxzLmlzRW1wdHkoa3ZbMV0pKSB7CisgICAgICAgIHN1YnBhcmFtcy5hZGQobmV3IFN1YlBhcmFtKHVybERlY29kZShrZXkpLCB1cmxEZWNvZGUoa3ZbMV0pKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzdWJwYXJhbXMuYWRkKG5ldyBTdWJQYXJhbSh1cmxEZWNvZGUoa2V5KSwgbnVsbCkpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gc3VicGFyYW1zOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHVybEVuY29kZShTdHJpbmcgc3RyKSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiBVUkxFbmNvZGVyLmVuY29kZShzdHIsIFVURl84LmRpc3BsYXlOYW1lKCkpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOyAvLyBOb3QgcmVhbGx5CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHVybERlY29kZShTdHJpbmcgc3RyKSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiBVUkxEZWNvZGVyLmRlY29kZShzdHIsIFVURl84LmRpc3BsYXlOYW1lKCkpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigpOyAvLyBOb3QgcmVhbGx5CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0djUGFyYW0uamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vR2NQYXJhbS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlMDFlNmQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0djUGFyYW0uamF2YQpAQCAtMCwwICsxLDkyIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbjsKKworLy8gVE9ETzogaW52ZXN0aWdhdGUgdXNpbmcgb3JnLmpvZGEudGltZS5pbnN0YW50IGluc3RlYWQgb2YgRGF0ZQoraW1wb3J0IGphdmEudXRpbC5EYXRlOworCisvKiogU3BlY2lmaWNhdGlvbiBvZiBHQyBiZWhhdmlvciBmb3IgYSBnaXZlbiBmaWxlLiAqLworcHVibGljIGZpbmFsIGNsYXNzIEdjUGFyYW0geworCisgIHByaXZhdGUgc3RhdGljIGVudW0gQ29kZSB7CisgICAgTk9ORSwKKyAgICBFWFBJUkVTX0FUCisgIH0KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBHY1BhcmFtIE5PTkVfUEFSQU0gPSBuZXcgR2NQYXJhbShDb2RlLk5PTkUsIG51bGwpOworCisgIHByaXZhdGUgZmluYWwgQ29kZSBjb2RlOworICBwcml2YXRlIGZpbmFsIERhdGUgZGF0ZTsKKworICBwcml2YXRlIEdjUGFyYW0oQ29kZSBjb2RlLCBEYXRlIGRhdGUpIHsKKyAgICB0aGlzLmNvZGUgPSBjb2RlOworICAgIHRoaXMuZGF0ZSA9IGRhdGU7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiBBIEdjUGFyYW0gZm9yIGV4cGlyYXRpb24gYXQgdGhlIGdpdmVuIGRhdGUuCisgICAqLworICBwdWJsaWMgc3RhdGljIEdjUGFyYW0gZXhwaXJlc0F0KERhdGUgZGF0ZSkgeworICAgIHJldHVybiBuZXcgR2NQYXJhbShDb2RlLkVYUElSRVNfQVQsIGRhdGUpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gdGhlICJub25lIiBHY1BhcmFtLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBHY1BhcmFtIG5vbmUoKSB7CisgICAgcmV0dXJuIE5PTkVfUEFSQU07CisgIH0KKworICAvKioKKyAgICogQHJldHVybiB0aGUgZXhwaXJhdGlvbiBhc3NvY2lhdGVkIHdpdGgge0Bjb2RlIHRoaXN9LgorICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB0aGUgR2NQYXJhbSBpcyBub3QgYW4gZXhwaXJhdGlvbgorICAgKi8KKyAgcHVibGljIERhdGUgZ2V0RXhwaXJhdGlvbigpIHsKKyAgICBpZiAoIWlzRXhwaXJlc0F0KCkpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIkdjUGFyYW0gaXMgbm90IGFuIGV4cGlyYXRpb24iKTsKKyAgICB9CisgICAgcmV0dXJuIGRhdGU7CisgIH0KKworICAvKioKKyAgICogQHJldHVybiB3aGV0aGVyIHtAY29kZSB0aGlzfSBpcyBhbiBleHBpcmF0aW9uIEdjUGFyYW0KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzRXhwaXJlc0F0KCkgeworICAgIHJldHVybiBjb2RlID09IENvZGUuRVhQSVJFU19BVDsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIHdoZXRoZXIge0Bjb2RlIHRoaXN9IGlzIHRoZSBub25lIEdjUGFyYW0KKyAgICovCisgIHB1YmxpYyBib29sZWFuIGlzTm9uZSgpIHsKKyAgICByZXR1cm4gY29kZSA9PSBDb2RlLk5PTkU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvYmopIHsKKyAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBHY1BhcmFtKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBHY1BhcmFtIHRoYXQgPSAoR2NQYXJhbSkgb2JqOworICAgIHJldHVybiAodGhpcy5jb2RlID09IHRoYXQuY29kZSkKKyAgICAgICAgJiYgKHRoaXMuaXNOb25lKCkgfHwgdGhpcy5kYXRlLmdldFRpbWUoKSA9PSB0aGF0LmRhdGUuZ2V0VGltZSgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgeworICAgIHJldHVybiBpc05vbmUoKSA/IDAgOiBkYXRlLmhhc2hDb2RlKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vSW52YWxpZEFjY291bnRFeGNlcHRpb24uamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vSW52YWxpZEFjY291bnRFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNWNmMzIxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9JbnZhbGlkQWNjb3VudEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqIEV4Y2VwdGlvbiB0aHJvd24gd2hlbiBhbiBhY2NvdW50IGRvZXMgbm90IGV4aXN0LiAqLworcHVibGljIGZpbmFsIGNsYXNzIEludmFsaWRBY2NvdW50RXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24geworICBwdWJsaWMgSW52YWxpZEFjY291bnRFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICBzdXBlcihtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyBJbnZhbGlkQWNjb3VudEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICB9CisKKyAgcHVibGljIEludmFsaWRBY2NvdW50RXhjZXB0aW9uKFRocm93YWJsZSBjYXVzZSkgeworICAgIHN1cGVyKGNhdXNlKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9MYXp5SW5pdGlhbGl6YWJsZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9MYXp5SW5pdGlhbGl6YWJsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYyNGNlYTEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0xhenlJbml0aWFsaXphYmxlLmphdmEKQEAgLTAsMCArMSwyNyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb247CisKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIEEgY2xhc3Mgd2hvc2UgaW5pdGlhbGl6YXRpb24gcmVxdWlyZXMgZGlzayBJTywgd2hpY2ggaXMgZGVmZXJyZWQgdG8gdGhlIHRpbWUgb2YgZmlyc3QgdXNlLiBUaGUKKyAqIGNsaWVudCBjYW4gb3B0aW9uYWxseSBjYWxsIHtAbGluayAjaW5pdH0gb24gdGhlIGNsYXNzIGluIG9yZGVyIHRvIGluaXRpYWxpemUgaXQgKGFuZCBoYW5kbGUgYW55CisgKiBleGNlcHRpb25zKSBpbW1lZGlhdGVseS4KKyAqLworcHVibGljIGludGVyZmFjZSBMYXp5SW5pdGlhbGl6YWJsZSB7CisgIHZvaWQgaW5pdCgpIHRocm93cyBJT0V4Y2VwdGlvbjsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vTGltaXRFeGNlZWRlZEV4Y2VwdGlvbi5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9MaW1pdEV4Y2VlZGVkRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWJmNzRkMAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vTGltaXRFeGNlZWRlZEV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsMzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uOworCisvKiogRXhjZXB0aW9uIHRocm93biB0byBpbmRpY2F0ZSB0aGF0IGEgbGltaXQgc2V0IGJ5IHRoZSBzeXN0ZW0gaGFzIGJlZW4gZXhjZWVkLiAqLworcHVibGljIGZpbmFsIGNsYXNzIExpbWl0RXhjZWVkZWRFeGNlcHRpb24gZXh0ZW5kcyBSdW50aW1lRXhjZXB0aW9uIHsKKyAgcHVibGljIExpbWl0RXhjZWVkZWRFeGNlcHRpb24oKSB7CisgICAgc3VwZXIoKTsKKyAgfQorCisgIHB1YmxpYyBMaW1pdEV4Y2VlZGVkRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisgICAgc3VwZXIobWVzc2FnZSk7CisgIH0KKworICBwdWJsaWMgTGltaXRFeGNlZWRlZEV4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgc3VwZXIobWVzc2FnZSwgY2F1c2UpOworICB9CisKKyAgcHVibGljIExpbWl0RXhjZWVkZWRFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgc3VwZXIoY2F1c2UpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0xvY2suamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vTG9jay5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZmMTU4NWIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0xvY2suamF2YQpAQCAtMCwwICsxLDMyIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbjsKKworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKiBFbnN1cmVzIG11dHVhbCBleGNsdXNpdmUgYWNjZXNzIHRvIGEgcmVzb3VyY2UuICovCitwdWJsaWMgaW50ZXJmYWNlIExvY2sgZXh0ZW5kcyBDbG9zZWFibGUgeworCisgIC8qKiBSZWxlYXNlcyB0aGUgbG9jayB0aGF0IGlzIGhlbGQuICovCisgIHZvaWQgcmVsZWFzZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAvKiogUmV0dXJucyB0cnVlIGlmIGxvY2sgaXMgc3RpbGwgaGVsZC4gKi8KKyAgYm9vbGVhbiBpc1ZhbGlkKCk7CisKKyAgLyoqIFJldHVybnMgdHJ1ZSBpZiBsb2NrIGlzIHNoYXJlZCBhbmQgZmFsc2UgaWYgaXQgaXMgZXhjbHVzaXZlLiAqLworICBib29sZWFuIGlzU2hhcmVkKCk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0xvY2tTY29wZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9Mb2NrU2NvcGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMGU2OGUwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9Mb2NrU2NvcGUuamF2YQpAQCAtMCwwICsxLDI3NiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb247CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkludGVycnVwdGVkSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUxvY2s7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TZW1hcGhvcmU7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5OdWxsYWJsZTsKKworLyoqCisgKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgTG9ja30gYmFzZWQgb24gYSBKYXZhIGNoYW5uZWwge0BsaW5rIEZpbGVMb2NrfSBhbmQgU2VtYXBob3Jlcy4gSXQKKyAqIGhhbmRsZXMgbXVsdGktdGhyZWFkIGFuZCBtdWx0aS1wcm9jZXNzIGV4Y2x1c2lvbi4KKyAqCisgKiA8cD5OT1RFOiBNdWx0aS10aHJlYWQgZXhjbHVzaW9uIGlzIG5vdCBzdXBwb3J0ZWQgbmF0aXZlbHkgYnkgSmF2YSAoU2VlIHtAbGluaworICogaHR0cHM6Ly9kb2NzLm9yYWNsZS5jb20vamF2YXNlLzcvZG9jcy9hcGkvamF2YS9uaW8vY2hhbm5lbHMvRmlsZUNoYW5uZWwuaHRtbH0pLCBidXQgaXQgaXMKKyAqIHByb3ZpZGVkIGhlcmUuIEZvciBpdCB0byB3b3JrIHByb3Blcmx5LCBhIG1hcCBmcm9tIGZpbGUgbmFtZSB0byBTZW1hcGhvcmUgaXMgbWFpbnRhaW5lZC4gSWYgdGhlCisgKiBzY29wZSBvZiB0aGF0IG1hcCBpcyBub3QgYmlnIGVub3VnaCAoZWcsIGlmIHRoZSBtYXAgaXMgbWFpbnRhaW5lZCBpbiBhIEJhY2tlbmQsIGJ1dCB0aGVyZSBhcmUKKyAqIG11bHRpcGxlIEJhY2tlbmQgaW5zdGFuY2VzIGFjY2Vzc2luZyB0aGUgc2FtZSBmaWxlKSwgaXQgaXMgc3RpbGwgcG9zc2libGUgdG8gZ2V0IGEKKyAqIE92ZXJsYXBwaW5nRmlsZUxvY2tFeGNlcHRpb24uCisgKgorICogPHA+Tk9URTogVGhlIGtleXMgaW4gdGhlIHNlbWFwaG9yZSBtYXAgYXJlIGdlbmVyYXRlZCBmcm9tIHRoZSBGaWxlIG9yIFVyaSBzdHJpbmcuIE5vIGF0dGVtcHQgaXMKKyAqIG1hZGUgdG8gY2Fub25pY2FsaXplIHRob3NlIHN0cmluZ3MsIG9yIGRlYWwgd2l0aCBvdGhlciBjb3JuZXIgY2FzZXMgbGlrZSBoYXJkIGxpbmtzLgorICoKKyAqIDxwPlRPRE86IEltcGxlbWVudGVkIHNoYXJlZCB0aHJlYWQgbG9ja3MgaWYgbmVlZGVkLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTG9ja1Njb3BlIHsKKworICBATnVsbGFibGUgcHJpdmF0ZSBmaW5hbCBDb25jdXJyZW50TWFwPFN0cmluZywgU2VtYXBob3JlPiBsb2NrTWFwOworCisgIC8qKgorICAgKiBAZGVwcmVjYXRlZCBQcmVmZXIgdGhlIHN0YXRpYyB7QGxpbmsgY3JlYXRlKCl9IGZhY3RvcnkgbWV0aG9kLgorICAgKi8KKyAgQERlcHJlY2F0ZWQKKyAgcHVibGljIExvY2tTY29wZSgpIHsKKyAgICB0aGlzKG5ldyBDb25jdXJyZW50SGFzaE1hcDw+KCkpOworICB9CisKKyAgcHJpdmF0ZSBMb2NrU2NvcGUoQ29uY3VycmVudE1hcDxTdHJpbmcsIFNlbWFwaG9yZT4gbG9ja01hcCkgeworICAgIHRoaXMubG9ja01hcCA9IGxvY2tNYXA7CisgIH0KKworICAvKiogUmV0dXJucyBhIG5ldyBpbnN0YW5jZS4gKi8KKyAgcHVibGljIHN0YXRpYyBMb2NrU2NvcGUgY3JlYXRlKCkgeworICAgIHJldHVybiBuZXcgTG9ja1Njb3BlKG5ldyBDb25jdXJyZW50SGFzaE1hcDw+KCkpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgYSBuZXcgaW5zdGFuY2UgdGhhdCB3aWxsIHVzZSB0aGUgZ2l2ZW4gbWFwIGZvciBsb2NrIGxlYXNpbmcuIFRoaXMgaXMgb25seSBuZWNlc3NhcnkgaWYKKyAgICoge0Bjb2RlIExvY2tTY29wZX0gY2FuJ3QgYmUgYSBtYW5hZ2VkIGFzIGEgc2luZ2xldG9uIGJ1dCB7QGNvZGUgbG9ja01hcH0gY2FuIGJlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBMb2NrU2NvcGUgY3JlYXRlV2l0aEV4aXN0aW5nVGhyZWFkTG9ja3MoQ29uY3VycmVudE1hcDxTdHJpbmcsIFNlbWFwaG9yZT4gbG9ja01hcCkgeworICAgIHJldHVybiBuZXcgTG9ja1Njb3BlKGxvY2tNYXApOworICB9CisKKyAgLyoqIFJldHVybnMgYSBuZXcgaW5zdGFuY2UgdGhhdCB3aWxsIGFsd2F5cyBmYWlsIHRvIGFjcXVpcmUgdGhyZWFkIGxvY2tzLiAqLworICBwdWJsaWMgc3RhdGljIExvY2tTY29wZSBjcmVhdGVXaXRoRmFpbGluZ1RocmVhZExvY2tzKCkgeworICAgIHJldHVybiBuZXcgTG9ja1Njb3BlKG51bGwpOworICB9CisKKyAgLyoqIEFjcXVpcmVzIGEgY3Jvc3MtdGhyZWFkIGxvY2sgb24ge0Bjb2RlIHVyaX0uIFRoaXMgYmxvY2tzIHVudGlsIHRoZSBsb2NrIGlzIG9idGFpbmVkLiAqLworICBwdWJsaWMgTG9jayB0aHJlYWRMb2NrKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKCF0aHJlYWRMb2Nrc0FyZUF2YWlsYWJsZSgpKSB7CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbigiQ291bGRuJ3QgYWNxdWlyZSBsb2NrIik7CisgICAgfQorCisgICAgU2VtYXBob3JlIHNlbWFwaG9yZSA9IGdldE9yQ3JlYXRlU2VtYXBob3JlKHVyaS50b1N0cmluZygpKTsKKyAgICB0cnkgKFNlbWFwaG9yZVJlc291cmNlIHNlbWFwaG9yZVJlc291cmNlID0gU2VtYXBob3JlUmVzb3VyY2UuYWNxdWlyZShzZW1hcGhvcmUpKSB7CisgICAgICByZXR1cm4gbmV3IFNlbWFwaG9yZUxvY2tJbXBsKHNlbWFwaG9yZVJlc291cmNlLnJlbGVhc2VGcm9tVHJ5QmxvY2soKSk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEF0dGVtcHRzIHRvIGFjcXVpcmUgYSBjcm9zcy10aHJlYWQgbG9jayBvbiB7QGNvZGUgdXJpfS4gVGhpcyBkb2VzIG5vdCBibG9jaywgYW5kIHJldHVybnMgbnVsbAorICAgKiBpZiB0aGUgbG9jayBjYW5ub3QgYmUgb2J0YWluZWQgaW1tZWRpYXRlbHkuCisgICAqLworICBATnVsbGFibGUKKyAgcHVibGljIExvY2sgdHJ5VGhyZWFkTG9jayhVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICghdGhyZWFkTG9ja3NBcmVBdmFpbGFibGUoKSkgeworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorCisgICAgU2VtYXBob3JlIHNlbWFwaG9yZSA9IGdldE9yQ3JlYXRlU2VtYXBob3JlKHVyaS50b1N0cmluZygpKTsKKyAgICB0cnkgKFNlbWFwaG9yZVJlc291cmNlIHNlbWFwaG9yZVJlc291cmNlID0gU2VtYXBob3JlUmVzb3VyY2UudHJ5QWNxdWlyZShzZW1hcGhvcmUpKSB7CisgICAgICBpZiAoIXNlbWFwaG9yZVJlc291cmNlLmFjcXVpcmVkKCkpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgICByZXR1cm4gbmV3IFNlbWFwaG9yZUxvY2tJbXBsKHNlbWFwaG9yZVJlc291cmNlLnJlbGVhc2VGcm9tVHJ5QmxvY2soKSk7CisgICAgfQorICB9CisKKyAgLyoqIEFjcXVpcmVzIGEgY3Jvc3MtcHJvY2VzcyBsb2NrIG9uIHtAY29kZSBjaGFubmVsfS4gVGhpcyBibG9ja3MgdW50aWwgdGhlIGxvY2sgaXMgb2J0YWluZWQuICovCisgIHB1YmxpYyBMb2NrIGZpbGVMb2NrKEZpbGVDaGFubmVsIGNoYW5uZWwsIGJvb2xlYW4gc2hhcmVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZpbGVMb2NrIGxvY2sgPSBjaGFubmVsLmxvY2soMEwgLyogcG9zaXRpb24gKi8sIExvbmcuTUFYX1ZBTFVFIC8qIHNpemUgKi8sIHNoYXJlZCk7CisgICAgcmV0dXJuIG5ldyBGaWxlTG9ja0ltcGwobG9jayk7CisgIH0KKworICAvKioKKyAgICogQXR0ZW1wdHMgdG8gYWNxdWlyZSBhIGNyb3NzLXByb2Nlc3MgbG9jayBvbiB7QGNvZGUgY2hhbm5lbH0uIFRoaXMgZG9lcyBub3QgYmxvY2ssIGFuZCByZXR1cm5zCisgICAqIG51bGwgaWYgdGhlIGxvY2sgY2Fubm90IGJlIG9idGFpbmVkIGltbWVkaWF0ZWx5LgorICAgKi8KKyAgQE51bGxhYmxlCisgIHB1YmxpYyBMb2NrIHRyeUZpbGVMb2NrKEZpbGVDaGFubmVsIGNoYW5uZWwsIGJvb2xlYW4gc2hhcmVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBGaWxlTG9jayBsb2NrID0gY2hhbm5lbC50cnlMb2NrKDBMIC8qIHBvc2l0aW9uICovLCBMb25nLk1BWF9WQUxVRSAvKiBzaXplICovLCBzaGFyZWQpOworICAgICAgaWYgKGxvY2sgPT0gbnVsbCkgeworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIHJldHVybiBuZXcgRmlsZUxvY2tJbXBsKGxvY2spOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CisgICAgICAvLyBBbmRyb2lkIHRocm93cyBJT0V4Y2VwdGlvbiB3aXRoIG1lc3NhZ2UgImZjbnRsIGZhaWxlZDogRUFHQUlOIChUcnkgYWdhaW4pIiBpbnN0ZWFkCisgICAgICAvLyBvZiByZXR1cm5pbmcgbnVsbCBhcyBleHBlY3RlZC4KKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgYm9vbGVhbiB0aHJlYWRMb2Nrc0FyZUF2YWlsYWJsZSgpIHsKKyAgICByZXR1cm4gbG9ja01hcCAhPSBudWxsOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRmlsZUxvY2tJbXBsIGltcGxlbWVudHMgTG9jayB7CisKKyAgICBwcml2YXRlIEZpbGVMb2NrIGZpbGVMb2NrOworICAgIHByaXZhdGUgU2VtYXBob3JlIHNlbWFwaG9yZTsKKworICAgIHB1YmxpYyBGaWxlTG9ja0ltcGwoRmlsZUxvY2sgZmlsZUxvY2spIHsKKyAgICAgIHRoaXMuZmlsZUxvY2sgPSBmaWxlTG9jazsKKyAgICAgIHRoaXMuc2VtYXBob3JlID0gbnVsbDsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBAZGVwcmVjYXRlZCBQcmVmZXIgdGhlIHNpbmdsZS1hcmd1bWVudCB7QGNvZGUgRmlsZUxvY2tJbXBsKEZpbGVMb2NrKX0uCisgICAgICovCisgICAgQERlcHJlY2F0ZWQKKyAgICBwdWJsaWMgRmlsZUxvY2tJbXBsKEZpbGVMb2NrIGZpbGVMb2NrLCBTZW1hcGhvcmUgc2VtYXBob3JlKSB7CisgICAgICB0aGlzLmZpbGVMb2NrID0gZmlsZUxvY2s7CisgICAgICB0aGlzLnNlbWFwaG9yZSA9IHNlbWFwaG9yZTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCByZWxlYXNlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIFRoZSBzZW1hcGhvcmUgZ3VhcmRzIGFjY2VzcyB0byB0aGUgZmlsZUxvY2ssIHNvIGZpbGVMb2NrICptdXN0KiBiZSByZWxlYXNlZCBmaXJzdC4KKyAgICAgIHRyeSB7CisgICAgICAgIGlmIChmaWxlTG9jayAhPSBudWxsKSB7CisgICAgICAgICAgZmlsZUxvY2sucmVsZWFzZSgpOworICAgICAgICAgIGZpbGVMb2NrID0gbnVsbDsKKyAgICAgICAgfQorICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgaWYgKHNlbWFwaG9yZSAhPSBudWxsKSB7CisgICAgICAgICAgc2VtYXBob3JlLnJlbGVhc2UoKTsKKyAgICAgICAgICBzZW1hcGhvcmUgPSBudWxsOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZCgpIHsKKyAgICAgIHJldHVybiBmaWxlTG9jay5pc1ZhbGlkKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNTaGFyZWQoKSB7CisgICAgICByZXR1cm4gZmlsZUxvY2suaXNTaGFyZWQoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZWxlYXNlKCk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU2VtYXBob3JlTG9ja0ltcGwgaW1wbGVtZW50cyBMb2NrIHsKKworICAgIHByaXZhdGUgU2VtYXBob3JlIHNlbWFwaG9yZTsKKworICAgIFNlbWFwaG9yZUxvY2tJbXBsKFNlbWFwaG9yZSBzZW1hcGhvcmUpIHsKKyAgICAgIHRoaXMuc2VtYXBob3JlID0gc2VtYXBob3JlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJlbGVhc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgaWYgKHNlbWFwaG9yZSAhPSBudWxsKSB7CisgICAgICAgIHNlbWFwaG9yZS5yZWxlYXNlKCk7CisgICAgICAgIHNlbWFwaG9yZSA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGJvb2xlYW4gaXNWYWxpZCgpIHsKKyAgICAgIHJldHVybiBzZW1hcGhvcmUgIT0gbnVsbDsKKyAgICB9CisKKyAgICAvKiogU2VtYXBob3JlIGxvY2tzIGFyZSBhbHdheXMgZXhjbHVzaXZlLiAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBib29sZWFuIGlzU2hhcmVkKCkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHJlbGVhc2UoKTsKKyAgICB9CisgIH0KKworICAvLyBTZW1hcGhvcmVSZXNvdXJjZSBzaW1pbGFyIHRvIFJlbGVhc2VhYmxlUmVzb3VyY2UgdGhhdCBoYW5kbGVzIGJvdGggcmVsZWFzaW5nIGFuZCBpbXBsZW1lbnRpbmcKKyAgLy8gY2xvc2VhYmxlLgorICBwcml2YXRlIHN0YXRpYyBjbGFzcyBTZW1hcGhvcmVSZXNvdXJjZSBpbXBsZW1lbnRzIENsb3NlYWJsZSB7CisgICAgQE51bGxhYmxlIHByaXZhdGUgU2VtYXBob3JlIHNlbWFwaG9yZTsKKworICAgIHN0YXRpYyBTZW1hcGhvcmVSZXNvdXJjZSB0cnlBY3F1aXJlKFNlbWFwaG9yZSBzZW1hcGhvcmUpIHsKKyAgICAgIGJvb2xlYW4gYWNxdWlyZWQgPSBzZW1hcGhvcmUudHJ5QWNxdWlyZSgpOworICAgICAgcmV0dXJuIG5ldyBTZW1hcGhvcmVSZXNvdXJjZShhY3F1aXJlZCA/IHNlbWFwaG9yZSA6IG51bGwpOworICAgIH0KKworICAgIHN0YXRpYyBTZW1hcGhvcmVSZXNvdXJjZSBhY3F1aXJlKFNlbWFwaG9yZSBzZW1hcGhvcmUpIHRocm93cyBJbnRlcnJ1cHRlZElPRXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIHNlbWFwaG9yZS5hY3F1aXJlKCk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBleCkgeworICAgICAgICB0aHJvdyBuZXcgSW50ZXJydXB0ZWRJT0V4Y2VwdGlvbigic2VtYXBob3JlIG5vdCBhY3F1aXJlZDogIiArIGV4KTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBuZXcgU2VtYXBob3JlUmVzb3VyY2Uoc2VtYXBob3JlKTsKKyAgICB9CisKKyAgICBTZW1hcGhvcmVSZXNvdXJjZShATnVsbGFibGUgU2VtYXBob3JlIHNlbWFwaG9yZSkgeworICAgICAgdGhpcy5zZW1hcGhvcmUgPSBzZW1hcGhvcmU7CisgICAgfQorCisgICAgYm9vbGVhbiBhY3F1aXJlZCgpIHsKKyAgICAgIHJldHVybiAoc2VtYXBob3JlICE9IG51bGwpOworICAgIH0KKworICAgIFNlbWFwaG9yZSByZWxlYXNlRnJvbVRyeUJsb2NrKCkgeworICAgICAgU2VtYXBob3JlIHJlc3VsdCA9IHNlbWFwaG9yZTsKKyAgICAgIHNlbWFwaG9yZSA9IG51bGw7CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgeworICAgICAgaWYgKHNlbWFwaG9yZSAhPSBudWxsKSB7CisgICAgICAgIHNlbWFwaG9yZS5yZWxlYXNlKCk7CisgICAgICAgIHNlbWFwaG9yZSA9IG51bGw7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBTZW1hcGhvcmUgZ2V0T3JDcmVhdGVTZW1hcGhvcmUoU3RyaW5nIGtleSkgeworICAgIC8vIE5PVEU6IEVudHJpZXMgYWRkZWQgdG8gdGhpcyBsb2NrTWFwIGFyZSBuZXZlciByZW1vdmVkLiBJZiBhIGxhcmdlLCB2YXJ5aW5nIG51bWJlciBvZgorICAgIC8vIGZpbGVzIGFyZSBsb2NrZWQsIGFkZGluZyBhIG1lY2hhbmlzbSBkZWxldGUgb2Jzb2xldGUgZW50cmllcyBpbiB0aGUgdGFibGUgd291bGQgYmUgZGVzaXJhYmxlLgorICAgIC8vIFRoYXQgaXMgbm90IHRoZSBjYXNlIG5vdy4KKyAgICBTZW1hcGhvcmUgc2VtYXBob3JlID0gbG9ja01hcC5nZXQoa2V5KTsKKyAgICBpZiAoc2VtYXBob3JlID09IG51bGwpIHsKKyAgICAgIGxvY2tNYXAucHV0SWZBYnNlbnQoa2V5LCBuZXcgU2VtYXBob3JlKDEpKTsKKyAgICAgIHNlbWFwaG9yZSA9IGxvY2tNYXAuZ2V0KGtleSk7IC8vIFJlLWdldCgpIGluIGNhc2UgYW5vdGhlciB0aHJlYWQgcHV0SWZBYnNlbnQoKSBiZWZvcmUgdXMuCisgICAgfQorICAgIHJldHVybiBzZW1hcGhvcmU7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL01hbGZvcm1lZFVyaUV4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE3YzI4OWEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL01hbGZvcm1lZFVyaUV4Y2VwdGlvbi5qYXZhCkBAIC0wLDAgKzEsNDAgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBFeGNlcHRpb24gdGhyb3duIHRvIGluZGljYXRlIHRoYXQgYSBtYWxmb3JtZWQgVXJpIHdhcyBwYXNzZWQgYXMgYW4gYXJndW1lbnQuCisgKgorICogPHA+VGhpcyBjbGFzcyBvZiBleGNlcHRpb24gaXMgdXNlZCBvbmx5IGR1cmluZyBzdGF0aWMgVXJpIHBhcnNpbmcsIHN1Y2ggYXMgYSBVcmkgdGhhdCBkb2VzIG5vdAorICogY29uZm9ybSB0byBpdHMgc2NoZW1lIG9yIGEgZnJhZ21lbnQgdGhhdCBjb3VsZG4ndCBiZSBwYXJzZWQuIEl0IGlzIG5ldmVyIHVzZWQgdG8gaW5kaWNhdGUgYQorICogdHJhbnNpZW50IGZpbGVzeXN0ZW0gZmFpbHVyZSwgc3VjaCBhcyBjYWxsaW5nIGEgZmlsZSBvcGVyYXRpb24gb24gYSBkaXJlY3Rvcnkgb3IgdHJ5aW5nIHRvIGFjY2VzcworICogYW4gdW5hdmFpbGFibGUgc3RvcmFnZSBkZXZpY2UuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNYWxmb3JtZWRVcmlFeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisgIHB1YmxpYyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICBzdXBlcihtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSBjYXVzZSkgeworICAgIHN1cGVyKG1lc3NhZ2UsIGNhdXNlKTsKKyAgfQorCisgIHB1YmxpYyBNYWxmb3JtZWRVcmlFeGNlcHRpb24oVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgc3VwZXIoY2F1c2UpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL1BhcmFtQ29tcHV0ZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vUGFyYW1Db21wdXRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNjYWQ3ZDAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL1BhcmFtQ29tcHV0ZXIuamF2YQpAQCAtMCwwICsxLDM1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbjsKKworLyoqCisgKiBBIFBhcmFtQ29tcHV0ZXIgdXBkYXRlcyB0aGUgZnJhZ21lbnQgcGFyYW0gdmFsdWUgaW4gb3JkZXIgdG8gZW5jb2RlIHN0YXRlIGluIHRoZSBVUkkgZnJhZ21lbnQKKyAqIGJhc2VkIG9uIHRoZSBjb250ZW50IG9mIHRoZSBzdHJlYW0uIFRoZSBwcmltYXJ5IHVzZSBjYXNlIGZvciB0aGlzIGlzIGNoZWNrc3VtLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFBhcmFtQ29tcHV0ZXIgeworCisgIC8qKiBQYXJhbUNvbXB1dGVyIGNhbGxiYWNrLCB0byBiZSBpbnZva2VkIGV4YWN0bHkgb25jZSB3aGVuIHRoZSBjb21wdXRlZCBwYXJhbSB2YWx1ZSBpcyByZWFkeS4gKi8KKyAgaW50ZXJmYWNlIENhbGxiYWNrIHsKKyAgICB2b2lkIG9uUGFyYW1WYWx1ZUNvbXB1dGVkKEZyYWdtZW50LlBhcmFtVmFsdWUgdmFsdWUpOworICB9CisKKyAgLyoqCisgICAqIFNldHMgYSBjYWxsYmFjayB3aGljaCBpcyBpbnZva2VkIHdoZW4gdGhlIGNvbXB1dGVkIFVSSSBpcyBhdmFpbGFibGUgKGVnLCBlbmQgb2Ygc3RyZWFtKS4KKyAgICoKKyAgICogPHA+Tk9URTogTXVzdCBpbnZva2UgY2FsbGJhY2sgZXhhY3RseSBvbmNlLgorICAgKi8KKyAgdm9pZCBzZXRDYWxsYmFjayhDYWxsYmFjayBjYWxsYmFjayk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL1JlbGVhc2FibGVSZXNvdXJjZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9SZWxlYXNhYmxlUmVzb3VyY2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNWQyNjU3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9SZWxlYXNhYmxlUmVzb3VyY2UuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbjsKKworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5OdWxsYWJsZTsKKworLyoqCisgKiBBIHdyYXBwZXIgZm9yIGEgQ2xvc2VhYmxlIHJlc291cmNlIHRoYXQgYWxsb3dzIGNhbGxlciB0byBmcmVlIHRoYXQgcmVzb3VyY2UgZnJvbSBhCisgKiB0cnktd2l0aC1yZXNvdXJjZXMgYmxvY2suCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBSZWxlYXNhYmxlUmVzb3VyY2U8VCBleHRlbmRzIENsb3NlYWJsZT4gaW1wbGVtZW50cyBDbG9zZWFibGUgeworICBATnVsbGFibGUgcHJpdmF0ZSBUIHJlc291cmNlOworCisgIHByaXZhdGUgUmVsZWFzYWJsZVJlc291cmNlKFQgcmVzb3VyY2UpIHsKKyAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhIFJlbGVhc2FibGVSZXNvdXJjZSB3cmFwcGVkIGFyb3VuZCBhIHJlc291cmNlLgorICAgKgorICAgKiBAcGFyYW0gcmVzb3VyY2UgdGhlIENsb3NlYWJsZSByZXNvdXJjZS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgPFQgZXh0ZW5kcyBDbG9zZWFibGU+IFJlbGVhc2FibGVSZXNvdXJjZTxUPiBjcmVhdGUoVCByZXNvdXJjZSkgeworICAgIHJldHVybiBuZXcgUmVsZWFzYWJsZVJlc291cmNlPFQ+KHJlc291cmNlKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSB3cmFwcGVkIHJlc291cmNlIGFuZCByZWxlYXNlcyBvd25lcnNoaXAuIFRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIGVuc3VyaW5nIHRoZQorICAgKiByZXNvdXJjZSBpcyBjbG9zZWQuCisgICAqCisgICAqIEByZXR1cm4gdGhlIHdyYXBwZWQgcmVzb3VyY2UuCisgICAqLworICBATnVsbGFibGUKKyAgcHVibGljIFQgcmVsZWFzZSgpIHsKKyAgICBUIGZyZWVkID0gcmVzb3VyY2U7CisgICAgcmVzb3VyY2UgPSBudWxsOworICAgIHJldHVybiBmcmVlZDsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSB3cmFwcGVkIHJlc291cmNlIGJ1dCBkb2VzIG5vdCByZWxlYXNlIG93bmVyc2hpcC4KKyAgICoKKyAgICogQHJldHVybiB0aGUgd3JhcHBlZCByZXNvdXJjZS4KKyAgICovCisgIEBOdWxsYWJsZQorICBwdWJsaWMgVCBnZXQoKSB7CisgICAgcmV0dXJuIHJlc291cmNlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAocmVzb3VyY2UgIT0gbnVsbCkgeworICAgICAgcmVzb3VyY2UuY2xvc2UoKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vU2l6YWJsZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9TaXphYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDA5M2VkYwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vU2l6YWJsZS5qYXZhCkBAIC0wLDAgKzEsMzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uOworCitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworCisvKiogSW50ZXJmYWNlIGZvciBhY2Nlc3NpbmcgdGhlIHNpemUgb2YgYSBkYXRhIGJlaGluZCBhIHN0cmVhbS4gKi8KK3B1YmxpYyBpbnRlcmZhY2UgU2l6YWJsZSB7CisKKyAgLyoqCisgICAqIFJldHVybiB0aGUgbG9naWNhbCBzaXplIG9mIHRoZSBzdHJlYW0gb3IgbnVsbCBpZiBpdCBpcyB1bmtub3duLiBUaGUgbG9naWNhbCBzaXplIGlzIGRlZmluZWQgYXMKKyAgICogdGhlIHRvdGFsIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCB0byBzdG9yZSBhbGwgb2YgdGhlIGRhdGEgaW4gdGhlIHN0cmVhbSBhZnRlciBhcHBseWluZyB0aGUKKyAgICogdHJhbnNmb3JtLiBUaGlzIGlzIGV4cGVjdGVkIHRvIGJlIGFuIGVmZmljaWVudCBvcGVyYXRpb24uIEluIHBhcnRpY3VsYXIsIGlmIGl0IGlzIE8oZmlsZXNpemUpCisgICAqIHRvIGNvbXB1dGUgdGhlIGxvZ2ljYWwgc2l6ZSwgaW1wbGVtZW50b3Igc2hvdWxkIHJldHVybiBudWxsIHJhdGhlciB0aGFuIHBlcmZvcm0gdGhhdAorICAgKiBjYWxjdWxhdGlvbi4KKyAgICovCisgIEBOdWxsYWJsZQorICBMb25nIHNpemUoKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL1N5bmNhYmxlLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL1N5bmNhYmxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmRmNjAxZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vU3luY2FibGUuamF2YQpAQCAtMCwwICsxLDIzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKiBJbnRlcmZhY2UgZmx1c2hpbmcgT1MgYnVmZmVycyBpbiBvcmRlciB0byBlbnN1cmUgZGF0YSBpcyB3cml0dGVuIHRvIHBlcnNpc3RlbnQgc3RvcmFnZS4gKi8KK3B1YmxpYyBpbnRlcmZhY2UgU3luY2FibGUgeworICB2b2lkIHN5bmMoKSB0aHJvd3MgSU9FeGNlcHRpb247Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL1Vuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24uamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmNTkyYTIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL1Vuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24uamF2YQpAQCAtMCwwICsxLDMzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbjsKKworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKiBUaGUgb3BlcmF0aW9uIGlzIHVuc3VwcG9ydGVkIGJ5IHRoZSBiYWNrZW5kIG9yIGF0IGxlYXN0IG9uZSB0cmFuc2Zvcm0gc3BlY2lmaWVkIGluIHRoZSBVUkkuICovCitwdWJsaWMgZmluYWwgY2xhc3MgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKKyAgcHVibGljIFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oU3RyaW5nIG1lc3NhZ2UpIHsKKyAgICBzdXBlcihtZXNzYWdlKTsKKyAgfQorCisgIHB1YmxpYyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICBzdXBlcihtZXNzYWdlLCBjYXVzZSk7CisgIH0KKworICBwdWJsaWMgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbihUaHJvd2FibGUgY2F1c2UpIHsKKyAgICBzdXBlcihjYXVzZSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBmZmQ0MDAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0JVSUxECkBAIC0wLDAgKzEsNzkgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJjaGFyc2V0cyIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkNoYXJzZXRzLmphdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImV4Y2VwdGlvbnMiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJFeGNlcHRpb25zLmphdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gInByZWNvbmRpdGlvbnMiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJQcmVjb25kaXRpb25zLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJmb3J3YXJkaW5nX3N0cmVhbSIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkZvcndhcmRpbmdJbnB1dFN0cmVhbS5qYXZhIiwKKyAgICAgICAgIkZvcndhcmRpbmdPdXRwdXRTdHJlYW0uamF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiYmFja2VuZF9zdHJlYW0iLAorICAgIHNyY3MgPSBbCisgICAgICAgICJCYWNrZW5kSW5wdXRTdHJlYW0uamF2YSIsCisgICAgICAgICJCYWNrZW5kT3V0cHV0U3RyZWFtLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpmb3J3YXJkaW5nX3N0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImxhenlfc3RyZWFtIiwKKyAgICBzcmNzID0gWworICAgICAgICAiTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtLmphdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImxpdGVfdHJhbnNmb3JtX2ZyYWdtZW50cyIsCisgICAgc3JjcyA9IFsiTGl0ZVRyYW5zZm9ybUZyYWdtZW50cy5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9CYWNrZW5kSW5wdXRTdHJlYW0uamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvQmFja2VuZElucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTZhNDhhZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvQmFja2VuZElucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw1NyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWw7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5GaWxlQ2hhbm5lbENvbnZlcnRpYmxlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkZpbGVDb252ZXJ0aWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5TaXphYmxlOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworCisvKiogQSBGaWxlLWJhc2VkIElucHV0U3RyZWFtIHRoYXQgaW1wbGVtZW50cyBhbGwgb3B0aW9uYWwgQmFja2VuZCBiZWhhdmlvcnMuICovCitwdWJsaWMgZmluYWwgY2xhc3MgQmFja2VuZElucHV0U3RyZWFtIGV4dGVuZHMgRm9yd2FyZGluZ0lucHV0U3RyZWFtCisgICAgaW1wbGVtZW50cyBGaWxlQ29udmVydGlibGUsIEZpbGVDaGFubmVsQ29udmVydGlibGUsIFNpemFibGUgeworICBwcml2YXRlIGZpbmFsIEZpbGVJbnB1dFN0cmVhbSBmaWxlSW5wdXRTdHJlYW07CisgIHByaXZhdGUgZmluYWwgRmlsZSBmaWxlOworCisgIHB1YmxpYyBzdGF0aWMgQmFja2VuZElucHV0U3RyZWFtIGNyZWF0ZShGaWxlIGZpbGUpIHRocm93cyBGaWxlTm90Rm91bmRFeGNlcHRpb24geworICAgIHJldHVybiBuZXcgQmFja2VuZElucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSksIGZpbGUpOworICB9CisKKyAgcHJpdmF0ZSBCYWNrZW5kSW5wdXRTdHJlYW0oRmlsZUlucHV0U3RyZWFtIGZpbGVJbnB1dFN0cmVhbSwgRmlsZSBmaWxlKSB7CisgICAgc3VwZXIoZmlsZUlucHV0U3RyZWFtKTsKKyAgICB0aGlzLmZpbGVJbnB1dFN0cmVhbSA9IGZpbGVJbnB1dFN0cmVhbTsKKyAgICB0aGlzLmZpbGUgPSBmaWxlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBGaWxlIHRvRmlsZSgpIHsKKyAgICByZXR1cm4gZmlsZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgRmlsZUNoYW5uZWwgdG9GaWxlQ2hhbm5lbCgpIHsKKyAgICByZXR1cm4gZmlsZUlucHV0U3RyZWFtLmdldENoYW5uZWwoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTG9uZyBzaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZmlsZUlucHV0U3RyZWFtLmdldENoYW5uZWwoKS5zaXplKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvQmFja2VuZE91dHB1dFN0cmVhbS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9CYWNrZW5kT3V0cHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODg0YTdiYwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvQmFja2VuZE91dHB1dFN0cmVhbS5qYXZhCkBAIC0wLDAgKzEsNjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uRmlsZUNoYW5uZWxDb252ZXJ0aWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5GaWxlQ29udmVydGlibGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uU3luY2FibGU7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworCisvKiogQSBGaWxlLWJhc2VkIE91dHB1dFN0cmVhbSB0aGF0IGltcGxlbWVudHMgYWxsIG9wdGlvbmFsIEJhY2tlbmQgYmVoYXZpb3JzLiAqLworcHVibGljIGNsYXNzIEJhY2tlbmRPdXRwdXRTdHJlYW0gZXh0ZW5kcyBGb3J3YXJkaW5nT3V0cHV0U3RyZWFtCisgICAgaW1wbGVtZW50cyBGaWxlQ29udmVydGlibGUsIEZpbGVDaGFubmVsQ29udmVydGlibGUsIFN5bmNhYmxlIHsKKyAgcHJpdmF0ZSBmaW5hbCBGaWxlT3V0cHV0U3RyZWFtIGZpbGVPdXRwdXRTdHJlYW07CisgIHByaXZhdGUgZmluYWwgRmlsZSBmaWxlOworCisgIHB1YmxpYyBzdGF0aWMgQmFja2VuZE91dHB1dFN0cmVhbSBjcmVhdGVGb3JXcml0ZShGaWxlIGZpbGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ldyBCYWNrZW5kT3V0cHV0U3RyZWFtKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGUpLCBmaWxlKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgQmFja2VuZE91dHB1dFN0cmVhbSBjcmVhdGVGb3JBcHBlbmQoRmlsZSBmaWxlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBuZXcgQmFja2VuZE91dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlLCB0cnVlIC8qIGFwcGVuZCAqLyksIGZpbGUpOworICB9CisKKyAgLyoqIE5PVEU6IHRoaXMgY29uc3RydWN0b3IgaXMgcHVibGljIG9ubHkgaW4gb3JkZXIgdG8gYWxsb3cgc3ViY2xhc3NpbmcuICovCisgIHB1YmxpYyBCYWNrZW5kT3V0cHV0U3RyZWFtKEZpbGVPdXRwdXRTdHJlYW0gZmlsZU91dHB1dFN0cmVhbSwgRmlsZSBmaWxlKSB7CisgICAgc3VwZXIoZmlsZU91dHB1dFN0cmVhbSk7CisgICAgdGhpcy5maWxlT3V0cHV0U3RyZWFtID0gZmlsZU91dHB1dFN0cmVhbTsKKyAgICB0aGlzLmZpbGUgPSBmaWxlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBGaWxlIHRvRmlsZSgpIHsKKyAgICByZXR1cm4gZmlsZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgRmlsZUNoYW5uZWwgdG9GaWxlQ2hhbm5lbCgpIHsKKyAgICByZXR1cm4gZmlsZU91dHB1dFN0cmVhbS5nZXRDaGFubmVsKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgc3luYygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZmlsZU91dHB1dFN0cmVhbS5nZXRGRCgpLnN5bmMoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9DaGFyc2V0cy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9DaGFyc2V0cy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0YmY2NmMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0NoYXJzZXRzLmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWw7CisKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CisKKy8qKgorICogQ29udGFpbnMgY29uc3RhbnQgZGVmaW5pdGlvbnMgZm9yIHRoZSBzdGFuZGFyZCB7QGxpbmsgQ2hhcnNldH0gaW5zdGFuY2VzLCB3aGljaCBhcmUgZ3VhcmFudGVlZCB0bworICogYmUgc3VwcG9ydGVkIGJ5IGFsbCBKYXZhIHBsYXRmb3JtIGltcGxlbWVudGF0aW9ucy4KKyAqCisgKiA8cD5UaGlzIGlzIGludGVuZGVkIHRvIGJlIHVzZWQgaW4gbGlldSBvZiB7QGxpbmsgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzfSwgd2hpY2ggd2FzCisgKiBhZGRlZCBpbiBBUEkgbGV2ZWwgMTkgYW5kIHRodXMgZG9lcyBub3Qgc3VwcG9ydCBKZWxseWJlYW4gZGV2aWNlcy4gSXQgaXMgYSB0cmltbWVkLWRvd24gZm9yayBvZgorICogdGhlIENoYXJzZXRzIGNsYXNzIHVuZGVyIEd1YXZhLCByZXBsaWNhdGVkIGhlcmUgdG8gYXZvaWQgdGhlIGhlYXZ5IGRlcGVuZGVuY3kuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBDaGFyc2V0cyB7CisKKyAgLyoqIFVTLUFTQ0lJOiBzZXZlbi1iaXQgQVNDSUksIHRoZSBCYXNpYyBMYXRpbiBibG9jayBvZiB0aGUgVW5pY29kZSBjaGFyYWN0ZXIgc2V0IChJU082NDYtVVMpLiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIENoYXJzZXQgVVNfQVNDSUkgPSBDaGFyc2V0LmZvck5hbWUoIlVTLUFTQ0lJIik7CisKKyAgLyoqIElTTyBMYXRpbiBBbHBoYWJldCBOby4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBDaGFyc2V0IElTT184ODU5XzEgPSBDaGFyc2V0LmZvck5hbWUoIklTTy04ODU5LTEiKTsKKworICAvKiogVVRGLTg6IGVpZ2h0LWJpdCBVQ1MgVHJhbnNmb3JtYXRpb24gRm9ybWF0LiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIENoYXJzZXQgVVRGXzggPSBDaGFyc2V0LmZvck5hbWUoIlVURi04Iik7CisKKyAgcHJpdmF0ZSBDaGFyc2V0cygpIHt9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0V4Y2VwdGlvbnMuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvRXhjZXB0aW9ucy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEwYzI5NTQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0V4Y2VwdGlvbnMuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbDsKKworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQ7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworCisvKiogU3RhdGljIGhlbHBlcnMgZm9yIGNvbW1vbmx5LXVzZWQgb3BlcmF0aW9ucyBvbiB7QGxpbmsgRXhjZXB0aW9ufSBjbGFzc2VzLiAqLworcHVibGljIGZpbmFsIGNsYXNzIEV4Y2VwdGlvbnMgeworCisgIC8qKgorICAgKiBDb21iaW5lcyBtdWx0aXBsZSB7QGNvZGUgY2F1c2VzfSBpbnRvIGEgc2luZ2xlIG5ldyB7QGxpbmsgSU9FeGNlcHRpb259LiBDYXVzZXMgYXJlIGF0dGFjaGVkIHRvCisgICAqIHRoZSBuZXcgZXhjZXB0aW9uIGFzIHtAY29kZSBzdXBwcmVzc2VkfSwgb3IgaWYgdW5zdXBwb3J0ZWQgKFNESyA8MTkpLCB0aGUgbmV3IGV4Y2VwdGlvbiBtZXNzYWdlCisgICAqIHNpbXBseSBpbmNsdWRlcyB0aGUgbnVtYmVyIG9mIGNhdXNlcy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSU9FeGNlcHRpb24gY29tYmluZWRJT0V4Y2VwdGlvbihTdHJpbmcgbWVzc2FnZSwgTGlzdDxJT0V4Y2VwdGlvbj4gY2F1c2VzKSB7CisgICAgLy8gYWRkU3VwcHJlc3NlZCBpcyBhdmFpbGFibGUgb24gU0RLIDE5Ky4KKyAgICBpZiAoQnVpbGQuVkVSU0lPTi5TREtfSU5UIDwgMTkpIHsKKyAgICAgIFN0cmluZyBzdXBwcmVzc2VkQ291bnQgPQorICAgICAgICAgIFN0cmluZy5mb3JtYXQoTG9jYWxlLlVTLCAiICglZCBzdXBwcmVzc2VkIGV4Y2VwdGlvbnMpIiwgY2F1c2VzLnNpemUoKSk7CisgICAgICByZXR1cm4gbmV3IElPRXhjZXB0aW9uKG1lc3NhZ2UgKyBzdXBwcmVzc2VkQ291bnQpOworICAgIH0KKworICAgIElPRXhjZXB0aW9uIHJlc3VsdCA9IG5ldyBJT0V4Y2VwdGlvbihtZXNzYWdlKTsKKyAgICBmb3IgKElPRXhjZXB0aW9uIGNhdXNlIDogY2F1c2VzKSB7CisgICAgICByZXN1bHQuYWRkU3VwcHJlc3NlZChjYXVzZSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICBwcml2YXRlIEV4Y2VwdGlvbnMoKSB7fQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9Gb3J3YXJkaW5nSW5wdXRTdHJlYW0uamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvRm9yd2FyZGluZ0lucHV0U3RyZWFtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTk1YmRiMAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvRm9yd2FyZGluZ0lucHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSwzNyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWw7CisKK2ltcG9ydCBqYXZhLmlvLkZpbHRlcklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiBSZW1vdmVzIGlkaW9zeW5jcmFjeSBvZiBGaWx0ZXJJbnB1dFN0cmVhbSwgd2hpY2ggZG9lcyBub3QgYWx3YXlzIGZvcndhcmQgdG8gZGVsZWdhdGUgZGlyZWN0bHkuCisgKgorICogPHA+VGhpcyBjbGFzcywgYW5kIG5vdCBGaWx0ZXJJbnB1dFN0cmVhbSwgbXVzdCBiZSB1c2VkIGZvciBhbGwgTW9iU3RvcmUgY29kZS4KKyAqLworcHVibGljIGNsYXNzIEZvcndhcmRpbmdJbnB1dFN0cmVhbSBleHRlbmRzIEZpbHRlcklucHV0U3RyZWFtIHsKKworICBwdWJsaWMgRm9yd2FyZGluZ0lucHV0U3RyZWFtKElucHV0U3RyZWFtIGluKSB7CisgICAgc3VwZXIoaW4pOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gaW4ucmVhZChiKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9Gb3J3YXJkaW5nT3V0cHV0U3RyZWFtLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0ZvcndhcmRpbmdPdXRwdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZWMzM2ExCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9Gb3J3YXJkaW5nT3V0cHV0U3RyZWFtLmphdmEKQEAgLTAsMCArMSw0MyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWw7CisKK2ltcG9ydCBqYXZhLmlvLkZpbHRlck91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCisvKioKKyAqIFJlbW92ZXMgc29tZSBpZGlvc3luY3JhY2llcyBvZiBGaWx0ZXJPdXRwdXRTdHJlYW0uIEl0IGFsd2F5cyBkZWxlZ2F0ZXMgZGlyZWN0bHksIGFuZCBhdm9pZHMKKyAqIGJ5dGUtYnktYnl0ZSBpbXBsZW1lbnRhdGlvbiBvZiB3cml0ZS4KKyAqCisgKiA8cD5UaGlzIGNsYXNzLCBhbmQgbm90IEZpbHRlck91dHB1dFN0cmVhbSwgbXVzdCBiZSB1c2VkIGZvciBhbGwgTW9iU3RvcmUgY29kZS4KKyAqLworcHVibGljIGNsYXNzIEZvcndhcmRpbmdPdXRwdXRTdHJlYW0gZXh0ZW5kcyBGaWx0ZXJPdXRwdXRTdHJlYW0geworCisgIHB1YmxpYyBGb3J3YXJkaW5nT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBvdXQpIHsKKyAgICBzdXBlcihvdXQpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIG91dC53cml0ZShiKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBvdXQud3JpdGUoYiwgb2ZmLCBsZW4pOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0xhenlCeXRlQXJyYXlJbnB1dFN0cmVhbS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9MYXp5Qnl0ZUFycmF5SW5wdXRTdHJlYW0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZTkyMzVkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9MYXp5Qnl0ZUFycmF5SW5wdXRTdHJlYW0uamF2YQpAQCAtMCwwICsxLDEzMCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWw7CisKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5DYWxsYWJsZTsKKworLyoqCisgKiBBbiB7QGNvZGUgSW5wdXRTdHJlYW19IHRoYXQgd3JhcHMgYSBieXRlIGFycmF5IHByb3ZpZGVkIGxhemlseS4gVGhpcyBjYW4gYmUgaGVscGZ1bCBmb3IgYWRhcHRpbmcKKyAqIGFuIGFsbC1hdC1vbmNlIGJ5dGUtcHJvY2Vzc2luZyBBUEkgdG8gYSBzdHJlYW1pbmcgcGFyYWRpZ20uIFNhbXBsZSB1c2FnZToKKyAqCisgKiA8cHJlPntAY29kZQorICogSW5wdXRTdHJlYW0gc291cmNlID0gLi4uOworICogSW5wdXRTdHJlYW0gbGF6eSA9CisgKiAgICAgbmV3IExhenlCeXRlQXJyYXlJbnB1dFN0cmVhbSgKKyAqICAgICAgICAgKCkgLT4geworICogICAgICAgICAgIHRyeSB7CisgKiAgICAgICAgICAgICBieXRlW10gYnl0ZXMgPSBCeXRlU3RyZWFtcy50b0J5dGVBcnJheShzb3VyY2UpOworICogICAgICAgICAgICAgcmV0dXJuIG15Qnl0ZUZ1bmN0aW9uKGJ5dGVzKTsKKyAqICAgICAgICAgICB9IGZpbmFsbHkgeworICogICAgICAgICAgICAgc291cmNlLmNsb3NlKCk7CisgKiAgICAgICAgICAgfQorICogICAgICAgICB9KTsKKyAqIC8vIHNvdXJjZSBzdHJlYW0gaXMgbmVpdGhlciByZWFkIG5vciBwcm9jZXNzZWQgdW50aWwgbGF6eS5yZWFkKCkKKyAqIH08L3ByZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIExhenlCeXRlQXJyYXlJbnB1dFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIHsKKworICBwcml2YXRlIGZpbmFsIENhbGxhYmxlPGJ5dGVbXT4gYnl0ZVByb3ZpZGVyOworCisgIC8vIExhemlseSBpbml0aWFsaXplZCBieSBpbml0KCkKKyAgcHJpdmF0ZSB2b2xhdGlsZSBib29sZWFuIGlzSW5pdGlhbGl6ZWQgPSBmYWxzZTsKKyAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBkZWxlZ2F0ZTsKKworICAvKioKKyAgICogQ29uc3RydWN0cyBhIG5ldyBpbnN0YW5jZSB0aGF0IHdpbGwgbGF6aWx5IGNhbGwgdXBvbiB7QGNvZGUgYnl0ZVByb3ZpZGVyfSBvbmNlIGJ5dGVzIGFyZQorICAgKiByZXF1ZXN0ZWQuIFRoZSBwcm92aWRlciB3aWxsIGJlIGNhbGxlZCBhdCBtb3N0IG9uY2U7IGlmIGl0IHRocm93cyBleGNlcHRpb24sIHRoZSB7QGNvZGUKKyAgICogTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtfSB3aWxsIGJlIGxlZnQgaW4gYW4gaW5vcGVyYWJsZSBzdGF0ZS4KKyAgICoKKyAgICogPHA+VGhlIGNhbGxlciBNVVNUIHJlYWQgb3IgY2xvc2UgdGhlIHN0cmVhbSBpbiBvcmRlciB0byBhdm9pZCBhIHBvc3NpYmxlIHJlc291cmNlIGxlYWsgaW4gdGhlCisgICAqIGJ5dGUgcHJvdmlkZXIuCisgICAqLworICBwdWJsaWMgTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtKENhbGxhYmxlPGJ5dGVbXT4gYnl0ZVByb3ZpZGVyKSB7CisgICAgdGhpcy5ieXRlUHJvdmlkZXIgPSBieXRlUHJvdmlkZXI7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBhdmFpbGFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmICghaXNJbml0aWFsaXplZCkgeworICAgICAgcmV0dXJuIDA7IC8vIGF2YWlsYWJsZSgpIHJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IGNhbiBiZSByZWFkIHdpdGhvdXQgYmxvY2tpbmcKKyAgICB9CisgICAgcmV0dXJuIGRlbGVnYXRlLmF2YWlsYWJsZSgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbml0KCk7IC8vIGdpdmUgdGhlIHVuZGVybHlpbmcgYnl0ZSBzb3VyY2UgYW4gb3Bwb3J0dW5pdHkgdG8gY2xvc2UgYW55IG9wZW4gcmVzb3VyY2VzCisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbml0KCk7CisgICAgcmV0dXJuIGRlbGVnYXRlLnJlYWQoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaW5pdCgpOworICAgIHJldHVybiBkZWxlZ2F0ZS5yZWFkKGIpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbml0KCk7CisgICAgcmV0dXJuIGRlbGVnYXRlLnJlYWQoYiwgb2ZmLCBsZW4pOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBsb25nIHNraXAobG9uZyBuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGluaXQoKTsKKyAgICByZXR1cm4gZGVsZWdhdGUuc2tpcChuKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBtYXJrKGludCByZWFkbGltaXQpIHsKKyAgICBpZiAoIWlzSW5pdGlhbGl6ZWQpIHsKKyAgICAgIHJldHVybjsgLy8gc3RyZWFtIGhhc24ndCBiZWVuIHJlYWQsIHRodXMgaXRzIHBvc2l0aW9uIGlzIDAsIHRodXMgbm90aGluZyB0byBtYXJrCisgICAgfQorICAgIGRlbGVnYXRlLm1hcmsocmVhZGxpbWl0KTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBtYXJrU3VwcG9ydGVkKCkgeworICAgIHJldHVybiB0cnVlOyAvLyB0aGUgbWFya1N1cHBvcnRlZCBtZXRob2Qgb2YgQnl0ZUFycmF5SW5wdXRTdHJlYW0gYWx3YXlzIHJldHVybnMgdHJ1ZQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHJlc2V0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpbml0KCk7CisgICAgZGVsZWdhdGUucmVzZXQoKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBpbml0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoIWlzSW5pdGlhbGl6ZWQpIHsKKyAgICAgIGlzSW5pdGlhbGl6ZWQgPSB0cnVlOyAvLyBkb24ndCB0cnkgYWdhaW4gaWYgcHJvdmlkZXIgZmFpbHMKKyAgICAgIHRyeSB7CisgICAgICAgIGRlbGVnYXRlID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVQcm92aWRlci5jYWxsKCkpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBlOworICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUpOworICAgICAgfQorICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9MaXRlVHJhbnNmb3JtRnJhZ21lbnRzLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0xpdGVUcmFuc2Zvcm1GcmFnbWVudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YmExZjcyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9MaXRlVHJhbnNmb3JtRnJhZ21lbnRzLmphdmEKQEAgLTAsMCArMSwxMTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudGV4dC5UZXh0VXRpbHM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5Kb2luZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5TcGxpdHRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4Lk1hdGNoZXI7CitpbXBvcnQgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm47CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5OdWxsYWJsZTsKKworLyoqCisgKiBUaGUgZnJhZ21lbnQgcGFyc2VyLCB1bmZvcnR1bmF0ZWx5LCBpcyByYXRoZXIgbGFyZ2UgaW4gY29kZSBzaXplLiBUaGlzIGNsYXNzIHByb3ZpZGVzIHNvbWUKKyAqIGxpZ2h0ZXIgdXRpbGl0aWVzIGZvciBhY2Nlc3NpbmcgYW5kIG1hbmlwdWxhdGluZyB0aGUgdHJhbnNmb3JtIGZyYWdtZW50IHBhcmFtLiBJdCBwcm92aWRlcyBhCisgKiBzdHJpY3Qgc3Vic2V0IG9mIHRoZSBmdW5jdGlvbmFsaXR5IGluIHtAbGluayBGcmFnbWVudH0uCisgKgorICogPHA+SW4gcGFydGljdWxhciwgaXQgZG9lcyBub3Qgc3VwcG9ydAorICoKKyAqIDx1bD4KKyAqICAgPGxpPkVuY29kZWQgdHJhbnNmb3JtIG5hbWVzLgorICogICA8bGk+UGFyc2luZyB0cmFuc2Zvcm0gcGFyYW1zLgorICogPC91bD4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIExpdGVUcmFuc2Zvcm1GcmFnbWVudHMgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFBhdHRlcm4gWEZPUk1fTkFNRV9QQVRURVJOID0gUGF0dGVybi5jb21waWxlKCIoXFx3KykuKiIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWEZPUk1fRlJBR01FTlRfUFJFRklYID0gInRyYW5zZm9ybT0iOworCisgIC8qKgorICAgKiBQYXJzZXMgVVJJIGZyYWdtZW50LCByZXR1cm5pbmcgdGhlIG5hbWVzIG9mIHRoZSB0cmFuc2Zvcm1zIHRoYXQgYXJlIGVuYWJsZWQuIEhhcyB0aGUgZm9sbG93aW5nCisgICAqIGxpbWl0YXRpb25zOgorICAgKgorICAgKiA8dWw+CisgICAqICAgPGxpPklnbm9yZXMgc3VicGFyYW1zLiBUbyBhY2Nlc3MgdGhvc2UsIHVzZSB7QGxpbmsgRnJhZ21lbnR9IGZyb20geW91ciB0cmFuc2Zvcm0uCisgICAqICAgPGxpPlJlcXVpcmVzIHRoZSBmcmFnbWVudCBzdGFydCB3aXRoICJ0cmFuc2Zvcm09Ii4KKyAgICogICA8bGk+UmVxdWlyZXMgZW5jb2RlZCB0cmFuc2Zvcm0gbmFtZSB0byBjb250YWluIG9ubHkgd29yZCBjaGFycyAoaWUsIFx3KS4KKyAgICogPC91bD4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSW1tdXRhYmxlTGlzdDxTdHJpbmc+IHBhcnNlVHJhbnNmb3JtTmFtZXMoVXJpIHVyaSkgeworICAgIEltbXV0YWJsZUxpc3QuQnVpbGRlcjxTdHJpbmc+IGJ1aWxkZXIgPSBJbW11dGFibGVMaXN0LmJ1aWxkZXIoKTsKKyAgICBmb3IgKFN0cmluZyBzcGVjIDogcGFyc2VUcmFuc2Zvcm1TcGVjcyh1cmkpKSB7CisgICAgICBidWlsZGVyLmFkZChwYXJzZVNwZWNOYW1lKHNwZWMpKTsKKyAgICB9CisgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBQYXJzZXMgVVJJIGZyYWdtZW50LCByZXR1cm5pbmcgdGhlIHRyYW5zZm9ybXMgc3BlY3MgZm91bmQuIEhhcyB0aGUgZm9sbG93aW5nIGxpbWl0YXRpb25zOgorICAgKgorICAgKiA8dWw+CisgICAqICAgPGxpPlJlcXVpcmVzIHRoZSBmcmFnbWVudCBzdGFydCB3aXRoICJ0cmFuc2Zvcm09Ii4KKyAgICogPC91bD4KKyAgICoKKyAgICogQHJldHVybiBMaXN0IG9mIGVuY29kZWQgdHJhbnNmb3JtIHNwZWNzIC0gZWcgImludGVncml0eShzaGEyNTY9YWJjMTIzKSIKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgSW1tdXRhYmxlTGlzdDxTdHJpbmc+IHBhcnNlVHJhbnNmb3JtU3BlY3MoVXJpIHVyaSkgeworICAgIFN0cmluZyBmcmFnbWVudCA9IHVyaS5nZXRFbmNvZGVkRnJhZ21lbnQoKTsKKyAgICBpZiAoVGV4dFV0aWxzLmlzRW1wdHkoZnJhZ21lbnQpIHx8ICFmcmFnbWVudC5zdGFydHNXaXRoKFhGT1JNX0ZSQUdNRU5UX1BSRUZJWCkpIHsKKyAgICAgIHJldHVybiBJbW11dGFibGVMaXN0Lm9mKCk7CisgICAgfQorICAgIFN0cmluZyBzcGVjcyA9IGZyYWdtZW50LnN1YnN0cmluZyhYRk9STV9GUkFHTUVOVF9QUkVGSVgubGVuZ3RoKCkpOworICAgIHJldHVybiBJbW11dGFibGVMaXN0LmNvcHlPZihTcGxpdHRlci5vbigiKyIpLm9taXRFbXB0eVN0cmluZ3MoKS5zcGxpdChzcGVjcykpOworICB9CisKKyAgLyoqCisgICAqIFBhcnNlIHRoZSBuYW1lIGZyb20gYW4gZW5jb2RlZCB0cmFuc2Zvcm0gc3BlYy4gRm9yIGV4YW1wbGUsICJpbnRlZ3JpdHkoc2hhMjU2PWFiYzEyMykiIHdvdWxkCisgICAqIHJldHVybiAiaW50ZWdyaXR5Ii4gSGFzIHRoZSBmb2xsb3dpbmcgbGltaXRhdGlvbnM6CisgICAqCisgICAqIDx1bD4KKyAgICogICA8bGk+SWdub3JlcyBzdWJwYXJhbXMuIFRvIGFjY2VzcyB0aG9zZSwgdXNlIHtAbGluayBGcmFnbWVudH0gZnJvbSB5b3VyIHRyYW5zZm9ybS4KKyAgICogICA8bGk+UmVxdWlyZXMgZW5jb2RlZCB0cmFuc2Zvcm0gbmFtZSB0byBjb250YWluIG9ubHkgd29yZCBjaGFycyAoaWUsIFx3KS4KKyAgICogPC91bD4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHBhcnNlU3BlY05hbWUoU3RyaW5nIGVuY29kZWRTcGVjKSB7CisgICAgTWF0Y2hlciBtYXRjaGVyID0gWEZPUk1fTkFNRV9QQVRURVJOLm1hdGNoZXIoZW5jb2RlZFNwZWMpOworICAgIGlmICghbWF0Y2hlci5tYXRjaGVzKCkpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkludmFsaWQgZnJhZ21lbnQgc3BlYzogIiArIGVuY29kZWRTcGVjKTsKKyAgICB9CisgICAgcmV0dXJuIG1hdGNoZXIuZ3JvdXAoMSk7CisgIH0KKworICAvKioKKyAgICogSm9pbnMgdGhlIGVuY29kZWQgdHJhbnNmb3JtIHNwZWNzIHRvIHByb2R1Y2UgYW4gZW5jb2RlZCB0cmFuc2Zvcm0gZnJhZ21lbnQgc3VpdGFibGUgZm9yIGFkZGluZworICAgKiB0byBhIFVyaSB3aXRoIHtAbGluayBVcmkuQnVpbGRlciNlbmNvZGVkRnJhZ21lbnR9LgorICAgKi8KKyAgQE51bGxhYmxlCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGpvaW5UcmFuc2Zvcm1TcGVjcyhMaXN0PFN0cmluZz4gZW5jb2RlZFNwZWNzKSB7CisgICAgaWYgKGVuY29kZWRTcGVjcy5pc0VtcHR5KCkpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICByZXR1cm4gWEZPUk1fRlJBR01FTlRfUFJFRklYICsgSm9pbmVyLm9uKCIrIikuam9pbihlbmNvZGVkU3BlY3MpOworICB9CisKKyAgcHJpdmF0ZSBMaXRlVHJhbnNmb3JtRnJhZ21lbnRzKCkge30KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvUHJlY29uZGl0aW9ucy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9QcmVjb25kaXRpb25zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2VhNjVlYgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvUHJlY29uZGl0aW9ucy5qYXZhCkBAIC0wLDAgKzEsNzggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsOworCitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5OdWxsYWJsZTsKKworLyoqCisgKiBTdGF0aWMgY29udmVuaWVuY2UgbWV0aG9kcyB0aGF0IGhlbHAgYSBtZXRob2QgY2hlY2sgd2hldGhlciBpdCB3YXMgaW52b2tlZCBjb3JyZWN0bHkuCisgKgorICogPHA+VGhpcyBpcyBhIHRyaW1tZWQgZG93biB2ZXJzaW9uIG9mIHRoZSBQcmVjb25kaXRpb25zIGNsYXNzIHVuZGVyIEd1YXZhLCByZXBsaWNhdGVkIGhlcmUgdG8KKyAqIGF2b2lkIHRoZSBoZWF2eSBkZXBlbmRlbmN5LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUHJlY29uZGl0aW9ucyB7CisKKyAgLyoqCisgICAqIEVuc3VyZXMgdGhlIHRydXRoIG9mIGFuIGV4cHJlc3Npb24gaW52b2x2aW5nIG9uZSBvciBtb3JlIHBhcmFtZXRlcnMgdG8gdGhlIGNhbGxpbmcgbWV0aG9kLgorICAgKgorICAgKiBAcGFyYW0gZXhwcmVzc2lvbiBhIGJvb2xlYW4gZXhwcmVzc2lvbgorICAgKiBAcGFyYW0gZXJyb3JNZXNzYWdlVGVtcGxhdGUgYSB0ZW1wbGF0ZSBmb3IgdGhlIGV4Y2VwdGlvbiBtZXNzYWdlIHNob3VsZCB0aGUgY2hlY2sgZmFpbC4gVGhlCisgICAqICAgICBtZXNzYWdlIGlzIGZvcm1lZCBieSByZXBsYWNpbmcgZWFjaCB7QGNvZGUgJXN9IHBsYWNlaG9sZGVyIGluIHRoZSB0ZW1wbGF0ZSB3aXRoIGFuCisgICAqICAgICBhcmd1bWVudC4gVGhlc2UgYXJlIG1hdGNoZWQgYnkgcG9zaXRpb24gLSB0aGUgZmlyc3Qge0Bjb2RlICVzfSBnZXRzIHtAY29kZQorICAgKiAgICAgZXJyb3JNZXNzYWdlQXJnc1swXX0sIGV0Yy4KKyAgICogQHBhcmFtIGVycm9yTWVzc2FnZUFyZ3MgdGhlIGFyZ3VtZW50cyB0byBiZSBzdWJzdGl0dXRlZCBpbnRvIHRoZSBtZXNzYWdlIHRlbXBsYXRlLiBBcmd1bWVudHMKKyAgICogICAgIGFyZSBjb252ZXJ0ZWQgdG8gc3RyaW5ncyB1c2luZyB7QGxpbmsgU3RyaW5nI3ZhbHVlT2YoT2JqZWN0KX0uCisgICAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHtAY29kZSBleHByZXNzaW9ufSBpcyBmYWxzZQorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGNoZWNrQXJndW1lbnQoCisgICAgICBib29sZWFuIGV4cHJlc3Npb24sCisgICAgICBATnVsbGFibGUgU3RyaW5nIGVycm9yTWVzc2FnZVRlbXBsYXRlLAorICAgICAgQE51bGxhYmxlIE9iamVjdC4uLiBlcnJvck1lc3NhZ2VBcmdzKSB7CisgICAgaWYgKCFleHByZXNzaW9uKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGZvcm1hdChlcnJvck1lc3NhZ2VUZW1wbGF0ZSwgZXJyb3JNZXNzYWdlQXJncykpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBFbnN1cmVzIHRoZSB0cnV0aCBvZiBhbiBleHByZXNzaW9uIGludm9sdmluZyB0aGUgc3RhdGUgb2YgdGhlIGNhbGxpbmcgaW5zdGFuY2UsIGJ1dCBub3QKKyAgICogaW52b2x2aW5nIGFueSBwYXJhbWV0ZXJzIHRvIHRoZSBjYWxsaW5nIG1ldGhvZC4KKyAgICoKKyAgICogQHBhcmFtIGV4cHJlc3Npb24gYSBib29sZWFuIGV4cHJlc3Npb24KKyAgICogQHBhcmFtIGVycm9yTWVzc2FnZVRlbXBsYXRlIGEgdGVtcGxhdGUgZm9yIHRoZSBleGNlcHRpb24gbWVzc2FnZSBzaG91bGQgdGhlIGNoZWNrIGZhaWwuIFRoZQorICAgKiAgICAgbWVzc2FnZSBpcyBmb3JtZWQgYnkgcmVwbGFjaW5nIGVhY2gge0Bjb2RlICVzfSBwbGFjZWhvbGRlciBpbiB0aGUgdGVtcGxhdGUgd2l0aCBhbgorICAgKiAgICAgYXJndW1lbnQuIFRoZXNlIGFyZSBtYXRjaGVkIGJ5IHBvc2l0aW9uIC0gdGhlIGZpcnN0IHtAY29kZSAlc30gZ2V0cyB7QGNvZGUKKyAgICogICAgIGVycm9yTWVzc2FnZUFyZ3NbMF19LCBldGMuCisgICAqIEBwYXJhbSBlcnJvck1lc3NhZ2VBcmdzIHRoZSBhcmd1bWVudHMgdG8gYmUgc3Vic3RpdHV0ZWQgaW50byB0aGUgbWVzc2FnZSB0ZW1wbGF0ZS4gQXJndW1lbnRzCisgICAqICAgICBhcmUgY29udmVydGVkIHRvIHN0cmluZ3MgdXNpbmcge0BsaW5rIFN0cmluZyN2YWx1ZU9mKE9iamVjdCl9LgorICAgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpZiB7QGNvZGUgZXhwcmVzc2lvbn0gaXMgZmFsc2UKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja1N0YXRlKAorICAgICAgYm9vbGVhbiBleHByZXNzaW9uLAorICAgICAgQE51bGxhYmxlIFN0cmluZyBlcnJvck1lc3NhZ2VUZW1wbGF0ZSwKKyAgICAgIEBOdWxsYWJsZSBPYmplY3QuLi4gZXJyb3JNZXNzYWdlQXJncykgeworICAgIGlmICghZXhwcmVzc2lvbikgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihmb3JtYXQoZXJyb3JNZXNzYWdlVGVtcGxhdGUsIGVycm9yTWVzc2FnZUFyZ3MpKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZm9ybWF0KFN0cmluZyB0ZW1wbGF0ZSwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICAvLyBXZSBkbyBub3QgaGFuZGxlIG51bGwgcGFyYW1ldGVycyBncmFjZWZ1bGx5IGxpa2UgR3VhdmEuIElmIHdlIGZpbmQgdGhhdCB3ZSBhcmUgcGFzc2luZyBpbgorICAgIC8vIGludmFsaWQgcGFyYW1ldGVycyB3ZSBjYW4gZG8gbW9yZSBjaGVja3MgaGVyZS4KKyAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCh0ZW1wbGF0ZSwgYXJncyk7CisgIH0KKworICBwcml2YXRlIFByZWNvbmRpdGlvbnMoKSB7fQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0Fsd2F5c1Rocm93c1RyYW5zZm9ybS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0Fsd2F5c1Rocm93c1RyYW5zZm9ybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5ZjFhMzAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvQWx3YXlzVGhyb3dzVHJhbnNmb3JtLmphdmEKQEAgLTAsMCArMSw4MCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZzsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbC5Gb3J3YXJkaW5nSW5wdXRTdHJlYW07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuRm9yd2FyZGluZ091dHB1dFN0cmVhbTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5UcmFuc2Zvcm07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCisvKiogQSBUcmFuc2Zvcm0gdGhhdCB0aHJvd3MgSU9FeGNlcHRpb25zIGZvciBhbnkgcmVhZCBvciB3cml0ZSBvcGVyYXRpb24uICovCitwdWJsaWMgY2xhc3MgQWx3YXlzVGhyb3dzVHJhbnNmb3JtIGltcGxlbWVudHMgVHJhbnNmb3JtIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTkFNRSA9ICJhbHdheXN0aHJvd3MiOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIG5hbWUoKSB7CisgICAgcmV0dXJuIE5BTUU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIHdyYXBGb3JSZWFkKFVyaSB1cmksIElucHV0U3RyZWFtIHdyYXBwZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ldyBGb3J3YXJkaW5nSW5wdXRTdHJlYW0od3JhcHBlZCkgeworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidGhyb3dpbmciKTsKKyAgICAgIH0KKworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidGhyb3dpbmciKTsKKyAgICAgIH0KKworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInRocm93aW5nIik7CisgICAgICB9CisgICAgfTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3V0cHV0U3RyZWFtIHdyYXBGb3JXcml0ZShVcmkgdXJpLCBPdXRwdXRTdHJlYW0gd3JhcHBlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gbmV3IEZvcndhcmRpbmdPdXRwdXRTdHJlYW0od3JhcHBlZCkgeworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ0aHJvd2luZyIpOworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oInRocm93aW5nIik7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigidGhyb3dpbmciKTsKKyAgICAgIH0KKyAgICB9OworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBPdXRwdXRTdHJlYW0gd3JhcEZvckFwcGVuZChVcmkgdXJpLCBPdXRwdXRTdHJlYW0gd3JhcHBlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gd3JhcEZvcldyaXRlKHVyaSwgd3JhcHBlZCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MTA3MjlmCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0JVSUxECkBAIC0wLDAgKzEsMTQyIEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCIvL3Rvb2xzL2J1aWxkX2RlZnMvdGVzdGluZzpiemxfbGlicmFyeS5iemwiLCAiYnpsX2xpYnJhcnkiKQorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF90ZXN0b25seSA9IDEsCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWyIvLzpfX3N1YnBhY2thZ2VzX18iXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKKyMgVGhpcyBpcyBhIGphdmFfbGlicmFyeSByYXRoZXIgdGhhbiBhbmRyb2lkX2xpYnJhcnkgYmVjYXVzZSBpdCBpbmNsdWRlcyB0ZXN0CisjIGluZnJhc3RydWN0dXJlIGZvciByb2JvbGVjdHJpYyB0ZXN0cy4gSXQgaXMgYSBzZXBhcmF0ZSBidWlsZCB0YXJnZXQgZnJvbSB0aGUKKyMgbWFpbiAidGVzdGluZyIgdGFyZ2V0IGJlbG93IGluIG9yZGVyIHRvIGFsbG93IGFuZHJvaWRfdGVzdHMgdG8gZGVwZW5kIG9uIHRoZQorIyBsYXR0ZXIuIFNlZSBsaW5rIGZvciBtb3JlIGluZm9ybWF0aW9uOgorIyA8aW50ZXJuYWw+CitqYXZhX2xpYnJhcnkoCisgICAgbmFtZSA9ICJyb2JvbGVjdHJpYyIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlNoYWRvd1V0aWxzLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBhbmRyb2lkX3Nka19saW51eCIsCisgICAgICAgICJAcm9ib2xlY3RyaWMiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImZpbGVzdG9yYWdlIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkZpbGVTdG9yYWdlVGVzdEJhc2UuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIkBqdW5pdCIsCisgICAgICAgICJAbW9ja2l0byIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAibWF0Y2hlcnMiLAorICAgIHRlc3Rvbmx5ID0gMSwKKyAgICBzcmNzID0gWyJGcmFnbWVudFBhcmFtTWF0Y2hlcnMuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6bGl0ZV90cmFuc2Zvcm1fZnJhZ21lbnRzIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJ0ZXN0aW5nIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkJhY2tlbmRUZXN0QmFzZS5qYXZhIiwKKyAgICAgICAgIkV4Y2VwdGlvblRlc3RpbmcuamF2YSIsCisgICAgICAgICJTdHJlYW1VdGlscy5qYXZhIiwKKyAgICAgICAgIlRlbXBvcmFyeUFuZHJvaWRVcmkuamF2YSIsCisgICAgICAgICJUZW1wb3JhcnlVcmkuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZF9hZGFwdGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpjaGFyc2V0cyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnN0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGp1bml0IiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiZXh0cmFzIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkFsd2F5c1Rocm93c1RyYW5zZm9ybS5qYXZhIiwKKyAgICAgICAgIkJ1ZmZlcmluZ01vbml0b3IuamF2YSIsCisgICAgICAgICJEdW1teVRyYW5zZm9ybXMuamF2YSIsCisgICAgICAgICJGaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyLmphdmEiLAorICAgICAgICAiTm9PcE1vbml0b3IuamF2YSIsCisgICAgICAgICJXcml0ZXNUaHJvd1RyYW5zZm9ybS5qYXZhIiwKKyAgICBdLAorICAgIGV4cG9ydHMgPSBbCisgICAgICAgICI6ZmFrZV9maWxlX2JhY2tlbmQiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbjpmcmFnbWVudCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6Zm9yd2FyZGluZ19zdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBqdW5pdCIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImZha2VfZmlsZV9iYWNrZW5kIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkZha2VGaWxlQmFja2VuZC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6Zm9yd2FyZGluZ19zdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICAgICAgIkBvcmdfY2hlY2tlcmZyYW1ld29ya19xdWFsIiwKKyAgICBdLAorKQorCitqYXZhX2xpdGVfcHJvdG9fbGlicmFyeSgKKyAgICBuYW1lID0gInRlc3RfbWVzc2FnZV9qYXZhX3Byb3RvX2xpdGUiLAorICAgIGRlcHMgPSBbIjp0ZXN0X21lc3NhZ2VfcHJvdG8iXSwKKykKKworcHJvdG9fbGlicmFyeSgKKyAgICBuYW1lID0gInRlc3RfbWVzc2FnZV9wcm90byIsCisgICAgc3JjcyA9IFsidGVzdF9tZXNzYWdlLnByb3RvIl0sCispCisKK2J6bF9saWJyYXJ5KAorICAgIG5hbWUgPSAiYnVpbGRfZGVmc19iemwiLAorICAgIHNyY3MgPSBbImJ1aWxkX2RlZnMuYnpsIl0sCisgICAgcGFyc2VfdGVzdHMgPSBGYWxzZSwKKyAgICBkZXBzID0gWyIvL3Rvb2xzL2J1aWxkX2RlZnMvYW5kcm9pZDpydWxlc19iemwiXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9CYWNrZW5kVGVzdEJhc2UuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9CYWNrZW5kVGVzdEJhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZGUxMjc3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0JhY2tlbmRUZXN0QmFzZS5qYXZhCkBAIC0wLDAgKzEsNTQ3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMuYXBwZW5kRmlsZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5jcmVhdGVGaWxlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLm1ha2VBcnJheU9mQnl0ZXNDb250ZW50OworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLnJlYWRGaWxlSW5CeXRlczsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5yZWFkRmlsZUluQnl0ZXNGcm9tU291cmNlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLndyaXRlRmlsZVRvU2luazsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3N1bWUuYXNzdW1lVHJ1ZTsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uRmlsZUNvbnZlcnRpYmxlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLk1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuQXBwZW5kU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWFkU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5Xcml0ZVN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5CYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0Lkxpc3RzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnByaW1pdGl2ZXMuQnl0ZXM7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UZXN0TmFtZTsKKworLyoqCisgKiBCYXNlIGNsYXNzIGZvciB7QGNvZGUgQmFja2VuZH0gdGVzdHMgdGhhdCBleGVyY2lzZXMgY29tbW9uIGJlaGF2aW9yIGV4cGVjdGVkIG9mIGFsbAorICogaW1wbGVtZW50YXRpb25zLiBDb25jcmV0ZSB0ZXN0IGNhc2VzIG11c3Qgc3BlY2lmeSBhIHRlc3QgcnVubmVyLCBleHRlbmQgZnJvbSB0aGlzIGNsYXNzLCBhbmQKKyAqIGltcGxlbWVudCB0aGUgYWJzdHJhY3Qgc2V0dXAgbWV0aG9kcy4gU3ViY2xhc3NlcyBhcmUgZnJlZSB0byBhZGQgYWRkaXRpb25hbCB0ZXN0IG1ldGhvZHMgaW4gb3JkZXIKKyAqIHRvIGV4ZXJjaXNlIGJhY2tlbmQtc3BlY2lmaWMgYmVoYXZpb3IgdXNpbmcgdGhlIHByb3ZpZGVkIHtAbGluayAjc3RvcmFnZX0uCisgKgorICogPHA+SWYgdGhlIGJhY2tlbmQgdW5kZXIgdGVzdCBkb2VzIG5vdCBzdXBwb3J0IGEgc3BlY2lmaWMgZmVhdHVyZSwgdGhlIHRlc3Qgc3ViY2xhc3Mgc2hvdWxkCisgKiBvdmVycmlkZSB0aGUgYXBwcm9wcmlhdGUge0Bjb2RlIHN1cHBvcnRzWCgpfSBhbmQgcmV0dXJuIGZhbHNlIGluIG9yZGVyIHRvIHNraXAgdGhlIGFzc29jaWF0ZWQKKyAqIHVuaXQgdGVzdHMuIE5PVEU6IHRoaXMgaXMgYWRvcHRlZCBmcm9tIEd1YXZhIGFuZCBzZWVtcyBsaWtlIHRoZSBsZWFzdC1iYWQgc3RyYXRlZ3kuCisgKgorICogPHA+QWJzdHJhY3Qgc2V0dXAgbWV0aG9kcyBtYXkgYmUgY2FsbGVkIGJlZm9yZSB0aGUge0Bjb2RlIEBCZWZvcmV9IG1ldGhvZHMgb2YgdGhlIHN1YmNsYXNzLCBhbmQKKyAqIHNvIHNob3VsZCBub3QgZGVwZW5kIG9uIHRoZW0uIHtAY29kZSBAQmVmb3JlQ2xhc3N9LCBsYXp5IGluaXRpYWxpemF0aW9uLCBhbmQgc3RhdGljCisgKiBpbml0aWFsaXphdGlvbiBhcmUgdmlhYmxlIGFsdGVybmF0aXZlcy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEJhY2tlbmRUZXN0QmFzZSB7CisKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGJ5dGVbXSBURVNUX0NPTlRFTlQgPSBtYWtlQXJyYXlPZkJ5dGVzQ29udGVudCgpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gT1RIRVJfQ09OVEVOVCA9IG1ha2VBcnJheU9mQnl0ZXNDb250ZW50KDYpOworCisgIEBSdWxlIHB1YmxpYyBUZXN0TmFtZSB0ZXN0TmFtZSA9IG5ldyBUZXN0TmFtZSgpOworCisgIC8qKiBSZXR1cm5zIHRoZSBjb25jcmV0ZSB7QGNvZGUgQmFja2VuZH0gaW5zdGFuY2UgdG8gYmUgdGVzdGVkLiAqLworICBwcm90ZWN0ZWQgYWJzdHJhY3QgQmFja2VuZCBiYWNrZW5kKCk7CisKKyAgLyoqIEVuYWJsZXMgdW5pdCB0ZXN0cyB2ZXJpZnlpbmcge0BsaW5rIEJhY2tlbmQjb3BlbkZvckFwcGVuZH0uICovCisgIHByb3RlY3RlZCBib29sZWFuIHN1cHBvcnRzQXBwZW5kKCkgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLyoqIEVuYWJsZXMgdW5pdCB0ZXN0cyB2ZXJpZnlpbmcge0BsaW5rIEJhY2tlbmQjcmVuYW1lfS4gKi8KKyAgcHJvdGVjdGVkIGJvb2xlYW4gc3VwcG9ydHNSZW5hbWUoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKioKKyAgICogRW5hYmxlcyB1bml0IHRlc3RzIHZlcmlmeWluZyB7QGxpbmsgQmFja2VuZCNjcmVhdGVEaXJlY3Rvcnl9LCB7QGxpbmsgQmFja2VuZCNpc0RpcmVjdG9yeX0sCisgICAqIHtAbGluayBCYWNrZW5kI2RlbGV0ZURpcmVjdG9yeX0sIHtAbGluayBCYWNrZW5kI2NoaWxkcmVufSwgYW5kIHdyaXRpbmcgdG8gYSBzdWJkaXJlY3RvcnkgdXJpLgorICAgKi8KKyAgcHJvdGVjdGVkIGJvb2xlYW4gc3VwcG9ydHNEaXJlY3RvcmllcygpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8qKiBFbmFibGVzIHVuaXQgdGVzdHMgdmVyaWZ5aW5nIHRoYXQge0BsaW5rIEZpbGVDb252ZXJ0aWJsZX0gY2FuIGJlIHJldHVybmVkIGRpcmVjdGx5LiAqLworICBwcm90ZWN0ZWQgYm9vbGVhbiBzdXBwb3J0c0ZpbGVDb252ZXJ0aWJsZSgpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8qKiBFbmFibGUgdW5pdCB0ZXN0cyB2ZXJpZnlpbmcge0BsaW5rIEJhY2tlbmQjdG9GaWxlfS4gKi8KKyAgcHJvdGVjdGVkIGJvb2xlYW4gc3VwcG9ydHNUb0ZpbGUoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyBhIFVSSSB0byBhIHRlbXBvcmFyeSBkaXJlY3RvcnkgZm9yIHdyaXRpbmcgdGVzdCBkYXRhIHRvLiBUaGUge0Bjb2RlIEJhY2tlbmR9IHNob3VsZCBiZQorICAgKiBhYmxlIHRvIHtAY29kZSBvcGVuRm9yV3JpdGV9IGEgZmlsZSB0byB0aGlzIGRpcmVjdG9yeSB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHNldHVwIGNvZGUuCisgICAqLworICBwcm90ZWN0ZWQgYWJzdHJhY3QgVXJpIGxlZ2FsVXJpQmFzZSgpIHRocm93cyBJT0V4Y2VwdGlvbjsKKworICAvKioKKyAgICogUmV0dXJucyBhIGxpc3Qgb2YgVVJJcyBmb3Igd2hpY2gge0Bjb2RlIEJhY2tlbmQub3BlbkZvclJlYWQodXJpKX0gaXMgZXhwZWN0ZWQgdG8gdGhyb3cge0Bjb2RlCisgICAqIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbn0gd2l0aG91dCBhbnkgYWRkaXRpb25hbCBzZXR1cCBjb2RlLgorICAgKi8KKyAgcHJvdGVjdGVkIExpc3Q8VXJpPiBpbGxlZ2FsVXJpc1RvUmVhZCgpIHsKKyAgICByZXR1cm4gSW1tdXRhYmxlTGlzdC5vZigpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgYSBsaXN0IG9mIFVSSXMgZm9yIHdoaWNoIHtAY29kZSBCYWNrZW5kLm9wZW5Gb3JXcml0ZSh1cmkpfSBpcyBleHBlY3RlZCB0byB0aHJvdyB7QGNvZGUKKyAgICogTWFsZm9ybWVkVXJpRXhjZXB0aW9ufSB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHNldHVwIGNvZGUuCisgICAqLworICBwcm90ZWN0ZWQgTGlzdDxVcmk+IGlsbGVnYWxVcmlzVG9Xcml0ZSgpIHsKKyAgICByZXR1cm4gSW1tdXRhYmxlTGlzdC5vZigpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgYSBsaXN0IG9mIFVSSXMgZm9yIHdoaWNoIHtAY29kZSBCYWNrZW5kLm9wZW5Gb3JBcHBlbmQodXJpKX0gaXMgZXhwZWN0ZWQgdG8gdGhyb3cge0Bjb2RlCisgICAqIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbn0gd2l0aG91dCBhbnkgYWRkaXRpb25hbCBzZXR1cCBjb2RlLgorICAgKi8KKyAgcHJvdGVjdGVkIExpc3Q8VXJpPiBpbGxlZ2FsVXJpc1RvQXBwZW5kKCkgeworICAgIHJldHVybiBJbW11dGFibGVMaXN0Lm9mKCk7CisgIH0KKworICBAQmVmb3JlCisgIHB1YmxpYyBmaW5hbCB2b2lkIHNldFVwU3RvcmFnZSgpIHsKKyAgICBhc3NlcnRUaGF0KGJhY2tlbmQoKSkuaXNOb3ROdWxsKCk7CisgICAgc3RvcmFnZSA9IG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEltbXV0YWJsZUxpc3Qub2YoYmFja2VuZCgpKSwgSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgfQorCisgIC8qKiBSZXR1cm5zIHRoZSBzdG9yYWdlIGluc3RhbmNlIHVzZWQgaW4gdGVzdGluZy4gKi8KKyAgcHJvdGVjdGVkIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSgpIHsKKyAgICByZXR1cm4gc3RvcmFnZTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG5hbWVfcmV0dXJuc05vbkVtcHR5U3RyaW5nKCkgeworICAgIGFzc2VydFRoYXQoYmFja2VuZCgpLm5hbWUoKSkuaXNOb3RFbXB0eSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkZvclJlYWRfd2l0aE1pc3NpbmdGaWxlX3Rocm93c0ZpbGVOb3RGb3VuZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB1cmlGb3JUZXN0TWV0aG9kKCk7CisgICAgYXNzZXJ0VGhyb3dzKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkZvclJlYWRfd2l0aElsbGVnYWxVcmlfdGhyb3dzSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZm9yIChVcmkgdXJpIDogaWxsZWdhbFVyaXNUb1JlYWQoKSkgeworICAgICAgYXNzZXJ0VGhyb3dzKE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5Gb3JSZWFkX3JlYWRzV3JpdHRlbkNvbnRlbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgdXJpLCBURVNUX0NPTlRFTlQpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVJbkJ5dGVzKHN0b3JhZ2UsIHVyaSkpLmlzRXF1YWxUbyhURVNUX0NPTlRFTlQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkZvclJlYWRfcmV0dXJuc0ZpbGVDb252ZXJ0aWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc3VtZVRydWUoc3VwcG9ydHNGaWxlQ29udmVydGlibGUoKSk7CisKKyAgICBVcmkgdXJpID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSgpLCB1cmksIFRFU1RfQ09OVEVOVCk7CisKKyAgICBJbnB1dFN0cmVhbSBzdHJlYW0gPSBiYWNrZW5kKCkub3BlbkZvclJlYWQodXJpKTsKKyAgICBhc3NlcnRUaGF0KHN0cmVhbSkuaXNJbnN0YW5jZU9mKEZpbGVDb252ZXJ0aWJsZS5jbGFzcyk7CisgICAgRmlsZSBmaWxlID0gKChGaWxlQ29udmVydGlibGUpIHN0cmVhbSkudG9GaWxlKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkRmlsZUluQnl0ZXNGcm9tU291cmNlKG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSkpKS5pc0VxdWFsVG8oVEVTVF9DT05URU5UKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5Gb3JXcml0ZV93aXRoSWxsZWdhbFVyaV90aHJvd3NJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmb3IgKFVyaSB1cmkgOiBpbGxlZ2FsVXJpc1RvV3JpdGUoKSkgeworICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRm9yV3JpdGVfd2l0aEZhaWxlZERpcmVjdG9yeUNyZWF0aW9uX3Rocm93c0V4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc3VtZVRydWUoc3VwcG9ydHNEaXJlY3RvcmllcygpKTsKKworICAgIFVyaSBwYXJlbnQgPSB1cmlGb3JUZXN0TWV0aG9kKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCBwYXJlbnQsIFRFU1RfQ09OVEVOVCk7CisKKyAgICBVcmkgY2hpbGQgPSBwYXJlbnQuYnVpbGRVcG9uKCkuYXBwZW5kUGF0aCgiY2hpbGQiKS5idWlsZCgpOworICAgIGFzc2VydFRocm93cyhJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc3RvcmFnZS5vcGVuKGNoaWxkLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkZvcldyaXRlX292ZXJ3cml0ZXNFeGlzdGluZ0NvbnRlbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgdXJpLCBPVEhFUl9DT05URU5UKTsKKworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgdXJpLCBURVNUX0NPTlRFTlQpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVJbkJ5dGVzKHN0b3JhZ2UsIHVyaSkpLmlzRXF1YWxUbyhURVNUX0NPTlRFTlQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkZvcldyaXRlX2NyZWF0ZXNQYXJlbnREaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3N1bWVUcnVlKHN1cHBvcnRzRGlyZWN0b3JpZXMoKSk7CisKKyAgICBVcmkgcGFyZW50ID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIFVyaSBjaGlsZCA9IHBhcmVudC5idWlsZFVwb24oKS5hcHBlbmRQYXRoKCJjaGlsZCIpLmJ1aWxkKCk7CisKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIGNoaWxkLCBURVNUX0NPTlRFTlQpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeShwYXJlbnQpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZXhpc3RzKGNoaWxkKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRm9yV3JpdGVfcmV0dXJuc0ZpbGVDb252ZXJ0aWJsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc3VtZVRydWUoc3VwcG9ydHNGaWxlQ29udmVydGlibGUoKSk7CisKKyAgICBVcmkgdXJpID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIHRyeSAoT3V0cHV0U3RyZWFtIHN0cmVhbSA9IGJhY2tlbmQoKS5vcGVuRm9yV3JpdGUodXJpKSkgeworICAgICAgYXNzZXJ0VGhhdChzdHJlYW0pLmlzSW5zdGFuY2VPZihGaWxlQ29udmVydGlibGUuY2xhc3MpOworICAgICAgRmlsZSBmaWxlID0gKChGaWxlQ29udmVydGlibGUpIHN0cmVhbSkudG9GaWxlKCk7CisgICAgICB3cml0ZUZpbGVUb1NpbmsobmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSksIFRFU1RfQ09OVEVOVCk7CisgICAgfQorICAgIGFzc2VydFRoYXQocmVhZEZpbGVJbkJ5dGVzKHN0b3JhZ2UoKSwgdXJpKSkuaXNFcXVhbFRvKFRFU1RfQ09OVEVOVCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRm9yQXBwZW5kX3dpdGhJbGxlZ2FsVXJpX3Rocm93c0lsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc3VtZVRydWUoc3VwcG9ydHNBcHBlbmQoKSk7CisKKyAgICBmb3IgKFVyaSB1cmkgOiBpbGxlZ2FsVXJpc1RvQXBwZW5kKCkpIHsKKyAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICBNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsICgpIC0+IHN0b3JhZ2Uub3Blbih1cmksIEFwcGVuZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5Gb3JBcHBlbmRfYXBwZW5kc0NvbnRlbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3N1bWVUcnVlKHN1cHBvcnRzQXBwZW5kKCkpOworCisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgT1RIRVJfQ09OVEVOVCk7CisKKyAgICBhcHBlbmRGaWxlKHN0b3JhZ2UsIHVyaSwgVEVTVF9DT05URU5UKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlSW5CeXRlcyhzdG9yYWdlLCB1cmkpKS5pc0VxdWFsVG8oQnl0ZXMuY29uY2F0KE9USEVSX0NPTlRFTlQsIFRFU1RfQ09OVEVOVCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkZvckFwcGVuZF9yZXR1cm5zRmlsZUNvbnZlcnRpYmxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzdW1lVHJ1ZShzdXBwb3J0c0FwcGVuZCgpKTsKKyAgICBhc3N1bWVUcnVlKHN1cHBvcnRzRmlsZUNvbnZlcnRpYmxlKCkpOworCisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgT1RIRVJfQ09OVEVOVCk7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gc3RyZWFtID0gYmFja2VuZCgpLm9wZW5Gb3JBcHBlbmQodXJpKSkgeworICAgICAgYXNzZXJ0VGhhdChzdHJlYW0pLmlzSW5zdGFuY2VPZihGaWxlQ29udmVydGlibGUuY2xhc3MpOworICAgICAgRmlsZSBmaWxlID0gKChGaWxlQ29udmVydGlibGUpIHN0cmVhbSkudG9GaWxlKCk7CisgICAgICB3cml0ZUZpbGVUb1NpbmsobmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlsZSwgLyogYXBwZW5kID0gKi8gdHJ1ZSksIFRFU1RfQ09OVEVOVCk7CisgICAgfQorICAgIGFzc2VydFRoYXQocmVhZEZpbGVJbkJ5dGVzKHN0b3JhZ2UoKSwgdXJpKSkKKyAgICAgICAgLmlzRXF1YWxUbyhCeXRlcy5jb25jYXQoT1RIRVJfQ09OVEVOVCwgVEVTVF9DT05URU5UKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVGaWxlX2RlbGV0ZXNGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgVEVTVF9DT05URU5UKTsKKworICAgIHN0b3JhZ2UuZGVsZXRlRmlsZSh1cmkpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5leGlzdHModXJpKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZGVsZXRlRmlsZV9vbkRpcmVjdG9yeV90aHJvd3NGaWxlTm90Rm91bmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3N1bWVUcnVlKHN1cHBvcnRzRGlyZWN0b3JpZXMoKSk7CisKKyAgICBVcmkgdXJpID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIHN0b3JhZ2UuY3JlYXRlRGlyZWN0b3J5KHVyaSk7CisKKyAgICBhc3NlcnRUaHJvd3MoRmlsZU5vdEZvdW5kRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLmRlbGV0ZUZpbGUodXJpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVGaWxlX29uTWlzc2luZ0ZpbGVfdGhyb3dzRmlsZU5vdEZvdW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBhc3NlcnRUaHJvd3MoRmlsZU5vdEZvdW5kRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLmRlbGV0ZUZpbGUodXJpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZW5hbWVfcmVuYW1lc0ZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3N1bWVUcnVlKHN1cHBvcnRzUmVuYW1lKCkpOworCisgICAgVXJpIHVyaTEgPSB1cmlGb3JUZXN0TWV0aG9kV2l0aFN1ZmZpeCgiMSIpOworICAgIFVyaSB1cmkyID0gdXJpRm9yVGVzdE1ldGhvZFdpdGhTdWZmaXgoIjIiKTsKKyAgICBVcmkgdXJpMyA9IHVyaUZvclRlc3RNZXRob2RXaXRoU3VmZml4KCIzIik7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmkxLCBPVEhFUl9DT05URU5UKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaTIsIFRFU1RfQ09OVEVOVCk7CisKKyAgICBzdG9yYWdlLnJlbmFtZSh1cmkyLCB1cmkzKTsKKyAgICBzdG9yYWdlLnJlbmFtZSh1cmkxLCB1cmkyKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZXhpc3RzKHVyaTEpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkRmlsZUluQnl0ZXMoc3RvcmFnZSwgdXJpMikpLmlzRXF1YWxUbyhPVEhFUl9DT05URU5UKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlSW5CeXRlcyhzdG9yYWdlLCB1cmkzKSkuaXNFcXVhbFRvKFRFU1RfQ09OVEVOVCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZW5hbWVfcmVuYW1lc0RpcmVjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc3VtZVRydWUoc3VwcG9ydHNSZW5hbWUoKSk7CisgICAgYXNzdW1lVHJ1ZShzdXBwb3J0c0RpcmVjdG9yaWVzKCkpOworCisgICAgVXJpIHVyaUEgPSB1cmlGb3JUZXN0TWV0aG9kV2l0aFN1ZmZpeCgiYSIpOworICAgIFVyaSB1cmlCID0gdXJpRm9yVGVzdE1ldGhvZFdpdGhTdWZmaXgoImIiKTsKKworICAgIHN0b3JhZ2UuY3JlYXRlRGlyZWN0b3J5KHVyaUEpOworICAgIHN0b3JhZ2UucmVuYW1lKHVyaUEsIHVyaUIpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmlBKSkuaXNGYWxzZSgpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmlCKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBleGlzdHNfcmV0dXJuc1RydWVJZkZpbGVFeGlzdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5leGlzdHModXJpKSkuaXNGYWxzZSgpOworCisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIFRFU1RfQ09OVEVOVCk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyh1cmkpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGV4aXN0c19yZXR1cm5zVHJ1ZUlmRGlyZWN0b3J5RXhpc3RzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzdW1lVHJ1ZShzdXBwb3J0c0RpcmVjdG9yaWVzKCkpOworCisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZXhpc3RzKHVyaSkpLmlzRmFsc2UoKTsKKworICAgIHN0b3JhZ2UuY3JlYXRlRGlyZWN0b3J5KHVyaSk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyh1cmkpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGlzRGlyZWN0b3J5X3JldHVybnNUcnVlSWZEaXJlY3RvcnlFeGlzdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3N1bWVUcnVlKHN1cHBvcnRzRGlyZWN0b3JpZXMoKSk7CisKKyAgICBVcmkgdXJpID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmkpKS5pc0ZhbHNlKCk7CisKKyAgICBzdG9yYWdlLmNyZWF0ZURpcmVjdG9yeSh1cmkpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmkpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGlzRGlyZWN0b3J5X3JldHVybnNGYWxzZUlmRG9lc250RXhpc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3N1bWVUcnVlKHN1cHBvcnRzRGlyZWN0b3JpZXMoKSk7CisKKyAgICBVcmkgdXJpID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmkpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpc0RpcmVjdG9yeV9yZXR1cm5zRmFsc2VJZklzRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc3VtZVRydWUoc3VwcG9ydHNEaXJlY3RvcmllcygpKTsKKworICAgIFVyaSB1cmkgPSB1cmlGb3JUZXN0TWV0aG9kKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIFRFU1RfQ09OVEVOVCk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmlzRGlyZWN0b3J5KHVyaSkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNyZWF0ZURpcmVjdG9yeV9jcmVhdGVzRGlyZWN0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzdW1lVHJ1ZShzdXBwb3J0c0RpcmVjdG9yaWVzKCkpOworCisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBzdG9yYWdlLmNyZWF0ZURpcmVjdG9yeSh1cmkpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmkpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNyZWF0ZURpcmVjdG9yeV9jcmVhdGVzUGFyZW50RGlyZWN0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzdW1lVHJ1ZShzdXBwb3J0c0RpcmVjdG9yaWVzKCkpOworCisgICAgVXJpIHBhcmVudCA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBVcmkgY2hpbGQgPSBwYXJlbnQuYnVpbGRVcG9uKCkuYXBwZW5kUGF0aCgiY2hpbGQiKS5idWlsZCgpOworCisgICAgc3RvcmFnZS5jcmVhdGVEaXJlY3RvcnkoY2hpbGQpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeShjaGlsZCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeShwYXJlbnQpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGZpbGVTaXplX3dpdGhNaXNzaW5nRmlsZV9yZXR1cm5zWmVybygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB1cmlGb3JUZXN0TWV0aG9kKCk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmZpbGVTaXplKHVyaSkpLmlzRXF1YWxUbygwKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGZpbGVTaXplX3JldHVybnNTaXplT2ZGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKworICAgIGJhY2tlbmQoKS5vcGVuRm9yV3JpdGUodXJpKS5jbG9zZSgpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5maWxlU2l6ZSh1cmkpKS5pc0VxdWFsVG8oMCk7CisKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgVEVTVF9DT05URU5UKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZmlsZVNpemUodXJpKSkuaXNFcXVhbFRvKFRFU1RfQ09OVEVOVC5sZW5ndGgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZmlsZVNpemVfd2l0aERpclJldHVybnMwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzdW1lVHJ1ZShzdXBwb3J0c0RpcmVjdG9yaWVzKCkpOworCisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBzdG9yYWdlLmNyZWF0ZURpcmVjdG9yeSh1cmkpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5maWxlU2l6ZSh1cmkpKS5pc0VxdWFsVG8oMCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVEaXJlY3Rvcnlfc2hvdWxkRGVsZXRlRW1wdHlEaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3N1bWVUcnVlKHN1cHBvcnRzRGlyZWN0b3JpZXMoKSk7CisKKyAgICBVcmkgdXJpID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmkpKS5pc0ZhbHNlKCk7CisgICAgc3RvcmFnZS5jcmVhdGVEaXJlY3RvcnkodXJpKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuaXNEaXJlY3RvcnkodXJpKSkuaXNUcnVlKCk7CisgICAgc3RvcmFnZS5kZWxldGVEaXJlY3RvcnkodXJpKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuaXNEaXJlY3RvcnkodXJpKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZGVsZXRlRGlyZWN0b3J5X3Nob3VsZE5PVERlbGV0ZU5vbkVtcHR5RGlyZWN0b3J5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzdW1lVHJ1ZShzdXBwb3J0c0RpcmVjdG9yaWVzKCkpOworCisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBzdG9yYWdlLmNyZWF0ZURpcmVjdG9yeSh1cmkpOworICAgIFVyaSBmaWxlVXJpID0gdXJpLmJ1aWxkVXBvbigpLmFwcGVuZFBhdGgoImZpbGUiKS5idWlsZCgpOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgZmlsZVVyaSwgVEVTVF9DT05URU5UKTsKKworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmkpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaHJvd3MoSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IHN0b3JhZ2UuZGVsZXRlRGlyZWN0b3J5KHVyaSkpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmkpKS5pc1RydWUoKTsKKworICAgIHN0b3JhZ2UuZGVsZXRlRmlsZShmaWxlVXJpKTsKKyAgICBzdG9yYWdlLmRlbGV0ZURpcmVjdG9yeSh1cmkpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmkpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVEaXJlY3Rvcnlfb25GaWxlU2hvdWxkVGhyb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3N1bWVUcnVlKHN1cHBvcnRzRGlyZWN0b3JpZXMoKSk7CisKKyAgICBVcmkgdXJpID0gdXJpRm9yVGVzdE1ldGhvZCgpOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgdXJpLCBURVNUX0NPTlRFTlQpOworCisgICAgYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLmRlbGV0ZURpcmVjdG9yeSh1cmkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNoaWxkcmVuX3dpdGhFbXB0eURpcmVjdG9yeVNob3VsZFJldHVybkVtcHR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzdW1lVHJ1ZShzdXBwb3J0c0RpcmVjdG9yaWVzKCkpOworCisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBzdG9yYWdlLmNyZWF0ZURpcmVjdG9yeSh1cmkpOworCisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmNoaWxkcmVuKHVyaSkpLmlzRW1wdHkoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNoaWxkcmVuX29uTm90Rm91bmRTaG91bGRUaHJvdygpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc3VtZVRydWUoc3VwcG9ydHNEaXJlY3RvcmllcygpKTsKKworICAgIFVyaSB1cmkgPSB1cmlGb3JUZXN0TWV0aG9kKCk7CisKKyAgICBhc3NlcnRUaHJvd3MoSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IHN0b3JhZ2UuY2hpbGRyZW4odXJpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjaGlsZHJlbl9vbkZpbGVTaG91bGRUaHJvdygpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc3VtZVRydWUoc3VwcG9ydHNEaXJlY3RvcmllcygpKTsKKworICAgIFVyaSB1cmkgPSB1cmlGb3JUZXN0TWV0aG9kKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIFRFU1RfQ09OVEVOVCk7CisKKyAgICBhc3NlcnRUaHJvd3MoSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IHN0b3JhZ2UuY2hpbGRyZW4odXJpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjaGlsZHJlbl9zaG91bGRSZXR1cm5GaWxlc0FuZFN1YkRpcmVjdG9yaWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzdW1lVHJ1ZShzdXBwb3J0c0RpcmVjdG9yaWVzKCkpOworCisgICAgVXJpIHVyaSA9IHVyaUZvclRlc3RNZXRob2QoKTsKKyAgICBzdG9yYWdlLmNyZWF0ZURpcmVjdG9yeSh1cmkpOworCisgICAgTGlzdDxVcmk+IGZpbGVVcmlzID0KKyAgICAgICAgQXJyYXlzLmFzTGlzdCgKKyAgICAgICAgICAgIHVyaS5idWlsZFVwb24oKS5hcHBlbmRQYXRoKCJmaWxlMSIpLmJ1aWxkKCksCisgICAgICAgICAgICB1cmkuYnVpbGRVcG9uKCkuYXBwZW5kUGF0aCgiZmlsZTIiKS5idWlsZCgpLAorICAgICAgICAgICAgdXJpLmJ1aWxkVXBvbigpLmFwcGVuZFBhdGgoImZpbGUzIikuYnVpbGQoKSk7CisgICAgZm9yIChVcmkgZmlsZSA6IGZpbGVVcmlzKSB7CisgICAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIGZpbGUsIFRFU1RfQ09OVEVOVCk7CisgICAgfQorCisgICAgTGlzdDxVcmk+IHN1YmRpclVyaXMgPQorICAgICAgICBBcnJheXMuYXNMaXN0KAorICAgICAgICAgICAgdXJpLmJ1aWxkVXBvbigpLmFwcGVuZFBhdGgoImRpcjEiKS5idWlsZCgpLAorICAgICAgICAgICAgdXJpLmJ1aWxkVXBvbigpLmFwcGVuZFBhdGgoImRpcjIiKS5idWlsZCgpLAorICAgICAgICAgICAgdXJpLmJ1aWxkVXBvbigpLmFwcGVuZFBhdGgoImRpcjMiKS5idWlsZCgpKTsKKyAgICBmb3IgKFVyaSBzdWJkaXIgOiBzdWJkaXJVcmlzKSB7CisgICAgICBzdG9yYWdlLmNyZWF0ZURpcmVjdG9yeShzdWJkaXIpOworICAgIH0KKyAgICBMaXN0PFVyaT4gc3ViZGlyVXJpc1dpdGhUcmFpbGluZ1NsYXNoZXMgPQorICAgICAgICBMaXN0cy50cmFuc2Zvcm0oc3ViZGlyVXJpcywgdSAtPiBVcmkucGFyc2UodS50b1N0cmluZygpICsgIi8iKSk7CisKKyAgICBMaXN0PFVyaT4gZXhwZWN0ZWQgPSBMaXN0cy5uZXdBcnJheUxpc3QoKTsKKyAgICBleHBlY3RlZC5hZGRBbGwoZmlsZVVyaXMpOworICAgIGV4cGVjdGVkLmFkZEFsbChzdWJkaXJVcmlzV2l0aFRyYWlsaW5nU2xhc2hlcyk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmNoaWxkcmVuKHVyaSkpLmNvbnRhaW5zRXhhY3RseUVsZW1lbnRzSW4oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdG9GaWxlX2NvbnZlcnRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzdW1lVHJ1ZShzdXBwb3J0c1RvRmlsZSgpKTsKKworICAgIFVyaSB1cmkgPSB1cmlGb3JUZXN0TWV0aG9kKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIFRFU1RfQ09OVEVOVCk7CisgICAgRmlsZSBmaWxlID0gYmFja2VuZCgpLnRvRmlsZSh1cmkpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVJbkJ5dGVzRnJvbVNvdXJjZShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKSkuaXNFcXVhbFRvKFRFU1RfQ09OVEVOVCk7CisgIH0KKworICAvKiogUmV0dXJucyBhIFVSSSBpbiB0aGUgdGVzdCBkaXJlY3RvcnkgdW5pcXVlIHRvIHRoZSBjdXJyZW50IHRlc3QgbWV0aG9kLiAqLworICBwcm90ZWN0ZWQgVXJpIHVyaUZvclRlc3RNZXRob2QoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBsZWdhbFVyaUJhc2UoKS5idWlsZFVwb24oKS5hcHBlbmRQYXRoKHRlc3ROYW1lLmdldE1ldGhvZE5hbWUoKSkuYnVpbGQoKTsKKyAgfQorCisgIC8qKiBSZXR1cm5zIGEgVVJJIGluIHRoZSB0ZXN0IGRpcmVjdG9yeSB1bmlxdWUgdG8gdGhlIGN1cnJlbnQgdGVzdCBtZXRob2QgYW5kIHtAY29kZSBzdWZmaXh9LiAqLworICBwcml2YXRlIFVyaSB1cmlGb3JUZXN0TWV0aG9kV2l0aFN1ZmZpeChTdHJpbmcgc3VmZml4KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBsZWdhbFVyaUJhc2UoKS5idWlsZFVwb24oKS5hcHBlbmRQYXRoKHRlc3ROYW1lLmdldE1ldGhvZE5hbWUoKSArICItIiArIHN1ZmZpeCkuYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0J1ZmZlcmluZ01vbml0b3IuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9CdWZmZXJpbmdNb25pdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmFhYWRlYgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9CdWZmZXJpbmdNb25pdG9yLmphdmEKQEAgLTAsMCArMSw3NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZzsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5Nb25pdG9yOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtOworCisvKiogQSB0ZXN0aW5nIG1vbml0b3IgYnVmZmVycyBieXRlcyByZWFkIGFuZCB3cml0dGVuLiAqLworcHVibGljIGNsYXNzIEJ1ZmZlcmluZ01vbml0b3IgaW1wbGVtZW50cyBNb25pdG9yIHsKKyAgcHJpdmF0ZSBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gcmVhZEJ1ZmZlciA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgcHJpdmF0ZSBmaW5hbCBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gd3JpdGVCdWZmZXIgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgIHByaXZhdGUgZmluYWwgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGFwcGVuZEJ1ZmZlciA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKworICBwdWJsaWMgYnl0ZVtdIGJ5dGVzUmVhZCgpIHsKKyAgICByZXR1cm4gcmVhZEJ1ZmZlci50b0J5dGVBcnJheSgpOworICB9CisKKyAgcHVibGljIGJ5dGVbXSBieXRlc1dyaXR0ZW4oKSB7CisgICAgcmV0dXJuIHdyaXRlQnVmZmVyLnRvQnl0ZUFycmF5KCk7CisgIH0KKworICBwdWJsaWMgYnl0ZVtdIGJ5dGVzQXBwZW5kZWQoKSB7CisgICAgcmV0dXJuIGFwcGVuZEJ1ZmZlci50b0J5dGVBcnJheSgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBNb25pdG9yLklucHV0TW9uaXRvciBtb25pdG9yUmVhZChVcmkgdXJpKSB7CisgICAgcmV0dXJuIG5ldyBSZWFkTW9uaXRvcigpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBNb25pdG9yLk91dHB1dE1vbml0b3IgbW9uaXRvcldyaXRlKFVyaSB1cmkpIHsKKyAgICByZXR1cm4gbmV3IFdyaXRlTW9uaXRvcigpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBNb25pdG9yLk91dHB1dE1vbml0b3IgbW9uaXRvckFwcGVuZChVcmkgdXJpKSB7CisgICAgcmV0dXJuIG5ldyBBcHBlbmRNb25pdG9yKCk7CisgIH0KKworICBjbGFzcyBSZWFkTW9uaXRvciBpbXBsZW1lbnRzIE1vbml0b3IuSW5wdXRNb25pdG9yIHsKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBieXRlc1JlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHsKKyAgICAgIHJlYWRCdWZmZXIud3JpdGUoYiwgb2ZmLCBsZW4pOworICAgIH0KKyAgfQorCisgIGNsYXNzIFdyaXRlTW9uaXRvciBpbXBsZW1lbnRzIE1vbml0b3IuT3V0cHV0TW9uaXRvciB7CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYnl0ZXNXcml0dGVuKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICB3cml0ZUJ1ZmZlci53cml0ZShiLCBvZmYsIGxlbik7CisgICAgfQorICB9CisKKyAgY2xhc3MgQXBwZW5kTW9uaXRvciBpbXBsZW1lbnRzIE1vbml0b3IuT3V0cHV0TW9uaXRvciB7CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYnl0ZXNXcml0dGVuKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICBhcHBlbmRCdWZmZXIud3JpdGUoYiwgb2ZmLCBsZW4pOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0R1bW15VHJhbnNmb3Jtcy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0R1bW15VHJhbnNmb3Jtcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkZTNkMDEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvRHVtbXlUcmFuc2Zvcm1zLmphdmEKQEAgLTAsMCArMSw1NCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZzsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5UcmFuc2Zvcm07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCisvKiogRHVtbXkgdHJhbnNmb3JtIHNwZWNzIGZvciB0ZXN0aW5nLiAqLworcHVibGljIGNsYXNzIER1bW15VHJhbnNmb3JtcyB7CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBUcmFuc2Zvcm0gQ0FQX0ZJTEVOQU1FX1RSQU5TRk9STSA9CisgICAgICBuZXcgVHJhbnNmb3JtKCkgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgICAgICAgIHJldHVybiAiY2FwIjsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgSW5wdXRTdHJlYW0gd3JhcEZvclJlYWQoVXJpIHVyaSwgSW5wdXRTdHJlYW0gd3JhcHBlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICByZXR1cm4gd3JhcHBlZDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgT3V0cHV0U3RyZWFtIHdyYXBGb3JXcml0ZShVcmkgdXJpLCBPdXRwdXRTdHJlYW0gd3JhcHBlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgICByZXR1cm4gd3JhcHBlZDsKKyAgICAgICAgfQorCisgICAgICAgIEBPdmVycmlkZQorICAgICAgICBwdWJsaWMgT3V0cHV0U3RyZWFtIHdyYXBGb3JBcHBlbmQoVXJpIHVyaSwgT3V0cHV0U3RyZWFtIHdyYXBwZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgcmV0dXJuIHdyYXBwZWQ7CisgICAgICAgIH0KKworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBlbmNvZGUoVXJpIHVyaSwgU3RyaW5nIGZpbGVuYW1lKSB7CisgICAgICAgICAgcmV0dXJuIGZpbGVuYW1lLnRvVXBwZXJDYXNlKCk7CisgICAgICAgIH0KKyAgICAgIH07Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvRXhjZXB0aW9uVGVzdGluZy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0V4Y2VwdGlvblRlc3RpbmcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NzU1N2JiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0V4Y2VwdGlvblRlc3RpbmcuamF2YQpAQCAtMCwwICsxLDM0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkZ1dHVyZTsKKworLyoqIENvbW1vbiBoZWxwZXIgdXRpbGl0aWVzIGZvciB0ZXN0aW5nIGV4Y2VwdGlvbnMuICovCitwdWJsaWMgZmluYWwgY2xhc3MgRXhjZXB0aW9uVGVzdGluZyB7CisgIHB1YmxpYyBzdGF0aWMgPFQgZXh0ZW5kcyBUaHJvd2FibGU+IFQgYXNzZXJ0VGhyb3dzQXN5bmMoCisgICAgICBDbGFzczxUPiB0aHJvd2FibGVUeXBlLCBGdXR1cmU8Pz4gZnV0dXJlKSB7CisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4ZWN1dGlvbkV4Y2VwdGlvbiA9IGFzc2VydFRocm93cyhFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsIGZ1dHVyZTo6Z2V0KTsKKyAgICBhc3NlcnRUaGF0KGV4ZWN1dGlvbkV4Y2VwdGlvbikuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKHRocm93YWJsZVR5cGUpOworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICAgIFQgZXhjZXB0aW9uQ2F1c2UgPSAoVCkgZXhlY3V0aW9uRXhjZXB0aW9uLmdldENhdXNlKCk7CisgICAgcmV0dXJuIGV4Y2VwdGlvbkNhdXNlOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvRmFrZUZpbGVCYWNrZW5kLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvRmFrZUZpbGVCYWNrZW5kLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjU4MWM5YQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9GYWtlRmlsZUJhY2tlbmQuamF2YQpAQCAtMCwwICsxLDI4NCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZzsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5HY1BhcmFtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkxvY2tTY29wZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbC5Gb3J3YXJkaW5nT3V0cHV0U3RyZWFtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuRW51bU1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvdW50RG93bkxhdGNoOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uY29uY3VycmVudC5HdWFyZGVkQnk7CitpbXBvcnQgb3JnLmNoZWNrZXJmcmFtZXdvcmsuY2hlY2tlci5udWxsbmVzcy5xdWFsLk51bGxhYmxlOworCisvKiogQSBGYWtlIEJhY2tlbmQgZm9yIHRlc3RpbmcuIEl0IGFsbG93cyBvdmVycmlkaW5nIGNlcnRhaW4gYmVoYXZpb3IuICovCitwdWJsaWMgY2xhc3MgRmFrZUZpbGVCYWNrZW5kIGltcGxlbWVudHMgQmFja2VuZCB7CisgIHByaXZhdGUgZmluYWwgQmFja2VuZCBkZWxlZ2F0ZTsKKworICBAR3VhcmRlZEJ5KCJmYWlsdXJlTWFwIikKKyAgcHJpdmF0ZSBmaW5hbCBATnVsbGFibGUgTWFwPE9wZXJhdGlvblR5cGUsIElPRXhjZXB0aW9uPiBmYWlsdXJlTWFwID0KKyAgICAgIG5ldyBFbnVtTWFwPD4oT3BlcmF0aW9uVHlwZS5jbGFzcyk7CisKKyAgQEd1YXJkZWRCeSgic3VzcGVuc2lvbk1hcCIpCisgIHByaXZhdGUgZmluYWwgQE51bGxhYmxlIE1hcDxPcGVyYXRpb25UeXBlLCBDb3VudERvd25MYXRjaD4gc3VzcGVuc2lvbk1hcCA9CisgICAgICBuZXcgRW51bU1hcDw+KE9wZXJhdGlvblR5cGUuY2xhc3MpOworCisgIC8qKiBBdmFpbGFibGUgb3BlcmF0aW9uIHR5cGVzLiAqLworICBwdWJsaWMgZW51bSBPcGVyYXRpb25UeXBlIHsKKyAgICBBTEwsCisgICAgUkVBRCwgLy8gb3BlbkZvclJlYWQsIG9wZW5Gb3JOYXRpdmVSZWFkCisgICAgV1JJVEUsIC8vIG9wZW5Gb3JXcml0ZSwgb3BlbkZvckFwcGVuZAorICAgIFFVRVJZLCAvLyBleGlzdHMsIGlzRGlyZWN0b3J5LCBmaWxlU2l6ZSwgY2hpbGRyZW4sIGdldEdjUGFyYW0sIHRvRmlsZQorICAgIE1BTkFHRSwgLy8gZGVsZXRlLCByZW5hbWUsIGNyZWF0ZURpcmVjdG9yeSwgc2V0R2NQYXJhbQorICAgIFdSSVRFX1NUUkVBTSwgLy8gb3BlbkZvcldyaXRlL0FwcGVuZCByZXR1cm4gc3RyZWFtcyB0aGF0IGZhaWwKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGEge0BsaW5rIEZha2VGaWxlQmFja2VuZH0gdGhhdCBkZWxlZ2F0ZXMgdG8ge0BsaW5rIEphdmFGaWxlQmFja2VuZH0gKGZpbGU6Ly8gVVJJcykuIFVzZQorICAgKiB3aXRoIHtAbGluayBUZW1wb3JhcnlVcml9IHRvIGF2b2lkIGZpbGUgcGF0aCBjb2xsaXNpb25zLgorICAgKi8KKyAgcHVibGljIEZha2VGaWxlQmFja2VuZCgpIHsKKyAgICB0aGlzKG5ldyBKYXZhRmlsZUJhY2tlbmQoKSk7CisgIH0KKworICAvKiogQ3JlYXRlcyBhIHtAbGluayBGYWtlRmlsZUJhY2tlbmR9IHRoYXQgZGVsZWdhdGVzIHRvIHtAY29kZSBkZWxlZ2F0ZX0uICovCisgIHB1YmxpYyBGYWtlRmlsZUJhY2tlbmQoQmFja2VuZCBkZWxlZ2F0ZSkgeworICAgIHRoaXMuZGVsZWdhdGUgPSBkZWxlZ2F0ZTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHNldEZhaWx1cmUoT3BlcmF0aW9uVHlwZSB0eXBlLCBJT0V4Y2VwdGlvbiBleCkgeworICAgIHN5bmNocm9uaXplZCAoZmFpbHVyZU1hcCkgeworICAgICAgaWYgKHR5cGUgPT0gT3BlcmF0aW9uVHlwZS5BTEwpIHsKKyAgICAgICAgZm9yIChPcGVyYXRpb25UeXBlIHQgOiBPcGVyYXRpb25UeXBlLnZhbHVlcygpKSB7CisgICAgICAgICAgZmFpbHVyZU1hcC5wdXQodCwgZXgpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICBmYWlsdXJlTWFwLnB1dCh0eXBlLCBleCk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgY2xlYXJGYWlsdXJlKE9wZXJhdGlvblR5cGUgdHlwZSkgeworICAgIHN5bmNocm9uaXplZCAoZmFpbHVyZU1hcCkgeworICAgICAgaWYgKHR5cGUgPT0gT3BlcmF0aW9uVHlwZS5BTEwpIHsKKyAgICAgICAgZmFpbHVyZU1hcC5jbGVhcigpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgZmFpbHVyZU1hcC5yZW1vdmUodHlwZSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgc2V0U3VzcGVuc2lvbihPcGVyYXRpb25UeXBlIHR5cGUpIHsKKyAgICBzeW5jaHJvbml6ZWQgKHN1c3BlbnNpb25NYXApIHsKKyAgICAgIGlmICh0eXBlID09IE9wZXJhdGlvblR5cGUuQUxMKSB7CisgICAgICAgIGZvciAoT3BlcmF0aW9uVHlwZSB0IDogT3BlcmF0aW9uVHlwZS52YWx1ZXMoKSkgeworICAgICAgICAgIHN1c3BlbnNpb25NYXAucHV0KHQsIG5ldyBDb3VudERvd25MYXRjaCgxKSk7CisgICAgICAgIH0KKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHN1c3BlbnNpb25NYXAucHV0KHR5cGUsIG5ldyBDb3VudERvd25MYXRjaCgxKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgcHVibGljIHZvaWQgY2xlYXJTdXNwZW5zaW9uKE9wZXJhdGlvblR5cGUgdHlwZSkgeworICAgIHN5bmNocm9uaXplZCAoc3VzcGVuc2lvbk1hcCkgeworICAgICAgaWYgKHR5cGUgPT0gT3BlcmF0aW9uVHlwZS5BTEwpIHsKKyAgICAgICAgZm9yIChDb3VudERvd25MYXRjaCBsYXRjaCA6IHN1c3BlbnNpb25NYXAudmFsdWVzKCkpIHsKKyAgICAgICAgICBsYXRjaC5jb3VudERvd24oKTsKKyAgICAgICAgfQorICAgICAgICBzdXNwZW5zaW9uTWFwLmNsZWFyKCk7CisgICAgICB9IGVsc2UgaWYgKHN1c3BlbnNpb25NYXAuY29udGFpbnNLZXkodHlwZSkpIHsKKyAgICAgICAgc3VzcGVuc2lvbk1hcC5nZXQodHlwZSkuY291bnREb3duKCk7CisgICAgICAgIHN1c3BlbnNpb25NYXAucmVtb3ZlKHR5cGUpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCB0aHJvd0lmKE9wZXJhdGlvblR5cGUgdHlwZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBJT0V4Y2VwdGlvbiBpb0V4Y2VwdGlvbjsKKyAgICBzeW5jaHJvbml6ZWQgKGZhaWx1cmVNYXApIHsKKyAgICAgIGlvRXhjZXB0aW9uID0gZmFpbHVyZU1hcC5nZXQodHlwZSk7CisgICAgfQorICAgIGlmIChpb0V4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICB0aHJvdyBpb0V4Y2VwdGlvbjsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgc3VzcGVuZElmKE9wZXJhdGlvblR5cGUgdHlwZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBDb3VudERvd25MYXRjaCBsYXRjaDsKKyAgICBzeW5jaHJvbml6ZWQgKHN1c3BlbnNpb25NYXApIHsKKyAgICAgIGxhdGNoID0gc3VzcGVuc2lvbk1hcC5nZXQodHlwZSk7CisgICAgfQorICAgIGlmIChsYXRjaCAhPSBudWxsKSB7CisgICAgICB0cnkgeworICAgICAgICBsYXRjaC5hd2FpdCgpOworICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKAorICAgICAgICAgICAgIlRocmVhZCBpbnRlcnJ1cHRlZCB3aGlsZSBDb3VudERvd25MYXRjaCBmb3Igc3VzcGVuZGVkIG9wZXJhdGlvbiBpcyB3YWl0aW5nICIsIGV4KTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgdGhyb3dPclN1c3BlbmRJZihPcGVyYXRpb25UeXBlIHR5cGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhyb3dJZih0eXBlKTsKKyAgICBzdXNwZW5kSWYodHlwZSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgIHJldHVybiBkZWxlZ2F0ZS5uYW1lKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIG9wZW5Gb3JSZWFkKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhyb3dPclN1c3BlbmRJZihPcGVyYXRpb25UeXBlLlJFQUQpOworICAgIHJldHVybiBkZWxlZ2F0ZS5vcGVuRm9yUmVhZCh1cmkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBQYWlyPFVyaSwgQ2xvc2VhYmxlPiBvcGVuRm9yTmF0aXZlUmVhZChVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93T3JTdXNwZW5kSWYoT3BlcmF0aW9uVHlwZS5SRUFEKTsKKyAgICByZXR1cm4gZGVsZWdhdGUub3BlbkZvck5hdGl2ZVJlYWQodXJpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3V0cHV0U3RyZWFtIG9wZW5Gb3JXcml0ZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93T3JTdXNwZW5kSWYoT3BlcmF0aW9uVHlwZS5XUklURSk7CisgICAgT3V0cHV0U3RyZWFtIG91dCA9IGRlbGVnYXRlLm9wZW5Gb3JXcml0ZSh1cmkpOworICAgIElPRXhjZXB0aW9uIGlvRXhjZXB0aW9uOworICAgIHN5bmNocm9uaXplZCAoZmFpbHVyZU1hcCkgeworICAgICAgaW9FeGNlcHRpb24gPSBmYWlsdXJlTWFwLmdldChPcGVyYXRpb25UeXBlLldSSVRFX1NUUkVBTSk7CisgICAgfQorICAgIGlmIChpb0V4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICByZXR1cm4gbmV3IEZhaWxpbmdPdXRwdXRTdHJlYW0ob3V0LCBpb0V4Y2VwdGlvbik7CisgICAgfQorICAgIHJldHVybiBvdXQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE91dHB1dFN0cmVhbSBvcGVuRm9yQXBwZW5kKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhyb3dPclN1c3BlbmRJZihPcGVyYXRpb25UeXBlLldSSVRFKTsKKyAgICBPdXRwdXRTdHJlYW0gb3V0ID0gZGVsZWdhdGUub3BlbkZvckFwcGVuZCh1cmkpOworICAgIElPRXhjZXB0aW9uIGlvRXhjZXB0aW9uOworICAgIHN5bmNocm9uaXplZCAoZmFpbHVyZU1hcCkgeworICAgICAgaW9FeGNlcHRpb24gPSBmYWlsdXJlTWFwLmdldChPcGVyYXRpb25UeXBlLldSSVRFX1NUUkVBTSk7CisgICAgfQorICAgIGlmIChpb0V4Y2VwdGlvbiAhPSBudWxsKSB7CisgICAgICByZXR1cm4gbmV3IEZhaWxpbmdPdXRwdXRTdHJlYW0ob3V0LCBpb0V4Y2VwdGlvbik7CisgICAgfQorICAgIHJldHVybiBvdXQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgZGVsZXRlRmlsZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93T3JTdXNwZW5kSWYoT3BlcmF0aW9uVHlwZS5NQU5BR0UpOworICAgIGRlbGVnYXRlLmRlbGV0ZUZpbGUodXJpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBkZWxldGVEaXJlY3RvcnkoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aHJvd09yU3VzcGVuZElmKE9wZXJhdGlvblR5cGUuTUFOQUdFKTsKKyAgICBkZWxlZ2F0ZS5kZWxldGVEaXJlY3RvcnkodXJpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCByZW5hbWUoVXJpIGZyb20sIFVyaSB0bykgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aHJvd09yU3VzcGVuZElmKE9wZXJhdGlvblR5cGUuTUFOQUdFKTsKKyAgICBkZWxlZ2F0ZS5yZW5hbWUoZnJvbSwgdG8pOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGV4aXN0cyhVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93T3JTdXNwZW5kSWYoT3BlcmF0aW9uVHlwZS5RVUVSWSk7CisgICAgcmV0dXJuIGRlbGVnYXRlLmV4aXN0cyh1cmkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGlzRGlyZWN0b3J5KFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhyb3dPclN1c3BlbmRJZihPcGVyYXRpb25UeXBlLlFVRVJZKTsKKyAgICByZXR1cm4gZGVsZWdhdGUuaXNEaXJlY3RvcnkodXJpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBjcmVhdGVEaXJlY3RvcnkoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aHJvd09yU3VzcGVuZElmKE9wZXJhdGlvblR5cGUuTUFOQUdFKTsKKyAgICBkZWxlZ2F0ZS5jcmVhdGVEaXJlY3RvcnkodXJpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgbG9uZyBmaWxlU2l6ZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93T3JTdXNwZW5kSWYoT3BlcmF0aW9uVHlwZS5RVUVSWSk7CisgICAgcmV0dXJuIGRlbGVnYXRlLmZpbGVTaXplKHVyaSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEl0ZXJhYmxlPFVyaT4gY2hpbGRyZW4oVXJpIHBhcmVudFVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aHJvd09yU3VzcGVuZElmKE9wZXJhdGlvblR5cGUuUVVFUlkpOworICAgIHJldHVybiBkZWxlZ2F0ZS5jaGlsZHJlbihwYXJlbnRVcmkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBHY1BhcmFtIGdldEdjUGFyYW0oVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aHJvd09yU3VzcGVuZElmKE9wZXJhdGlvblR5cGUuUVVFUlkpOworICAgIHJldHVybiBkZWxlZ2F0ZS5nZXRHY1BhcmFtKHVyaSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgc2V0R2NQYXJhbShVcmkgdXJpLCBHY1BhcmFtIHBhcmFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93T3JTdXNwZW5kSWYoT3BlcmF0aW9uVHlwZS5NQU5BR0UpOworICAgIGRlbGVnYXRlLnNldEdjUGFyYW0odXJpLCBwYXJhbSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEZpbGUgdG9GaWxlKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhyb3dPclN1c3BlbmRJZihPcGVyYXRpb25UeXBlLlFVRVJZKTsKKyAgICByZXR1cm4gZGVsZWdhdGUudG9GaWxlKHVyaSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExvY2tTY29wZSBsb2NrU2NvcGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBkZWxlZ2F0ZS5sb2NrU2NvcGUoKTsKKyAgfQorCisgIHN0YXRpYyBjbGFzcyBGYWlsaW5nT3V0cHV0U3RyZWFtIGV4dGVuZHMgRm9yd2FyZGluZ091dHB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBmaW5hbCBJT0V4Y2VwdGlvbiBleGNlcHRpb247CisKKyAgICBGYWlsaW5nT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBkZWxlZ2F0ZSwgSU9FeGNlcHRpb24gZXhjZXB0aW9uKSB7CisgICAgICBzdXBlcihkZWxlZ2F0ZSk7CisgICAgICB0aGlzLmV4Y2VwdGlvbiA9IGV4Y2VwdGlvbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRocm93IGV4Y2VwdGlvbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRocm93IGV4Y2VwdGlvbjsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9GaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4MWRlNzAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlci5qYXZhCkBAIC0wLDAgKzEsMTg1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFdpdGhNZXNzYWdlOworCitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZDsKK2ltcG9ydCBhbmRyb2lkLm9zLlByb2Nlc3M7CitpbXBvcnQgYW5kcm9pZC5vcy5TeXN0ZW1DbG9jazsKK2ltcG9ydCBhbmRyb2lkLnN5c3RlbS5PczsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZU1hcDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0Lk1hcHM7CitpbXBvcnQgamF2YS5pby5CdWZmZXJlZFJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuTWV0aG9kUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5tb2RlbC5GcmFtZXdvcmtNZXRob2Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMubW9kZWwuU3RhdGVtZW50OworCisvKioKKyAqIFJ1bGUgdG8gZW5zdXJlIHRoYXQgdGVzdHMgZG8gbm90IGxlYWsgZmlsZSBkZXNjcmlwdG9ycy4gVGhpcyBkb2VzIG5vdCBjdXJyZW50bHkgd29yayB3aXRoCisgKiByb2JvbGVjdHJpYyB0ZXN0cyAoYi8xMjEzMjUwMTcpLgorICoKKyAqIDxwPlVzYWdlOiA8Y29kZT5AUnVsZSBGaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyIGxlYWtDaGVja2VyID0gbmV3IEZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXIoKTsKKyAqIDwvY29kZT4KKyAqLworcHVibGljIGNsYXNzIEZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXIgaW1wbGVtZW50cyBNZXRob2RSdWxlIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJGaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9GRFMgPSAxMDI0OworCisgIHByaXZhdGUgTGlzdDxTdHJpbmc+IHByb2Nlc3Nlc1RvTW9uaXRvciA9IG51bGw7CisgIHByaXZhdGUgTGlzdDxTdHJpbmc+IGZpbGVzVG9Nb25pdG9yID0gbnVsbDsKKyAgcHJpdmF0ZSBsb25nIG1zVG9XYWl0ID0gMDsKKworICAvKioKKyAgICogUHJvY2Vzc2VzIHdob3NlIEZEcyB0aGUgRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlciBuZWVkcyB0byBtb25pdG9yLgorICAgKgorICAgKiBAcGFyYW0gcHJvY2Vzc2VzVG9Nb25pdG9yIFRoZSBuYW1lcyBvZiB0aGUgcHJvY2Vzc2VzIHRvIG1vbml0b3IuCisgICAqLworICBwdWJsaWMgRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlciB3aXRoUHJvY2Vzc2VzVG9Nb25pdG9yKExpc3Q8U3RyaW5nPiBwcm9jZXNzZXNUb01vbml0b3IpIHsKKyAgICB0aGlzLnByb2Nlc3Nlc1RvTW9uaXRvciA9IHByb2Nlc3Nlc1RvTW9uaXRvcjsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHB1YmxpYyBGaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyIHdpdGhGaWxlc1RvTW9uaXRvcihMaXN0PFN0cmluZz4gZmlsZXNUb01vbml0b3IpIHsKKyAgICB0aGlzLmZpbGVzVG9Nb25pdG9yID0gZmlsZXNUb01vbml0b3I7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICAvKioKKyAgICogSWYgdGhlIGZpbGVzIGFyZSBjbG9zZWQgYXN5bmNocm9ub3VzbHksIHRoZSBldmFsdWF0aW9uIGNvdWxkIGZhaWwuIFRoaXMgb3B0aW9uIGFsbG93cyB0bworICAgKiBwZXJmb3JtIHRoZSBldmFsdWF0aW9uIG9uZSBtb3JlIHRpbWUuCisgICAqCisgICAqIEBwYXJhbSBtc1RvV2FpdCBNaWxsaXNlY29uZHMgdGhlIEZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXIgbmVlZHMgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcuCisgICAqLworICBwdWJsaWMgRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlciB3aXRoV2FpdElmRmFpbHMobG9uZyBtc1RvV2FpdCkgeworICAgIHRoaXMubXNUb1dhaXQgPSBtc1RvV2FpdDsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHByaXZhdGUgSW1tdXRhYmxlTWFwPFN0cmluZywgSW50ZWdlcj4gZ2VuZXJhdGVNYXAoTGlzdDxJbnRlZ2VyPiBwaWRzKSB7CisgICAgSW1tdXRhYmxlTWFwLkJ1aWxkZXI8U3RyaW5nLCBJbnRlZ2VyPiBuYW1lcyA9IEltbXV0YWJsZU1hcC5idWlsZGVyKCk7CisgICAgZm9yIChpbnQgcGlkIDogcGlkcykgeworICAgICAgU3RyaW5nIGZkRGlyID0gIi9wcm9jLyIgKyBwaWQgKyAiL2ZkLyI7CisgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE1BWF9GRFM7IGkrKykgeworICAgICAgICB0cnkgeworICAgICAgICAgIEZpbGUgZmRGaWxlID0gbmV3IEZpbGUoZmREaXIgKyBpKTsKKyAgICAgICAgICBpZiAoIWZkRmlsZS5leGlzdHMoKSkgeworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgfQorICAgICAgICAgIFN0cmluZyBmaWxlUGF0aDsKKyAgICAgICAgICBpZiAoQnVpbGQuVkVSU0lPTi5TREtfSU5UID49IEJ1aWxkLlZFUlNJT05fQ09ERVMuTE9MTElQT1ApIHsKKyAgICAgICAgICAgIC8vIERpcmVjdGx5IHJlYWRpbmcgdGhlIHN5bWxpbmsgYWxsb3dzIHVzIHRvIHNlZSBzcGVjaWFsIGZpbGVzIChlLmcuLCBwaXBlcyksCisgICAgICAgICAgICAvLyB3aGljaCBhcmUgc2FuaXRpemVkIGJ5IGdldENhbm9uaWNhbFBhdGgoKQorICAgICAgICAgICAgZmlsZVBhdGggPSBPcy5yZWFkbGluayhmZEZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaWxlUGF0aCA9IGZkRmlsZS5nZXRDYW5vbmljYWxQYXRoKCk7CisgICAgICAgICAgfQorICAgICAgICAgIFN0cmluZyBrZXkgPSBmZEZpbGUgKyAiPSIgKyBmaWxlUGF0aDsKKyAgICAgICAgICBuYW1lcy5wdXQoa2V5LCBwaWQpOworICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgIExvZy53KFRBRywgaSArICIgLT4gIiArIGUpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBuYW1lcy5idWlsZE9yVGhyb3coKTsKKyAgfQorCisgIHByaXZhdGUgSW1tdXRhYmxlTGlzdDxJbnRlZ2VyPiBnZXRQcm9jZXNzSWRzKCkgeworICAgIGlmIChwcm9jZXNzZXNUb01vbml0b3IgPT0gbnVsbCkgeworICAgICAgaW50IG15UGlkID0gUHJvY2Vzcy5teVBpZCgpOworICAgICAgYXNzZXJ0V2l0aE1lc3NhZ2UoIk15IHByb2Nlc3MgSUQgdW5hdmFpbGFibGUgLSBhcmUgeW91IHVzaW5nIHJvYm9sZWN0cmljPyBiLzEyMTMyNTAxNyIpCisgICAgICAgICAgLnRoYXQobXlQaWQpCisgICAgICAgICAgLmlzR3JlYXRlclRoYW4oMCk7CisgICAgICByZXR1cm4gSW1tdXRhYmxlTGlzdC5vZihteVBpZCk7CisgICAgfQorICAgIEltbXV0YWJsZUxpc3QuQnVpbGRlcjxJbnRlZ2VyPiBwaWRzID0gSW1tdXRhYmxlTGlzdC5idWlsZGVyKCk7CisgICAgdHJ5IHsKKyAgICAgIFN0cmluZyBsaW5lOworICAgICAgamF2YS5sYW5nLlByb2Nlc3MgcCA9IFJ1bnRpbWUuZ2V0UnVudGltZSgpLmV4ZWMoInBzIik7CisgICAgICBCdWZmZXJlZFJlYWRlciBpbnB1dCA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIocC5nZXRJbnB1dFN0cmVhbSgpKSk7CisgICAgICB3aGlsZSAoKGxpbmUgPSBpbnB1dC5yZWFkTGluZSgpKSAhPSBudWxsKSB7CisgICAgICAgIGZvciAoU3RyaW5nIG5hbWUgOiBwcm9jZXNzZXNUb01vbml0b3IpIHsKKyAgICAgICAgICBpZiAobGluZS5lbmRzV2l0aChuYW1lKSkgeworICAgICAgICAgICAgcGlkcy5hZGQoSW50ZWdlci5wYXJzZUludChsaW5lLnNwbGl0KCJbIFx0XSsiLCAtMSlbMV0pKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgICAgaW5wdXQuY2xvc2UoKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMb2cuZShUQUcsIGUuZ2V0TWVzc2FnZSgpKTsKKyAgICB9CisgICAgcmV0dXJuIHBpZHMuYnVpbGQoKTsKKyAgfQorCisgIHByaXZhdGUgaW50IGZpbGVzVG9Nb25pdG9yQnV0T3BlbihTZXQ8U3RyaW5nPiBvcGVuRmlsZXNBZnRlcikgeworICAgIGludCByZXMgPSAwOworICAgIGZvciAoU3RyaW5nIGZpbGUgOiBmaWxlc1RvTW9uaXRvcikgeworICAgICAgcmVzID0gb3BlbkZpbGVzQWZ0ZXIuY29udGFpbnMoZmlsZSkgPyByZXMgKyAxIDogcmVzOworICAgIH0KKyAgICByZXR1cm4gcmVzOworICB9CisKKyAgcHJpdmF0ZSBpbnQgbnVtYmVyT2ZJbnRlcmVzdGluZ09wZW5GaWxlcyhNYXA8U3RyaW5nLCBJbnRlZ2VyPiBkaWZmTWFwKSB7CisgICAgU2V0PFN0cmluZz4gbmV3T3BlbkZpbGVzID0gZGlmZk1hcC5rZXlTZXQoKTsKKyAgICByZXR1cm4gZmlsZXNUb01vbml0b3IgPT0gbnVsbCA/IG5ld09wZW5GaWxlcy5zaXplKCkgOiBmaWxlc1RvTW9uaXRvckJ1dE9wZW4obmV3T3BlbkZpbGVzKTsKKyAgfQorCisgIHByaXZhdGUgTWFwPFN0cmluZywgSW50ZWdlcj4gZGlmZmVyZW5jZSgKKyAgICAgIEltbXV0YWJsZU1hcDxTdHJpbmcsIEludGVnZXI+IGJlZm9yZSwgSW1tdXRhYmxlTWFwPFN0cmluZywgSW50ZWdlcj4gYWZ0ZXIpIHsKKyAgICByZXR1cm4gTWFwcy5kaWZmZXJlbmNlKGJlZm9yZSwgYWZ0ZXIpLmVudHJpZXNPbmx5T25SaWdodCgpOworICB9CisKKyAgcHJpdmF0ZSBTdHJpbmcgYnVpbGRNZXNzYWdlKE1hcDxTdHJpbmcsIEludGVnZXI+IG9wZW5GaWxlcykgeworICAgIFN0cmluZ0J1aWxkZXIgYnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgYnVpbGRlci5hcHBlbmQoIllvdXIgdGVzdCBpcyBsZWFraW5nIGZpbGUgZGVzY3JpcHRvcnMhXG4iKTsKKyAgICBmb3IgKFN0cmluZyBrZXkgOiBvcGVuRmlsZXMua2V5U2V0KCkpIHsKKyAgICAgIGJ1aWxkZXIuYXBwZW5kKFN0cmluZy5mb3JtYXQoIiVzIGlzIHN0aWxsIG9wZW4gaW4gcHJvY2VzcyAlZFxuIiwga2V5LCBvcGVuRmlsZXMuZ2V0KGtleSkpKTsKKyAgICB9CisgICAgYnVpbGRlci5hcHBlbmQoJ1xuJyk7CisgICAgcmV0dXJuIGJ1aWxkZXIudG9TdHJpbmcoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RhdGVtZW50IGFwcGx5KFN0YXRlbWVudCBiYXNlLCBGcmFtZXdvcmtNZXRob2QgbWV0aG9kLCBPYmplY3QgdGFyZ2V0KSB7CisgICAgcmV0dXJuIG5ldyBTdGF0ZW1lbnQoKSB7CisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIGV2YWx1YXRlKCkgdGhyb3dzIFRocm93YWJsZSB7CisgICAgICAgIEltbXV0YWJsZUxpc3Q8SW50ZWdlcj4gcGlkcyA9IGdldFByb2Nlc3NJZHMoKTsKKyAgICAgICAgSW1tdXRhYmxlTWFwPFN0cmluZywgSW50ZWdlcj4gYmVmb3JlTWFwID0gZ2VuZXJhdGVNYXAocGlkcyk7CisKKyAgICAgICAgYmFzZS5ldmFsdWF0ZSgpOworCisgICAgICAgIE1hcDxTdHJpbmcsIEludGVnZXI+IGRpZmZNYXAgPSBkaWZmZXJlbmNlKGJlZm9yZU1hcCwgZ2VuZXJhdGVNYXAocGlkcykpOworICAgICAgICBpbnQgZGlmZiA9IG51bWJlck9mSW50ZXJlc3RpbmdPcGVuRmlsZXMoZGlmZk1hcCk7CisgICAgICAgIGlmIChkaWZmID4gMCAmJiBtc1RvV2FpdCA+IDApIHsKKyAgICAgICAgICBTeXN0ZW1DbG9jay5zbGVlcChtc1RvV2FpdCk7CisgICAgICAgICAgZGlmZk1hcCA9IGRpZmZlcmVuY2UoYmVmb3JlTWFwLCBnZW5lcmF0ZU1hcChwaWRzKSk7CisgICAgICAgICAgZGlmZiA9IG51bWJlck9mSW50ZXJlc3RpbmdPcGVuRmlsZXMoZGlmZk1hcCk7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0V2l0aE1lc3NhZ2UoYnVpbGRNZXNzYWdlKGRpZmZNYXApKS50aGF0KGRpZmYpLmlzRXF1YWxUbygwKTsKKyAgICAgIH0KKyAgICB9OworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvRmlsZVN0b3JhZ2VUZXN0QmFzZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0ZpbGVTdG9yYWdlVGVzdEJhc2UuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42OGFhMjUxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0ZpbGVTdG9yYWdlVGVzdEJhc2UuamF2YQpAQCAtMCwwICsxLDE0MyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZzsKKworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5BZGRpdGlvbmFsQW5zd2Vycy5yZXR1cm5zU2Vjb25kQXJnOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by53aGVuOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5UcmFuc2Zvcm07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcubW9ja2l0by5Nb2NrOworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9KVW5pdDsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvUnVsZTsKKworLyoqCisgKiBCYXNlIGNsYXNzIHdpdGggY29tbW9uIGNvZGUgZm9yIGZpbGUgc3RvcmFnZSB0ZXN0cy4KKyAqCisgKiA8cD5Nb2NrcyB1c2UgImZpbGUiLCAiY25zIiwgImNvbXByZXNzIiBhbmQgImVuY3J5cHQiIHRvIG1ha2UgdGhlIHRlc3RzIGVhc2llciB0byBmb2xsb3csIGJ1dCB0aGV5CisgKiBkbyBub3QgaW1wbGVtZW50IGFueSBvZiBzYWlkIGJlaGF2aW9ycy4KKyAqLworcHVibGljIGFic3RyYWN0IGNsYXNzIEZpbGVTdG9yYWdlVGVzdEJhc2UgeworCisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NraXRvID0gTW9ja2l0b0pVbml0LnJ1bGUoKTsKKworICBwcm90ZWN0ZWQgZmluYWwgVXJpIGZpbGUxVXJpOworICBwcm90ZWN0ZWQgZmluYWwgVXJpIGZpbGUyVXJpOworICBwcm90ZWN0ZWQgZmluYWwgVXJpIGZpbGUzVXJpOworICBwcm90ZWN0ZWQgZmluYWwgVXJpIGRpcjFVcmk7CisgIHByb3RlY3RlZCBmaW5hbCBTdHJpbmcgZmlsZTFGaWxlbmFtZTsKKyAgcHJvdGVjdGVkIGZpbmFsIFN0cmluZyBmaWxlMkZpbGVuYW1lOworICBwcm90ZWN0ZWQgZmluYWwgVXJpIGNuc1VyaTsKKyAgcHJvdGVjdGVkIGZpbmFsIFVyaSBmaWxlMUNvbXByZXNzVXJpOworICBwcm90ZWN0ZWQgZmluYWwgVXJpIGZpbGUxQ29tcHJlc3NVcmlXaXRoRW5jb2RlZDsKKyAgcHJvdGVjdGVkIGZpbmFsIFVyaSBmaWxlMkNvbXByZXNzRW5jcnlwdFVyaTsKKyAgcHJvdGVjdGVkIGZpbmFsIFVyaSBmaWxlM0lkZW50aXR5VXJpOworICBwcm90ZWN0ZWQgZmluYWwgVXJpIGRpcjJDb21wcmVzc1VyaTsKKyAgcHJvdGVjdGVkIGZpbmFsIFVyaSB1cmlXaXRoQ29tcHJlc3NQYXJhbTsKKyAgcHJvdGVjdGVkIGZpbmFsIFVyaSB1cmlXaXRoQ29tcHJlc3NQYXJhbVdpdGhFbmNvZGVkOworICBwcm90ZWN0ZWQgZmluYWwgVXJpIHVyaVdpdGhFbmNyeXB0UGFyYW07CisgIHByb3RlY3RlZCBmaW5hbCBVcmkgdXJpV2l0aElkZW50aXR5UGFyYW07CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW5wdXRTdHJlYW0gRU1QVFlfSU5QVVQgPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0obmV3IGJ5dGVbXSB7fSk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIE91dHB1dFN0cmVhbSBOVUxMX09VVFBVVCA9CisgICAgICBuZXcgT3V0cHV0U3RyZWFtKCkgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgLy8gaWdub3JlCisgICAgICAgIH0KKyAgICAgIH07CisKKyAgQE1vY2sgcHJvdGVjdGVkIEJhY2tlbmQgZmlsZUJhY2tlbmQ7CisgIEBNb2NrIHByb3RlY3RlZCBCYWNrZW5kIGNuc0JhY2tlbmQ7CisgIEBNb2NrIHByb3RlY3RlZCBUcmFuc2Zvcm0gY29tcHJlc3NUcmFuc2Zvcm07CisgIEBNb2NrIHByb3RlY3RlZCBUcmFuc2Zvcm0gZW5jcnlwdFRyYW5zZm9ybTsKKyAgQE1vY2sgcHJvdGVjdGVkIE1vbml0b3IgY291bnRpbmdNb25pdG9yOworCisgIHByb3RlY3RlZCBJbnB1dFN0cmVhbSBjb21wcmVzc0lucHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlW10ge30pOworICBwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZW5jcnlwdElucHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKG5ldyBieXRlW10ge30pOworICBwcm90ZWN0ZWQgT3V0cHV0U3RyZWFtIGNvbXByZXNzT3V0cHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICBwcm90ZWN0ZWQgT3V0cHV0U3RyZWFtIGVuY3J5cHRPdXRwdXRTdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgIHByb3RlY3RlZCBDbG9zZWFibGUgY2xvc2VhYmxlID0gKCkgLT4ge307CisKKyAgcHJvdGVjdGVkIGZpbmFsIFRyYW5zZm9ybSBpZGVudGl0eVRyYW5zZm9ybSA9CisgICAgICBuZXcgVHJhbnNmb3JtKCkgeworICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgICAgICAgIHJldHVybiAiaWRlbnRpdHkiOworICAgICAgICB9CisgICAgICB9OworCisgIHByb3RlY3RlZCBGaWxlU3RvcmFnZVRlc3RCYXNlKCkgeworICAgIC8vIFJvYm9sZWN0cmljIGRvZXNuJ3Qgc2VlbSB0byB3b3JrIHdpdGggc3RhdGljIGluaXRpYWxpemVycy4KKyAgICBmaWxlMVVyaSA9IFVyaS5wYXJzZSgiZmlsZTovLy9maWxlMSIpOworICAgIGZpbGUyVXJpID0gVXJpLnBhcnNlKCJmaWxlOi8vL2ZpbGUyIik7CisgICAgZmlsZTNVcmkgPSBVcmkucGFyc2UoImZpbGU6Ly8vZmlsZTMiKTsKKyAgICBkaXIxVXJpID0gVXJpLnBhcnNlKCJmaWxlOi8vL2RpcjEvIik7CisgICAgZmlsZTFGaWxlbmFtZSA9ICJmaWxlMSI7CisgICAgZmlsZTJGaWxlbmFtZSA9ICJmaWxlMiI7CisgICAgY25zVXJpID0gVXJpLnBhcnNlKCJjbnM6Ly8vMSIpOworICAgIGZpbGUxQ29tcHJlc3NVcmkgPSBVcmkucGFyc2UoImZpbGU6Ly8vZmlsZTEjdHJhbnNmb3JtPWNvbXByZXNzIik7CisgICAgLy8gUGVyY2VudCBlbmNvZGluZyBvZiBmcmFnbWVudCBwYXJhbXMgaXMgbm90IGluIG91ciBzcGVjICg8aW50ZXJuYWw+KSwgYnV0CisgICAgLy8gaW1wbGVtZW50ZWQgYW55d2F5LgorICAgIGZpbGUxQ29tcHJlc3NVcmlXaXRoRW5jb2RlZCA9IFVyaS5wYXJzZSgiZmlsZTovLy9maWxlMSN0cmFuc2Zvcm09Y29tcHJlc3MoayUzRD0lMjh2JTI5KSIpOworICAgIGZpbGUyQ29tcHJlc3NFbmNyeXB0VXJpID0gVXJpLnBhcnNlKCJmaWxlOi8vL2ZpbGUyI3RyYW5zZm9ybT1jb21wcmVzcytlbmNyeXB0Iik7CisgICAgZmlsZTNJZGVudGl0eVVyaSA9IFVyaS5wYXJzZSgiZmlsZTovLy9maWxlMyN0cmFuc2Zvcm09aWRlbnRpdHkiKTsKKyAgICBkaXIyQ29tcHJlc3NVcmkgPSBVcmkucGFyc2UoImZpbGU6Ly8vZGlyMi8jdHJhbnNmb3JtPWNvbXByZXNzIik7CisgICAgdXJpV2l0aENvbXByZXNzUGFyYW0gPSBVcmkucGFyc2UoIiN0cmFuc2Zvcm09Y29tcHJlc3MiKTsKKyAgICB1cmlXaXRoQ29tcHJlc3NQYXJhbVdpdGhFbmNvZGVkID0gVXJpLnBhcnNlKCIjdHJhbnNmb3JtPWNvbXByZXNzKGslM0Q9JTI4diUyOSkiKTsKKyAgICB1cmlXaXRoRW5jcnlwdFBhcmFtID0gVXJpLnBhcnNlKCIjdHJhbnNmb3JtPWVuY3J5cHQiKTsKKyAgICB1cmlXaXRoSWRlbnRpdHlQYXJhbSA9IFVyaS5wYXJzZSgiI3RyYW5zZm9ybT1pZGVudGl0eSIpOworICB9CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBpbml0TW9ja3NBbmRDcmVhdGVGaWxlU3RvcmFnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHdoZW4oZmlsZUJhY2tlbmQubmFtZSgpKS50aGVuUmV0dXJuKCJmaWxlIik7CisgICAgd2hlbihmaWxlQmFja2VuZC5vcGVuRm9yUmVhZChhbnkoKSkpLnRoZW5SZXR1cm4oRU1QVFlfSU5QVVQpOworICAgIHdoZW4oZmlsZUJhY2tlbmQub3BlbkZvcldyaXRlKGFueSgpKSkudGhlblJldHVybihOVUxMX09VVFBVVCk7CisgICAgd2hlbihmaWxlQmFja2VuZC5vcGVuRm9yQXBwZW5kKGFueSgpKSkudGhlblJldHVybihOVUxMX09VVFBVVCk7CisgICAgd2hlbihjbnNCYWNrZW5kLm9wZW5Gb3JSZWFkKGFueSgpKSkudGhlblJldHVybihFTVBUWV9JTlBVVCk7CisgICAgd2hlbihjbnNCYWNrZW5kLm9wZW5Gb3JXcml0ZShhbnkoKSkpLnRoZW5SZXR1cm4oTlVMTF9PVVRQVVQpOworICAgIHdoZW4oY25zQmFja2VuZC5vcGVuRm9yQXBwZW5kKGFueSgpKSkudGhlblJldHVybihOVUxMX09VVFBVVCk7CisgICAgd2hlbihjbnNCYWNrZW5kLm5hbWUoKSkudGhlblJldHVybigiY25zIik7CisgICAgd2hlbihjb21wcmVzc1RyYW5zZm9ybS5uYW1lKCkpLnRoZW5SZXR1cm4oImNvbXByZXNzIik7CisgICAgd2hlbihjb21wcmVzc1RyYW5zZm9ybS5lbmNvZGUoYW55KCksIGFueSgpKSkudGhlbihyZXR1cm5zU2Vjb25kQXJnKCkpOworICAgIHdoZW4oY29tcHJlc3NUcmFuc2Zvcm0uZGVjb2RlKGFueSgpLCBhbnkoKSkpLnRoZW4ocmV0dXJuc1NlY29uZEFyZygpKTsKKyAgICB3aGVuKGVuY3J5cHRUcmFuc2Zvcm0ubmFtZSgpKS50aGVuUmV0dXJuKCJlbmNyeXB0Iik7CisgICAgd2hlbihlbmNyeXB0VHJhbnNmb3JtLmVuY29kZShhbnkoKSwgYW55KCkpKS50aGVuKHJldHVybnNTZWNvbmRBcmcoKSk7CisgICAgd2hlbihlbmNyeXB0VHJhbnNmb3JtLmRlY29kZShhbnkoKSwgYW55KCkpKS50aGVuKHJldHVybnNTZWNvbmRBcmcoKSk7CisgICAgd2hlbihmaWxlQmFja2VuZC5vcGVuRm9yTmF0aXZlUmVhZChhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKFBhaXIuY3JlYXRlKFVyaS5wYXJzZSgiZmQ6MTIzIiksIGNsb3NlYWJsZSkpOworICAgIHdoZW4oY25zQmFja2VuZC5vcGVuRm9yTmF0aXZlUmVhZChhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKFBhaXIuY3JlYXRlKFVyaS5wYXJzZSgiZmQ6NDU2IiksIGNsb3NlYWJsZSkpOworICAgIGluaXRTdG9yYWdlKCk7CisgIH0KKworICAvLyBDYWxsZWQgYWZ0ZXIgbW9ja3MgYXJlIGluaXRpYWxpemVkIHRvIGNyZWF0ZSB0aGUgRmlsZVN0b3JhZ2UgaW5zdGFuY2UuCisgIC8vIFJlcXVpcmVkIGIvYyBvcmRlciBvZiBAQmVmb3JlcyBpcyBub24tZGV0ZXJtaW5pc3RpYy4KKyAgcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgaW5pdFN0b3JhZ2UoKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9GcmFnbWVudFBhcmFtTWF0Y2hlcnMuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9GcmFnbWVudFBhcmFtTWF0Y2hlcnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zODA4MDYzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0ZyYWdtZW50UGFyYW1NYXRjaGVycy5qYXZhCkBAIC0wLDAgKzEsNTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3Rpbmc7CisKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hcmdUaGF0OworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLkxpdGVUcmFuc2Zvcm1GcmFnbWVudHM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcjsKKworLyoqIE1hdGNoZXJzIGZvciBGcmFnbWVudCBQYXJhbXMuICovCitwdWJsaWMgZmluYWwgY2xhc3MgRnJhZ21lbnRQYXJhbU1hdGNoZXJzIHsKKworICAvKiogTWF0Y2hlciBmb3Ige0BsaW5rIEZyYWdtZW50LlBhcmFtVmFsdWV9cy4gKi8KKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgUGFyYW1WYWx1ZU1hdGNoZXIgaW1wbGVtZW50cyBBcmd1bWVudE1hdGNoZXI8VXJpPiB7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZXhwZWN0ZWRTcGVjOworCisgICAgUGFyYW1WYWx1ZU1hdGNoZXIoVXJpIGV4cGVjdGVkKSB7CisgICAgICBJbW11dGFibGVMaXN0PFN0cmluZz4gc3BlY3MgPSBMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLnBhcnNlVHJhbnNmb3JtU3BlY3MoZXhwZWN0ZWQpOworICAgICAgaWYgKHNwZWNzLnNpemUoKSAhPSAxKSB7CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlNob3VsZCBoYXZlIG9ubHkgb25lIHNwZWM6ICIgKyBleHBlY3RlZCk7CisgICAgICB9CisgICAgICB0aGlzLmV4cGVjdGVkU3BlYyA9IHNwZWNzLmdldCgwKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgYm9vbGVhbiBtYXRjaGVzKFVyaSBvdGhlcikgeworICAgICAgVXJpIG90aGVyVXJpID0gKFVyaSkgb3RoZXI7CisgICAgICBJbW11dGFibGVMaXN0PFN0cmluZz4gb3RoZXJTcGVjcyA9IExpdGVUcmFuc2Zvcm1GcmFnbWVudHMucGFyc2VUcmFuc2Zvcm1TcGVjcyhvdGhlclVyaSk7CisgICAgICBmb3IgKFN0cmluZyBvdGhlclNwZWMgOiBvdGhlclNwZWNzKSB7CisgICAgICAgIGlmIChleHBlY3RlZFNwZWMuZXF1YWxzKG90aGVyU3BlYykpIHsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgVXJpIGVxUGFyYW0oVXJpIGV4cGVjdGVkKSB7CisgICAgcmV0dXJuIGFyZ1RoYXQobmV3IFBhcmFtVmFsdWVNYXRjaGVyKGV4cGVjdGVkKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9Ob09wTW9uaXRvci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL05vT3BNb25pdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjg0ZTQxYQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9Ob09wTW9uaXRvci5qYXZhCkBAIC0wLDAgKzEsMzggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3Rpbmc7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuTW9uaXRvcjsKKworLyoqIEEgbW9uaXRvciB0aGF0IGRvZXNuJ3QgbW9uaXRvciBhbnkgSU8gKGkuZS4gYWx3YXlzIHJldHVybnMgbnVsbCkuICovCitwdWJsaWMgZmluYWwgY2xhc3MgTm9PcE1vbml0b3IgaW1wbGVtZW50cyBNb25pdG9yIHsKKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE1vbml0b3IuSW5wdXRNb25pdG9yIG1vbml0b3JSZWFkKFVyaSB1bnVzZWRVcmkpIHsKKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTW9uaXRvci5PdXRwdXRNb25pdG9yIG1vbml0b3JXcml0ZShVcmkgdW51c2VkVXJpKSB7CisgICAgcmV0dXJuIG51bGw7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE1vbml0b3IuT3V0cHV0TW9uaXRvciBtb25pdG9yQXBwZW5kKFVyaSB1bnVzZWRVcmkpIHsKKyAgICByZXR1cm4gbnVsbDsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL1NoYWRvd1V0aWxzLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvU2hhZG93VXRpbHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MWYxNjU1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL1NoYWRvd1V0aWxzLmphdmEKQEAgLTAsMCArMSwxNzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3Rpbmc7CisKK2ltcG9ydCBzdGF0aWMgb3JnLnJvYm9sZWN0cmljLnNoYWRvdy5hcGkuU2hhZG93LmRpcmVjdGx5T247CisKK2ltcG9ydCBhbmRyb2lkLmFwcC5BcHBsaWNhdGlvbjsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkOworaW1wb3J0IGFuZHJvaWQub3MuRW52aXJvbm1lbnQ7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLmFubm90YXRpb24uSW1wbGVtZW50YXRpb247CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLmFubm90YXRpb24uSW1wbGVtZW50czsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuYW5ub3RhdGlvbi5SZWFsT2JqZWN0OworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5zaGFkb3cuYXBpLlNoYWRvdzsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuc2hhZG93cy5TaGFkb3dTdGF0RnM7CisKKy8qKiBDb21tb24gaGVscGVyIHV0aWxpdGllcyB0aGF0IGV4dGVuZCB0aGUgUm9ib2xlY3RyaWMgU2hhZG93IEFQSS4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTaGFkb3dVdGlscyB7CisKKyAgLyoqCisgICAqIEFkZHMgYW4gZXh0ZXJuYWwgZGlyIHRvIHRoZSBSb2JvbGVjdHJpYyB7QGNvZGUgRW52aXJvbm1lbnR9IGFuZCB7QGNvZGUgQ29udGV4dH0uIEluIG9yZGVyIHRvCisgICAqIHVzZSB0aGlzIG1ldGhvZCwgdGhlIHRlc3QgY2xhc3MgbXVzdCBiZSBjb25maWd1cmVkIHRvIHVzZSB0aGUgY3VzdG9tIHtAbGluayBTaGFkb3dDb250ZXh0SW1wbH0KKyAgICogYW5kIHtAbGluayBTaGFkb3dFbnZpcm9ubWVudH0uCisgICAqLworICBwdWJsaWMgc3RhdGljIEZpbGUgYWRkRXh0ZXJuYWxEaXIoU3RyaW5nIHBhdGgsIGJvb2xlYW4gaXNFbXVsYXRlZCwgYm9vbGVhbiBpc01vdW50ZWQpIHsKKyAgICBGaWxlIGRpciA9IFNoYWRvd0Vudmlyb25tZW50LmFkZEV4dGVybmFsRGlyKHBhdGgpOworICAgIFN0cmluZyBzdG9yYWdlU3RhdGUgPSBpc01vdW50ZWQgPyBFbnZpcm9ubWVudC5NRURJQV9NT1VOVEVEIDogRW52aXJvbm1lbnQuTUVESUFfUkVNT1ZFRDsKKworICAgIFNoYWRvd0Vudmlyb25tZW50LnNldEV4dGVybmFsU3RvcmFnZUVtdWxhdGVkKGRpciwgaXNFbXVsYXRlZCk7CisgICAgU2hhZG93RW52aXJvbm1lbnQuc2V0RXh0ZXJuYWxTdG9yYWdlU3RhdGUoZGlyLCBzdG9yYWdlU3RhdGUpOworCisgICAgLy8gVGhlIHNoYWRvdyBpbXBsZW1lbnRhdGlvbiBvZiBMT0xMSVBPUCBzdG9yYWdlIEFQSXMgZG9lc24ndCBmdWxseSBoYW5kbGUgc3ViZGlyZWN0b3JpZXMsIHNvCisgICAgLy8gdGhlIGJlc3Qgd2UgY2FuIGRvIGlzIHRvIHNldCB0aGUgc2FtZSBzdG9yYWdlIHByb3BlcnRpZXMgb24gZWFjaCBkaXJlY3Rvcnkgd2UncmUgYWRkaW5nLgorICAgIFNoYWRvd0NvbnRleHRJbXBsIHNoYWRvdyA9CisgICAgICAgIFNoYWRvdy5leHRyYWN0KAorICAgICAgICAgICAgKChBcHBsaWNhdGlvbikgQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKSkuZ2V0QmFzZUNvbnRleHQoKSk7CisgICAgTGlzdDxGaWxlPiBwYWNrYWdlRGlycyA9IHNoYWRvdy5hZGRFeHRlcm5hbFBhY2thZ2VEaXJzKGRpcik7CisgICAgZm9yIChGaWxlIHBhY2thZ2VEaXIgOiBwYWNrYWdlRGlycykgeworICAgICAgU2hhZG93RW52aXJvbm1lbnQuc2V0RXh0ZXJuYWxTdG9yYWdlRW11bGF0ZWQocGFja2FnZURpciwgaXNFbXVsYXRlZCk7CisgICAgICBTaGFkb3dFbnZpcm9ubWVudC5zZXRFeHRlcm5hbFN0b3JhZ2VTdGF0ZShwYWNrYWdlRGlyLCBzdG9yYWdlU3RhdGUpOworICAgIH0KKworICAgIC8vIENvbmZpZ3VyZSBwcmltYXJ5IHN0b3JhZ2UgQVBJcyBpZiB0aGlzIGlzIHRoZSBmaXJzdCBleHRlcm5hbCBkaXIKKyAgICBpZiAoc2hhZG93LmdldEV4dGVybmFsRmlsZXNEaXJzKG51bGwpLmxlbmd0aCA9PSAxKSB7CisgICAgICBTaGFkb3dFbnZpcm9ubWVudC5zZXRFeHRlcm5hbFN0b3JhZ2VEaXJlY3RvcnkoZGlyKTsKKyAgICAgIFNoYWRvd0Vudmlyb25tZW50LnNldElzRXh0ZXJuYWxTdG9yYWdlRW11bGF0ZWQoaXNFbXVsYXRlZCk7CisgICAgICBTaGFkb3dFbnZpcm9ubWVudC5zZXRFeHRlcm5hbFN0b3JhZ2VTdGF0ZShzdG9yYWdlU3RhdGUpOworICAgIH0KKworICAgIHJldHVybiBkaXI7CisgIH0KKworICAvKioKKyAgICogQ29uZmlndXJlcyB0aGUgaW5mb3JtYXRpb24gcmV0dXJuZWQgYnkgdGhlIFJvYm9sZWN0cmljIHtAY29kZSBTdGF0c0ZzfS4KKyAgICoKKyAgICogQHBhcmFtIGRpciBUaGUgZmlsZSB1bmRlciB3aGljaCB7QGNvZGUgU3RhdEZzfSBzaG91bGQgcmV0dXJuIHRoZSBzcGVjaWZpZWQgc3RhdHMKKyAgICogQHBhcmFtIHRvdGFsQnl0ZXMgVG90YWwgbnVtYmVyIG9mIGJ5dGVzIG9uIHRoZSBmaWxlc3lzdGVtCisgICAqIEBwYXJhbSBmcmVlQnl0ZXMgTnVtYmVyIG9mIHVudXNlZCBieXRlcyBvbiB0aGUgZmlsZXN5c3RlbQorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHNldFN0YXRGcyhGaWxlIGRpciwgaW50IHRvdGFsQnl0ZXMsIGludCBmcmVlQnl0ZXMpIHsKKyAgICBpbnQgYmxvY2tDb3VudCA9IHRvdGFsQnl0ZXMgLyBTaGFkb3dTdGF0RnMuQkxPQ0tfU0laRTsKKyAgICBpbnQgZnJlZUJsb2NrcyA9IGZyZWVCeXRlcyAvIFNoYWRvd1N0YXRGcy5CTE9DS19TSVpFOworICAgIGludCBhdmFpbGFibGVCbG9ja3MgPSBmcmVlQmxvY2tzOworICAgIFNoYWRvd1N0YXRGcy5yZWdpc3RlclN0YXRzKGRpciwgYmxvY2tDb3VudCwgZnJlZUJsb2NrcywgYXZhaWxhYmxlQmxvY2tzKTsKKyAgfQorCisgIC8qKiBFeHRlbmRzIHRoZSBzdG9jayBSb2JvbGVjdHJpYyB7QGNvZGUgQ29udGV4dH0gc2hhZG93IHRvIHN1cHBvcnQgbXVsdGlwbGUgZXh0ZXJuYWxGaWxlc0RpcnMuICovCisgIEBJbXBsZW1lbnRzKGNsYXNzTmFtZSA9IG9yZy5yb2JvbGVjdHJpYy5zaGFkb3dzLlNoYWRvd0NvbnRleHRJbXBsLkNMQVNTX05BTUUpCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgU2hhZG93Q29udGV4dEltcGwgZXh0ZW5kcyBvcmcucm9ib2xlY3RyaWMuc2hhZG93cy5TaGFkb3dDb250ZXh0SW1wbCB7CisgICAgQFJlYWxPYmplY3QgcHJpdmF0ZSBDb250ZXh0IHJlYWxPYmplY3Q7CisKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8RmlsZT4gZXh0ZXJuYWxGaWxlc0RpcnMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBwcml2YXRlIGZpbmFsIExpc3Q8RmlsZT4gZXh0ZXJuYWxDYWNoZURpcnMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgIC8vIFVzZWQgdG8gc2ltdWxhdGUgYSByYWNlIGNvbmRpdGlvbiBmYWlsdXJlIG9uIHByZS1OIGRldmljZXMuIFNlZSBnZXRGaWxlc0Rpci4KKyAgICBwcml2YXRlIGJvb2xlYW4gZ2V0RmlsZXNEaXJSdW5BbHJlYWR5ID0gZmFsc2U7CisKKyAgICAvKioKKyAgICAgKiBBZGRzIHBhY2thZ2UtcHJpdmF0ZSAvZmlsZXMgYW5kIC9jYWNoZSBzdWJkaXJlY3RvcmllcyB0byB0aGUgUm9ib2xlY3RyaWMge0Bjb2RlIENvbnRleHR9CisgICAgICogdW5kZXIgdGhlIG5hbWVkIGV4dGVybmFsIHN0b3JhZ2Uge0Bjb2RlIHBhcnRpdGlvbn0sIHRoZW4gcmV0dXJucyB0aG9zZSBuZXcgc3ViZGlyZWN0b3JpZXMuCisgICAgICovCisgICAgTGlzdDxGaWxlPiBhZGRFeHRlcm5hbFBhY2thZ2VEaXJzKEZpbGUgcGFydGl0aW9uKSB7CisgICAgICBGaWxlIGZpbGVzRGlyID0gbmV3IEZpbGUocGFydGl0aW9uLCAiQW5kcm9pZC9kYXRhL2NvbS5nb29nbGUuYW5kcm9pZC5zdG9yYWdlLnRlc3QvZmlsZXMiKTsKKyAgICAgIEZpbGUgY2FjaGVEaXIgPSBuZXcgRmlsZShwYXJ0aXRpb24sICJBbmRyb2lkL2RhdGEvY29tLmdvb2dsZS5hbmRyb2lkLnN0b3JhZ2UudGVzdC9jYWNoZSIpOworICAgICAgZXh0ZXJuYWxGaWxlc0RpcnMuYWRkKGZpbGVzRGlyKTsKKyAgICAgIGV4dGVybmFsQ2FjaGVEaXJzLmFkZChjYWNoZURpcik7CisgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdChmaWxlc0RpciwgY2FjaGVEaXIpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIEBJbXBsZW1lbnRhdGlvbgorICAgIHB1YmxpYyBGaWxlIGdldEV4dGVybmFsRmlsZXNEaXIoU3RyaW5nIHR5cGUpIHsKKyAgICAgIHJldHVybiAhZXh0ZXJuYWxGaWxlc0RpcnMuaXNFbXB0eSgpID8gZXh0ZXJuYWxGaWxlc0RpcnMuZ2V0KDApIDogbnVsbDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBASW1wbGVtZW50YXRpb24KKyAgICBwdWJsaWMgRmlsZVtdIGdldEV4dGVybmFsRmlsZXNEaXJzKFN0cmluZyB0eXBlKSB7CisgICAgICByZXR1cm4gZXh0ZXJuYWxGaWxlc0RpcnMudG9BcnJheShuZXcgRmlsZVtleHRlcm5hbEZpbGVzRGlycy5zaXplKCldKTsKKyAgICB9CisKKyAgICBASW1wbGVtZW50YXRpb24KKyAgICBwdWJsaWMgRmlsZSBnZXRFeHRlcm5hbENhY2hlRGlyKCkgeworICAgICAgcmV0dXJuICFleHRlcm5hbENhY2hlRGlycy5pc0VtcHR5KCkgPyBleHRlcm5hbENhY2hlRGlycy5nZXQoMCkgOiBudWxsOworICAgIH0KKworICAgIEBJbXBsZW1lbnRhdGlvbgorICAgIHB1YmxpYyBGaWxlW10gZ2V0RXh0ZXJuYWxDYWNoZURpcnMoKSB7CisgICAgICByZXR1cm4gZXh0ZXJuYWxDYWNoZURpcnMudG9BcnJheShuZXcgRmlsZVtleHRlcm5hbENhY2hlRGlycy5zaXplKCldKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZWUgYi83MDI1NTgzNS4gVGhlIGZpcnN0IGNhbGwgKG9yIGZpcnN0IGZldyBjYWxscykgb2YgZ2V0RmlsZXNEaXIgbWF5IHJldHVybiBudWxsIG9uIHByZS1OCisgICAgICogZGV2aWNlcy4gV2Ugc2ltdWxhdGUgdGhpcyBieSByZXR1cm5pbmcgbnVsbCBvbmx5IG9uIHRoZSBmaXJzdCBjYWxsIGhlcmUuCisgICAgICovCisgICAgQEltcGxlbWVudGF0aW9uCisgICAgcHVibGljIEZpbGUgZ2V0RmlsZXNEaXIoKSB7CisgICAgICBpZiAoZ2V0RmlsZXNEaXJSdW5BbHJlYWR5IHx8IEJ1aWxkLlZFUlNJT04uU0RLX0lOVCA+PSBCdWlsZC5WRVJTSU9OX0NPREVTLk8pIHsKKyAgICAgICAgcmV0dXJuIGRpcmVjdGx5T24ocmVhbE9iamVjdCwgU2hhZG93Q29udGV4dEltcGwuQ0xBU1NfTkFNRSwgImdldEZpbGVzRGlyIik7CisgICAgICB9CisgICAgICBnZXRGaWxlc0RpclJ1bkFscmVhZHkgPSB0cnVlOworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEV4dGVuZHMgdGhlIHN0b2NrIFJvYm9sZWN0cmljIHtAY29kZSBFbnZpcm9ubWVudH0gc2hhZG93IHRvIGJldHRlciBlbXVsYXRlIGV4dGVybmFsIHN0b3JhZ2UKKyAgICogQVBJcyBvbiBsb3dlciBzZGsgbGV2ZWxzLgorICAgKi8KKyAgQEltcGxlbWVudHMoRW52aXJvbm1lbnQuY2xhc3MpCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgU2hhZG93RW52aXJvbm1lbnQgZXh0ZW5kcyBvcmcucm9ib2xlY3RyaWMuc2hhZG93cy5TaGFkb3dFbnZpcm9ubWVudCB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBGaWxlIGV4dGVybmFsU3RvcmFnZURpcmVjdG9yeTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIHZhbHVlIHJldHVybmVkIGJ5IHtAY29kZSBnZXRFeHRlcm5hbFN0b3JhZ2VEaXJlY3Rvcnl9LCB3aGljaCBzaG91bGQgYmUgdGhlIHNhbWUgcGF0aAorICAgICAqIGFzIHRoZSBmaXJzdCBkaXJlY3RvcnkgYWRkZWQgdmlhIHtAbGluayBTaGFkb3dFbnZpcm9ubWVudCNhZGRFeHRlcm5hbERpcn0uIFRoaXMgaXMgbmVjZXNzYXJ5CisgICAgICogYmVjYXVzZSBieSBkZWZhdWx0LCBSb2JvbGVjdHJpYyByZXR1cm5zIGEgZml4ZWQgdmFsdWUgZm9yIHtAY29kZSBnZXRFeHRlcm5hbFN0b3JhZ2VEaXJlY3Rvcnl9CisgICAgICogdGhhdCBkb2Vzbid0IHJlZmxlY3QgY2FsbHMgdG8gdGhlIG90aGVyIHNoYWRvdyBBUElzLgorICAgICAqLworICAgIHN0YXRpYyB2b2lkIHNldEV4dGVybmFsU3RvcmFnZURpcmVjdG9yeShGaWxlIGRpcikgeworICAgICAgZXh0ZXJuYWxTdG9yYWdlRGlyZWN0b3J5ID0gZGlyOworICAgIH0KKworICAgIEBJbXBsZW1lbnRhdGlvbgorICAgIHB1YmxpYyBzdGF0aWMgRmlsZSBnZXRFeHRlcm5hbFN0b3JhZ2VEaXJlY3RvcnkoKSB7CisgICAgICByZXR1cm4gZXh0ZXJuYWxTdG9yYWdlRGlyZWN0b3J5OworICAgIH0KKyAgfQorCisgIHByaXZhdGUgU2hhZG93VXRpbHMoKSB7fQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL1N0cmVhbVV0aWxzLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvU3RyZWFtVXRpbHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMmZlMDY4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL1N0cmVhbVV0aWxzLmphdmEKQEAgLTAsMCArMSwxNDcgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3Rpbmc7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuQ2hhcnNldHMuSVNPXzg4NTlfMTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuQ2hhcnNldHMuVVRGXzg7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlJlbGVhc2FibGVSZXNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuQXBwZW5kU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWFkU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5Xcml0ZVN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5CeXRlU3RyZWFtczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5DaGFyU3RyZWFtczsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLldyaXRlcjsKKworLyoqIEhlbHBlcnMgZm9yIHVzaW5nIFN0cmVhbXMgaW4gdGVzdHMuICovCitwdWJsaWMgZmluYWwgY2xhc3MgU3RyZWFtVXRpbHMgeworCisgIHByaXZhdGUgU3RyZWFtVXRpbHMoKSB7fQorCisgIEBEZXByZWNhdGVkCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBjcmVhdGVGaWxlKFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSwgVXJpIHVyaSwgU3RyaW5nIGNvbnRlbnRzKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB3cml0ZUZpbGVUb1Npbmsoc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpLCBjb250ZW50cyk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIHZvaWQgY3JlYXRlRmlsZShTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UsIFVyaSB1cmksIGJ5dGVbXSBjb250ZW50cykKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICBvdXQud3JpdGUoY29udGVudHMpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSBjb250ZW50cyB0byBzaW5rIHN0cmVhbSBhbmQgdGhlbiBjbG9zZSBpdC4KKyAgICoKKyAgICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBlcXVpdmFsZW50IGJ5dGUtYmFzZWQgbWV0aG9kLgorICAgKi8KKyAgQERlcHJlY2F0ZWQKKyAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlRmlsZVRvU2luayhPdXRwdXRTdHJlYW0gc2luaywgU3RyaW5nIGNvbnRlbnRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSAoV3JpdGVyIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoc2luaywgSVNPXzg4NTlfMSkpIHsKKyAgICAgIHdyaXRlci53cml0ZShjb250ZW50cyk7CisgICAgfQorICB9CisKKyAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlRmlsZVRvU2luayhPdXRwdXRTdHJlYW0gc2luaywgYnl0ZVtdIGNvbnRlbnRzKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSAoUmVsZWFzYWJsZVJlc291cmNlPENsb3NlYWJsZT4gb3V0ID0gUmVsZWFzYWJsZVJlc291cmNlLmNyZWF0ZShzaW5rKSkgeworICAgICAgc2luay53cml0ZShjb250ZW50cyk7CisgICAgfQorICB9CisKKyAgLyoqIEFwcGVuZHMgb3IgQ3JlYXRlcyBhIGZpbGUgYXQge0Bjb2RlIHVyaX0gY29udGFpbmluZyB0aGUgYnl0ZSBzdHJlYW0ge0Bjb2RlIGNvbnRlbnRzfS4gKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIGFwcGVuZEZpbGUoU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlLCBVcmkgdXJpLCBieXRlW10gY29udGVudHMpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IHN0b3JhZ2Uub3Blbih1cmksIEFwcGVuZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIG91dC53cml0ZShjb250ZW50cyk7CisgICAgfQorICB9CisKKyAgQERlcHJlY2F0ZWQKKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgcmVhZEZpbGUoU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlLCBVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiByZWFkRmlsZUZyb21Tb3VyY2Uoc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBieXRlW10gcmVhZEZpbGVJbkJ5dGVzKFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSwgVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0cnkgKElucHV0U3RyZWFtIGluID0gc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIHJldHVybiBCeXRlU3RyZWFtcy50b0J5dGVBcnJheShpbik7CisgICAgfQorICB9CisgIC8qKgorICAgKiBSZWFkIGFsbCBieXRlcyBmcm9tIHNvdXJjZSBzdHJlYW0gYW5kIHRoZW4gY2xvc2UgaXQuCisgICAqCisgICAqIEBkZXByZWNhdGVkIFVzZSB0aGUgZXF1aXZhbGVudCBieXRlLWJhc2VkIG1ldGhvZC4KKyAgICovCisgIEBEZXByZWNhdGVkCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWRGaWxlRnJvbVNvdXJjZShJbnB1dFN0cmVhbSBzb3VyY2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IChSZWFkZXIgcmVhZGVyID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKHNvdXJjZSwgSVNPXzg4NTlfMSkpIHsKKyAgICAgIHJldHVybiBDaGFyU3RyZWFtcy50b1N0cmluZyhyZWFkZXIpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIHJlYWRGaWxlSW5CeXRlc0Zyb21Tb3VyY2UoSW5wdXRTdHJlYW0gc291cmNlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGVbXSByZWFkID0gbnVsbDsKKyAgICB0cnkgKFJlbGVhc2FibGVSZXNvdXJjZTxDbG9zZWFibGU+IGluID0gUmVsZWFzYWJsZVJlc291cmNlLmNyZWF0ZShzb3VyY2UpKSB7CisgICAgICByZWFkID0gQnl0ZVN0cmVhbXMudG9CeXRlQXJyYXkoc291cmNlKTsKKyAgICB9CisgICAgcmV0dXJuIHJlYWQ7CisgIH0KKyAgLyoqCisgICAqIENyZWF0ZSBhbiBhbW91bnQgb2YgY29udGVudCB0aGF0IGV4Y2VlZHMgd2hhdCB0aGUgT1MgaXMgZXhwZWN0ZWQgdG8gYnVmZmVyLiBUaGlzIGlzIHN1ZmZpY2llbnQKKyAgICogZm9yIGNvbnZpbmNpbmcgb3Vyc2VsdmVzIHRoYXQgc3RyZWFtcyBiZWhhdmUgYXMgZXhwZWN0ZWQuCisgICAqCisgICAqIDxwPlRPRE86IFRoaXMgY291bGQgYWxzbyBiZSB0ZXN0ZGF0YSAtIHNob3VsZCBpdCBiZT8KKyAgICoKKyAgICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBlcXVpdmFsZW50IGJ5dGUtYmFzZWQgbWV0aG9kLgorICAgKi8KKyAgQERlcHJlY2F0ZWQKKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgbWFrZUNvbnRlbnRUaGF0RXhjZWVkc09zQnVmZmVyU2l6ZSgpIHsKKyAgICBTdHJpbmdCdWlsZGVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAyMDAwOyBpKyspIHsKKyAgICAgIGJ1Zi5hcHBlbmQoImFsbCB3b3JrIGFuZCBubyBwbGF5IG1ha2VzIGphY2sgYSBkdWxsIGJveVxuIik7CisgICAgfQorICAgIGFzc2VydFRoYXQoYnVmLmxlbmd0aCgpKS5pc0dyZWF0ZXJUaGFuKDY1NTM2IC8qIGxpbnV4IHBpcGUgY2FwYWNpdHkqLyk7CisgICAgcmV0dXJuIGJ1Zi50b1N0cmluZygpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBieXRlW10gbWFrZUJ5dGVDb250ZW50VGhhdEV4Y2VlZHNPc0J1ZmZlclNpemUoKSB7CisgICAgcmV0dXJuIG1ha2VBcnJheU9mQnl0ZXNDb250ZW50KDY1NTQwKTsgLy8gbGludXggcGlwZSBjYXBhY2l0eSBpcyA2NTUzNgorICB9CisKKyAgLyoqIENyZWF0ZSBhbiBhcmJpdHJhcnkgYXJyYXkgb2YgYnl0ZXMgKi8KKyAgcHVibGljIHN0YXRpYyBieXRlW10gbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoKSB7CisgICAgcmV0dXJuICJhbGwgd29yayBhbmQgbm8gcGxheSBtYWtlcyBqYWNrIGEgZHVsbCBib3lcbiIuZ2V0Qnl0ZXMoVVRGXzgpOworICB9CisKKyAgLyoqIENyZWF0ZSBhbiBhcmJpdHJhcnkgYXJyYXkgb2YgYnl0ZXMgb2YgYSBnaXZlbiBsZW5ndGggKi8KKyAgcHVibGljIHN0YXRpYyBieXRlW10gbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoaW50IGxlbmd0aCkgeworICAgIGJ5dGVbXSBhcnJheSA9IG5ldyBieXRlW2xlbmd0aF07CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeworICAgICAgYXJyYXlbaV0gPSAoYnl0ZSkgaTsKKyAgICB9CisgICAgcmV0dXJuIGFycmF5OworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvVGVtcG9yYXJ5QW5kcm9pZFVyaS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL1RlbXBvcmFyeUFuZHJvaWRVcmkuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTYyYjJjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL1RlbXBvcmFyeUFuZHJvaWRVcmkuamF2YQpAQCAtMCwwICsxLDg3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuQW5kcm9pZFVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRVcmlBZGFwdGVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5FeHRlcm5hbFJlc291cmNlOworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UZW1wb3JhcnlGb2xkZXI7CisKKy8qKgorICogVGhlIFRlbXBvcmFyeUFuZHJvaWRVcmkgUnVsZSBhbGxvd3MgY3JlYXRpb24gb2YgYW5kcm9pZDogc2NoZW1lIFVyaXMgdGhhdCBzaG91bGQgYmUgZGVsZXRlZCB3aGVuCisgKiB0aGUgdGVzdCBtZXRob2QgZmluaXNoZXMgKHdoZXRoZXIgaXQgcGFzc2VzIG9yIGZhaWxzKS4gVGhpcyBpcyBpbnRlbmRlZCB0byBiZSB0aGUgVXJpIGVxdWl2YWxlbnQKKyAqIG9mIHRoZSBidWlsdC1pbiBUZW1wb3JhcnlGb2xkZXIgcnVsZS4gRXhhbXBsZSBvZiB1c2FnZToKKyAqCisgKiA8cHJlPntAY29kZQorICogcHVibGljIGZpbmFsIGNsYXNzIFRlc3RDbGFzcyB7CisgKiAgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlBbmRyb2lkVXJpIHRtcFVyaSA9IG5ldyBUZW1wb3JhcnlBbmRyb2lkVXJpKCk7CisgKgorICogICBAVGVzdAorICogICBwdWJsaWMgdm9pZCB0ZXN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAqICAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICogICB9CisgKiB9CisgKiB9PC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUZW1wb3JhcnlBbmRyb2lkVXJpIGV4dGVuZHMgRXh0ZXJuYWxSZXNvdXJjZSB7CisKKyAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisKKyAgLy8gTGF6aWx5IGluaXRpYWxpemVkIGluIGJlZm9yZSgpCisgIHByaXZhdGUgVGVtcG9yYXJ5Rm9sZGVyIHRtcEZvbGRlcjsKKworICBwdWJsaWMgVGVtcG9yYXJ5QW5kcm9pZFVyaShDb250ZXh0IGNvbnRleHQpIHsKKyAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIGJlZm9yZSgpIHRocm93cyBUaHJvd2FibGUgeworICAgIC8vIEluaXRpYWxpemVzIFRlbXBvcmFyeUZvbGRlciB1bmRlciBhbmRyb2lkOi8vZmlsZXMvdGVzdGluZy9zaGFyZWQvCisgICAgVXJpIHJvb3RVcmkgPSBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0SW50ZXJuYWxMb2NhdGlvbigpLnNldE1vZHVsZSgidGVzdGluZyIpLmJ1aWxkKCk7CisgICAgRmlsZSByb290RmlsZSA9IEFuZHJvaWRVcmlBZGFwdGVyLmZvckNvbnRleHQoY29udGV4dCkudG9GaWxlKHJvb3RVcmkpOworICAgIHJvb3RGaWxlLm1rZGlycygpOworICAgIGlmICghcm9vdEZpbGUuaXNEaXJlY3RvcnkoKSkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb3VsZCBub3QgY3JlYXRlIHJvb3QgZGlyZWN0b3J5OiAiICsgcm9vdEZpbGUuZ2V0UGF0aCgpKTsKKyAgICB9CisKKyAgICB0bXBGb2xkZXIgPSBuZXcgVGVtcG9yYXJ5Rm9sZGVyKHJvb3RGaWxlKTsKKyAgICB0bXBGb2xkZXIuY3JlYXRlKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgYWZ0ZXIoKSB7CisgICAgdG1wRm9sZGVyLmRlbGV0ZSgpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgYW4gYW5kcm9pZDogVXJpIHRvIGEgbmV3IHRlbXBvcmFyeSBmaWxlLgorICAgKgorICAgKiA8cD5Ob3RlIHRoYXQsIHNpbWlsYXIgdG8ge0BsaW5rIFRlbXBvcmFyeVVyaX0sIHRoaXMgbWV0aG9kIHdpbGwgY3JlYXRlIGFuIGVtcHR5IGZpbGUgYXQgdGhlCisgICAqIHJldHVybmVkIGxvY2F0aW9uIChiLzE0MjU3MDY3NikuCisgICAqLworICBwdWJsaWMgVXJpIG5ld1VyaSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5mcm9tRmlsZSh0bXBGb2xkZXIubmV3RmlsZSgpKS5idWlsZCgpOworICB9CisKKyAgLyoqIFJldHVybnMgYW4gYW5kcm9pZDogVXJpIHRvIGEgbmV3IHRlbXBvcmFyeSBmb2xkZXIuICovCisgIHB1YmxpYyBVcmkgbmV3RGlyZWN0b3J5VXJpKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLmZyb21GaWxlKHRtcEZvbGRlci5uZXdGb2xkZXIoKSkuYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL1RlbXBvcmFyeVVyaS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL1RlbXBvcmFyeVVyaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIzYTgyODQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvVGVtcG9yYXJ5VXJpLmphdmEKQEAgLTAsMCArMSw3OCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZzsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkZpbGVVcmk7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuRXh0ZXJuYWxSZXNvdXJjZTsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGVtcG9yYXJ5Rm9sZGVyOworCisvKioKKyAqIFRoZSBUZW1wb3JhcnlVcmkgUnVsZSBhbGxvd3MgY3JlYXRpb24gb2YgZmlsZTogc2NoZW1lIFVyaXMgdGhhdCBzaG91bGQgYmUgZGVsZXRlZCB3aGVuIHRoZSB0ZXN0CisgKiBtZXRob2QgZmluaXNoZXMgKHdoZXRoZXIgaXQgcGFzc2VzIG9yIGZhaWxzKS4gVGhpcyBpcyBpbnRlbmRlZCB0byBiZSB0aGUgVXJpIGVxdWl2YWxlbnQgb2YgdGhlCisgKiBidWlsdC1pbiBUZW1wb3JhcnlGb2xkZXIgcnVsZS4gRXhhbXBsZSBvZiB1c2FnZToKKyAqCisgKiA8cHJlPntAY29kZQorICogcHVibGljIGZpbmFsIGNsYXNzIFRlc3RDbGFzcyB7CisgKiAgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlVcmkgdG1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworICoKKyAqICAgQFRlc3QKKyAqICAgcHVibGljIHZvaWQgdGVzdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgKiAgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAqICAgfQorICogfQorICogfTwvcHJlPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgVGVtcG9yYXJ5VXJpIGV4dGVuZHMgRXh0ZXJuYWxSZXNvdXJjZSB7CisKKyAgcHJpdmF0ZSBmaW5hbCBUZW1wb3JhcnlGb2xkZXIgdG1wRm9sZGVyID0gbmV3IFRlbXBvcmFyeUZvbGRlcigpOworCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgdm9pZCBiZWZvcmUoKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICB0bXBGb2xkZXIuY3JlYXRlKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIHZvaWQgYWZ0ZXIoKSB7CisgICAgdG1wRm9sZGVyLmRlbGV0ZSgpOworICB9CisKKyAgLyoqIFJldHVybnMgYSBmaWxlOiBVcmkgdG8gYSBuZXcgdGVtcG9yYXJ5IGZpbGUuICovCisgIHB1YmxpYyBVcmkgbmV3VXJpKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gRmlsZVVyaS5mcm9tRmlsZSh0bXBGb2xkZXIubmV3RmlsZSgpKTsKKyAgfQorCisgIC8qKiBSZXR1cm5zIGEgZmlsZTogVXJpIGJ1aWxkZXIgdG8gYSBuZXcgdGVtcG9yYXJ5IGZpbGUuICovCisgIHB1YmxpYyBGaWxlVXJpLkJ1aWxkZXIgbmV3VXJpQnVpbGRlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIEZpbGVVcmkuYnVpbGRlcigpLmZyb21GaWxlKHRtcEZvbGRlci5uZXdGaWxlKCkpOworICB9CisKKyAgLyoqIFJldHVybnMgYSBmaWxlOiBVcmkgdG8gYSBuZXcgdGVtcG9yYXJ5IGZvbGRlci4gKi8KKyAgcHVibGljIFVyaSBuZXdEaXJlY3RvcnlVcmkoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBGaWxlVXJpLmZyb21GaWxlKHRtcEZvbGRlci5uZXdGb2xkZXIoKSk7CisgIH0KKworICAvKiogUmV0dXJucyB0aGUgZmlsZTogVXJpIG9mIHRoZSBkaXJlY3RvcnkgdW5kZXIgd2hpY2ggb3RoZXIgVXJpcyBhcmUgY3JlYXRlZC4gKi8KKyAgcHVibGljIFVyaSBnZXRSb290VXJpKCkgeworICAgIHJldHVybiBGaWxlVXJpLmZyb21GaWxlKHRtcEZvbGRlci5nZXRSb290KCkpOworICB9CisKKyAgLyoqIFJldHVybnMgYSBmaWxlOiBVcmkgYnVpbGRlciBvZiB0aGUgZGlyZWN0b3J5IHVuZGVyIHdoaWNoIG90aGVyIFVyaXMgYXJlIGNyZWF0ZWQuICovCisgIHB1YmxpYyBGaWxlVXJpLkJ1aWxkZXIgZ2V0Um9vdFVyaUJ1aWxkZXIoKSB7CisgICAgcmV0dXJuIEZpbGVVcmkuYnVpbGRlcigpLmZyb21GaWxlKHRtcEZvbGRlci5nZXRSb290KCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvV3JpdGVzVGhyb3dUcmFuc2Zvcm0uamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9Xcml0ZXNUaHJvd1RyYW5zZm9ybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxNmU5MTYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvV3JpdGVzVGhyb3dUcmFuc2Zvcm0uamF2YQpAQCAtMCwwICsxLDc5IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkZyYWdtZW50OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLkZvcndhcmRpbmdPdXRwdXRTdHJlYW07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuVHJhbnNmb3JtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqIEEgVHJhbnNmb3JtIHRoYXQgdGhyb3dzIElPRXhjZXB0aW9uIGFmdGVyIHdyaXRpbmcgTiBieXRlcyBvZiBkYXRhIChyZWFkcyBhcmUgdW5hZmZlY3RlZCkuICovCitwdWJsaWMgY2xhc3MgV3JpdGVzVGhyb3dUcmFuc2Zvcm0gaW1wbGVtZW50cyBUcmFuc2Zvcm0geworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FID0gIndyaXRldGhyb3dzIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIExFTkdUSF9TVUJQQVJBTSA9ICJ3cml0ZV9sZW5ndGgiOworCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIG5hbWUoKSB7CisgICAgcmV0dXJuIE5BTUU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIHdyYXBGb3JSZWFkKFVyaSB1cmksIElucHV0U3RyZWFtIHdyYXBwZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHdyYXBwZWQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE91dHB1dFN0cmVhbSB3cmFwRm9yV3JpdGUoVXJpIHVyaSwgT3V0cHV0U3RyZWFtIHdyYXBwZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ldyBGb3J3YXJkaW5nT3V0cHV0U3RyZWFtKHdyYXBwZWQpIHsKKyAgICAgIGxvbmcgYnl0ZUNvdW50ID0gZ2V0TGVuZ3RoU3VicGFyYW0odXJpKTsKKworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgdm9pZCB3cml0ZShieXRlW10gYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgICAgd3JpdGUoYiwgMCwgYi5sZW5ndGgpOworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBsZW4gPSAoaW50KSBNYXRoLm1pbihsZW4sIGJ5dGVDb3VudCk7IC8vIFdyaXRlIG5vIG1vcmUgdGhhbiBieXRlQ291bnQgYnl0ZXMKKyAgICAgICAgb3V0LndyaXRlKGIsIG9mZiwgbGVuKTsKKyAgICAgICAgYnl0ZUNvdW50IC09IGxlbjsKKyAgICAgICAgaWYgKGJ5dGVDb3VudCA9PSAwKSB7CisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJ0aHJvd2luZyIpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHZvaWQgd3JpdGUoaW50IGIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHdyaXRlKG5ldyBieXRlW10geyhieXRlKSBifSwgMCwgMSk7CisgICAgICB9CisgICAgfTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3V0cHV0U3RyZWFtIHdyYXBGb3JBcHBlbmQoVXJpIHVyaSwgT3V0cHV0U3RyZWFtIHdyYXBwZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHdyYXBGb3JXcml0ZSh1cmksIHdyYXBwZWQpOworICB9CisKKyAgLyoqIFJldHVybnMgdGhlIHZhbHVlIG9mIHtAbGluayAjTEVOR1RIX1NVQlBBUkFNfSBpbiB7QGNvZGUgcGFyYW19LCBvciAwIGlmIG5vdCBwcmVzZW50LiAqLworICBwcml2YXRlIHN0YXRpYyBsb25nIGdldExlbmd0aFN1YnBhcmFtKFVyaSB1cmkpIHsKKyAgICBTdHJpbmcgdmFsdWUgPSBGcmFnbWVudC5nZXRUcmFuc2Zvcm1TdWJQYXJhbSh1cmksIE5BTUUsIExFTkdUSF9TVUJQQVJBTSk7CisgICAgcmV0dXJuIHZhbHVlICE9IG51bGwgPyBMb25nLnBhcnNlTG9uZyh2YWx1ZSkgOiAwOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvYnVpbGRfZGVmcy5iemwgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvYnVpbGRfZGVmcy5iemwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWVmOTA3YQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9idWlsZF9kZWZzLmJ6bApAQCAtMCwwICsxLDEwNCBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorIiIiQnVpbGQgZGVmaW5pdGlvbiBoZWxwZXJzIGZvciBNb2JTdG9yZSBsaWJyYXJ5LiIiIgorCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9hcHBsaWNhdGlvbl90ZXN0IikKKworIyBOT1RFOiBBUEkgbGV2ZWwgMTYgaXMgdGhlIGxvd2VzdCBzdXBwb3J0ZWQgYnkgR21zQ29yZSAoPGludGVybmFsPikKK19ERUZBVUxUX1RBUkdFVF9BUElTID0gWworICAgICIxNiIsCisgICAgIjE3IiwKKyAgICAiMTgiLAorICAgICIxOSIsCisgICAgIyBnZW5lcmljX3Bob25lOmdvb2dsZV8yMF94ODZfZ21zX3N0YWJsZSBkb2VzIG5vdCBleGlzdCAoMjA9S2l0S2F0IFdlYXIpCisgICAgIjIxIiwKKyAgICAiMjIiLAorICAgICIyMyIsCisgICAgIjI0IiwKKyAgICAiMjUiLAorICAgICIyNiIsCisgICAgIjI3IiwKKyAgICAiMjgiLAorICAgICIyOSIsCitdCisKK19HRU5FUklDX0RFVklDRV9GTVQgPSAiZ2VuZXJpY19waG9uZTpnb29nbGVfJXNfeDg2X2dtc19zdGFibGUiCitfRU1VTEFUT1JfRElSRUNUT1JZID0gIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzLyVzIgorCitkZWYgYW5kcm9pZF90ZXN0X211bHRpX2FwaSgKKyAgICAgICAgbmFtZSwKKyAgICAgICAgdGFyZ2V0X2FwaXMgPSBfREVGQVVMVF9UQVJHRVRfQVBJUywKKyAgICAgICAgKiprd2FyZ3MpOgorICAgICIiIlNpbXBsZSBkZWZpbml0aW9uIGZvciBydW5uaW5nIGFuIGFuZHJvaWRfYXBwbGljYXRpb25fdGVzdCBhZ2FpbnN0IG11bHRpcGxlIEFQSSBsZXZlbHMuCisKKyAgICBGb3IgZWFjaCBvZiB0aGUgc3BlY2lmaWVkIEFQSSBsZXZlbHMgd2UgZ2VuZXJhdGUgYW4gYW5kcm9pZF9hcHBsaWNhdGlvbl90ZXN0IGZvciB0aGUKKyAgICBnaXZlbiB0ZXN0IGZpbGUgcnVuIGF0IHRoYXQgQVBJIGxldmVsLiAgQWxsIG9mIHRoZXNlIHRlc3RzIHdpbGwgYmUgcnVuIG9uCisgICAgVEFQLiBXZSBhbHNvIGdlbmVyYXRlIGEgZHVwbGljYXRlIHRhcmdldCBhdCB0aGUgaGlnaGVzdCBBUEkgbGV2ZWwgZm9yIGVhc2UKKyAgICBvZiBsb2NhbCB0ZXN0aW5nOyBpdCdzIG1hcmtlZCBub3RhcCBzbyBUQVAgZG9lc24ndCBydW4gdGhlIHNhbWUgdGVzdCB0d2ljZS4KKworICAgIEZvciBleGFtcGxlLCB3aXRoIEZvb1Rlc3QuamF2YSBhbmQgQVBJIGxldmVscyAxOCBhbmQgMTksIHdlIGdlbmVyYXRlOgorICAgIC4uLjpGb29UZXN0X2dlbmVyaWNfcGhvbmVfZ29vZ2xlXzE4X3g4Nl9nbXNfc3RhYmxlIChBUEkgbGV2ZWwgMTgpCisgICAgLi4uOkZvb1Rlc3RfZ2VuZXJpY19waG9uZV9nb29nbGVfMTlfeDg2X2dtc19zdGFibGUgKEFQSSBsZXZlbCAxOSkKKyAgICAuLi46Rm9vVGVzdCAoQVBJIGxldmVsIDE5KQorCisgICAgQXJnczoKKyAgICAgIG5hbWU6IE5hbWUgb2YgdGhlICJkZWZhdWx0IiB0ZXN0IHRhcmdldCBhbmQgdXNlZCB0byBkZXJpdmUgc3VidGFyZ2V0cworICAgICAgdGFyZ2V0X2FwaXM6IExpc3Qgb2YgQW5kcm9pZCBBUEkgbGV2ZWxzIGFzIHN0cmluZ3MgZm9yIHdoaWNoIGEgdGVzdCBzaG91bGQKKyAgICAgICAgICAgICAgICAgICBiZSBnZW5lcmF0ZWQuIElmIHVuc3BlY2lmaWVkLCAxNi0yOCBleGNsdWRpbmcgMjAgYXJlIHVzZWQuCisgICAgICAqKmt3YXJnczogUGFyYW1ldGVycyB0aGF0IGFyZSBwYXNzZWQgdG8gdGhlIGdlbmVyYXRlZCBhbmRyb2lkX2FwcGxpY2F0aW9uX3Rlc3QgcnVsZS4KKyAgICAiIiIKKworICAgICMgR2VuZXJhdGUgYSB2ZXJib3NlbHktbmFtZWQgdGVzdCB0YXJnZXQgYXQgZWFjaCBBUEkgbGV2ZWwgZm9yIFRBUCB0ZXN0aW5nCisgICAgdGFyZ2V0X2RldmljZXMgPSBbXQorICAgIGZvciB0YXJnZXRfYXBpIGluIHRhcmdldF9hcGlzOgorICAgICAgICB0YXJnZXRfZGV2aWNlID0gX0dFTkVSSUNfREVWSUNFX0ZNVCAlICh0YXJnZXRfYXBpKQorICAgICAgICB0YXJnZXRfZGV2aWNlcy5hcHBlbmQodGFyZ2V0X2RldmljZSkKKyAgICBhbmRyb2lkX3Rlc3RfbXVsdGlfZGV2aWNlKAorICAgICAgICBuYW1lID0gbmFtZSwKKyAgICAgICAgdGFyZ2V0X2RldmljZXMgPSB0YXJnZXRfZGV2aWNlcywKKyAgICAgICAgKiprd2FyZ3MKKyAgICApCisKKyAgICAjIER1cGxpY2F0ZSB0aGUgaGlnaGVzdCBBUEkgdGFyZ2V0IHdpdGggYSBzaW1wbGUgbmFtZSBmb3IgbG9jYWwgdGVzdGluZworICAgIHRvcF9hcGkgPSB0YXJnZXRfYXBpc1stMV0KKyAgICB0ZXN0X2RldmljZSA9IF9FTVVMQVRPUl9ESVJFQ1RPUlkgJSAoX0dFTkVSSUNfREVWSUNFX0ZNVCAlIHRvcF9hcGkpCisgICAgYW5kcm9pZF9hcHBsaWNhdGlvbl90ZXN0KAorICAgICAgICBuYW1lID0gbmFtZSwKKyAgICAgICAgdGFyZ2V0X2RldmljZXMgPSBbdGVzdF9kZXZpY2VdLAorICAgICAgICB0YWdzID0gWyJub3RhcCJdLAorICAgICAgICAqKmt3YXJncworICAgICkKKworIyBUT0RPOiBjb25zaWRlciBjb21iaW5pbmcgd2l0aCBhbmRyb2lkX3Rlc3RfbXVsdGlfYXBpCitkZWYgYW5kcm9pZF90ZXN0X211bHRpX2RldmljZSgKKyAgICAgICAgbmFtZSwKKyAgICAgICAgdGFyZ2V0X2RldmljZXMsCisgICAgICAgICoqa3dhcmdzKToKKyAgICAiIiJTaW1wbGUgZGVmaW5pdGlvbiBmb3IgcnVubmluZyBhbiBhbmRyb2lkX2FwcGxpY2F0aW9uX3Rlc3QgYWdhaW5zdCBtdWx0aXBsZSBkZXZpY2VzLgorCisgICAgQXJnczoKKyAgICAgIG5hbWU6IE5hbWUgb2YgdGhlIHRlc3QgcnVsZTsgd2UgZ2VuZXJhdGUgc2V2ZXJhbCBzdWItdGFyZ2V0cyBiYXNlZCBvbiBBUEkuCisgICAgICB0YXJnZXRfZGV2aWNlczogTGlzdCBvZiBlbXVsYXRvcnMgYXMgc3RyaW5ncyBmb3Igd2hpY2ggYSB0ZXN0IHNob3VsZCBiZQorICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlZC4KKyAgICAgICoqa3dhcmdzOiBQYXJhbWV0ZXJzIHRoYXQgYXJlIHBhc3NlZCB0byB0aGUgZ2VuZXJhdGVkIGFuZHJvaWRfYXBwbGljYXRpb25fdGVzdCBydWxlLgorICAgICIiIgorICAgIGZvciB0YXJnZXRfZGV2aWNlIGluIHRhcmdldF9kZXZpY2VzOgorICAgICAgICBzYW5pdGl6ZWRfZGV2aWNlID0gdGFyZ2V0X2RldmljZS5yZXBsYWNlKCI6IiwgIl8iKSAgIyAiOiIgaXMgaW52YWxpZAorICAgICAgICB0ZXN0X25hbWUgPSAiJXNfJXMiICUgKG5hbWUsIHNhbml0aXplZF9kZXZpY2UpCisgICAgICAgIHRlc3RfZGV2aWNlID0gX0VNVUxBVE9SX0RJUkVDVE9SWSAlICh0YXJnZXRfZGV2aWNlKQorICAgICAgICBhbmRyb2lkX2FwcGxpY2F0aW9uX3Rlc3QoCisgICAgICAgICAgICBuYW1lID0gdGVzdF9uYW1lLAorICAgICAgICAgICAgdGFyZ2V0X2RldmljZXMgPSBbdGVzdF9kZXZpY2VdLAorICAgICAgICAgICAgKiprd2FyZ3MKKyAgICAgICAgKQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL3Rlc3RfbWVzc2FnZS5wcm90byBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy90ZXN0X21lc3NhZ2UucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDYxMWY5YwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy90ZXN0X21lc3NhZ2UucHJvdG8KQEAgLTAsMCArMSw0NiBAQAorLy8gQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworLy8KKy8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorLy8gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisvLworLy8gICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKy8vCisvLyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisvLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorLy8gV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisvLyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisvLyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy8vIER1bW15IHByb3RvcyBmb3IgdXNlIGluIHRlc3RzCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBnb29nbGUuYW5kcm9pZC5zdG9yYWdlLmNvbW1vbjsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJUZXN0TWVzc2FnZVByb3RvIjsKKworbWVzc2FnZSBGb29Qcm90byB7CisgIG9wdGlvbmFsIHN0cmluZyB0ZXh0ID0gMTsKKyAgb3B0aW9uYWwgYm9vbCBib29sZWFuID0gMjsKKyAgb3B0aW9uYWwgaW50MzIgaW50ZWdlciA9IDM7CisgIG9wdGlvbmFsIGJ5dGVzIGJ5dGVzID0gNDsKK30KKworbWVzc2FnZSBCYXJQcm90byB7CisgIG9wdGlvbmFsIGludDMyIGludGVnZXIgPSAxOworfQorCittZXNzYWdlIEV4dGVuZGFibGVQcm90byB7CisgIGV4dGVuc2lvbnMgMTAwMCB0byBtYXg7Cit9CisKK21lc3NhZ2UgRXh0ZW5zaW9uUHJvdG8geworICBleHRlbmQgRXh0ZW5kYWJsZVByb3RvIHsKKyAgICBvcHRpb25hbCBFeHRlbnNpb25Qcm90byBleHRlbnNpb24gPSAyMjYyMTk2ODg7CisgIH0KKyAgb3B0aW9uYWwgRm9vUHJvdG8gZm9vID0gMTsKK30KKworbWVzc2FnZSBNYXBQcm90byB7CisgIG1hcDxzdHJpbmcsIEJhclByb3RvPiBiYXIgPSAyOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXIvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvaW50ZWdyYXRpb24vZG93bmxvYWRlci9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MmUzNGZhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXIvQlVJTEQKQEAgLTAsMCArMSw0OCBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImRvd25sb2FkZXIyIiwKKyAgICBzcmNzID0gWworICAgICAgICAiRG93bmxvYWREZXN0aW5hdGlvbk9wZW5lci5qYXZhIiwKKyAgICAgICAgIkRvd25sb2FkTWV0YWRhdGFTdG9yZS5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpyYW5kb21fYWNjZXNzX2ZpbGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGRvd25sb2FkZXIiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImRvd25sb2FkZXIyX3NwIiwKKyAgICBzcmNzID0gWworICAgICAgICAiU2hhcmVkUHJlZmVyZW5jZXNEb3dubG9hZE1ldGFkYXRhLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpkb3dubG9hZGVyMiIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAZG93bmxvYWRlciIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9pbnRlZ3JhdGlvbi9kb3dubG9hZGVyL0Rvd25sb2FkRGVzdGluYXRpb25PcGVuZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9pbnRlZ3JhdGlvbi9kb3dubG9hZGVyL0Rvd25sb2FkRGVzdGluYXRpb25PcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTVlYzg1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXIvRG93bmxvYWREZXN0aW5hdGlvbk9wZW5lci5qYXZhCkBAIC0wLDAgKzEsMTg2IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmludGVncmF0aW9uLmRvd25sb2FkZXI7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24uYmFzZS5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQ7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0Lk1JTExJU0VDT05EUzsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5Eb3dubG9hZERlc3RpbmF0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkTWV0YWRhdGE7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuQ29udGV4dDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uUmVsZWFzYWJsZVJlc291cmNlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLlJhbmRvbUFjY2Vzc0ZpbGVPcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZTsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5GaWxlQ2hhbm5lbDsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Xcml0YWJsZUJ5dGVDaGFubmVsOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNhbmNlbGxhdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZW91dEV4Y2VwdGlvbjsKKworLyoqCisgKiBBIE1vYlN0b3JlIE9wZW5lciBmb3IgPGludGVybmFsPidzIHtAbGluayBEb3dubG9hZERlc3RpbmF0aW9ufS4KKyAqCisgKiA8cD5UaGlzIGNyZWF0ZXMgYSB7QGxpbmsgRG93bmxvYWREZXN0aW5hdGlvbn0gdGhhdCBzdXBwb3J0cyB3cml0aW5nIGRhdGEgYW5kIGNvbm5lY3RzIHRvIGEgc2hhcmVkCisgKiBQRFMgaW5zdGFuY2UgdG8gaGFuZGxlIG1ldGFkYXRhIHVwZGF0ZXMuCisgKgorICogPHByZT57QGNvZGUKKyAqIERvd25sb2FkZXIgZG93bmxvYWRlciA9IG5ldyBEb3dubG9hZGVyKC4uLik7CisgKiBEb3dubG9hZE1ldGFkYXRhU3RvcmUgbWV0YWRhdGFTdG9yZSA9IC4uLjsKKyAqIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKC4uLik7CisgKgorICogRG93bmxvYWREZXN0aW5hdGlvbiBkZXN0aW5hdGlvbiA9IHN0b3JhZ2Uub3BlbigKKyAqICAgdGFyZ2V0RmlsZVVyaSwKKyAqICAgRG93bmxvYWREZXN0aW5hdGlvbk9wZW5lci5jcmVhdGUobWV0YWRhdGFTdG9yZSkpOworICoKKyAqIGRvd25sb2FkZXIuZXhlY3V0ZSgKKyAqICAgZG93bmxvYWRlcgorICogICAgIC5uZXdSZXF1ZXN0QnVpbGRlcih1cmxUb0Rvd25sb2FkLCBkZXN0aW5hdGlvbikKKyAqICAgICAuYnVpbGQoKSk7CisgKiB9PC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBEb3dubG9hZERlc3RpbmF0aW9uT3BlbmVyIGltcGxlbWVudHMgT3BlbmVyPERvd25sb2FkRGVzdGluYXRpb24+IHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBUSU1FT1VUX01TID0gMTAwMDsKKworICAvKiogSW1wbGVtZW50YXRpb24gb2Yge0BsaW5rIERvd25sb2FkRGVzdGluYXRpb259IGNyZWF0ZWQgYnkgdGhlIG9wZW5lci4gKi8KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRG93bmxvYWREZXN0aW5hdGlvbkltcGwgaW1wbGVtZW50cyBEb3dubG9hZERlc3RpbmF0aW9uIHsKKyAgICAvLyBXZSBuZWVkIHRvIHRvdWNoIHR3byB1bmRlcmx5aW5nIGZpbGVzIChtZXRhZGF0YSBmcm9tIERvd25sb2FkTWV0YWRhdGFTdG9yZSBhbmQgdGhlIGRvd25sb2FkZWQKKyAgICAvLyBmaWxlKS4gRGVmaW5lIGEgbG9jayB0byBrZWVwIHRoZSBhY2Nlc3Mgb2YgdGhlc2UgZmlsZXMgc3luY2hyb25pemVkLgorICAgIHByaXZhdGUgZmluYWwgT2JqZWN0IGxvY2sgPSBuZXcgT2JqZWN0KCk7CisKKyAgICBwcml2YXRlIGZpbmFsIFVyaSBvbkRldmljZVVyaTsKKyAgICBwcml2YXRlIGZpbmFsIERvd25sb2FkTWV0YWRhdGFTdG9yZSBtZXRhZGF0YVN0b3JlOworICAgIHByaXZhdGUgZmluYWwgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKworICAgIHByaXZhdGUgRG93bmxvYWREZXN0aW5hdGlvbkltcGwoCisgICAgICAgIFVyaSBvbkRldmljZVVyaSwgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZSwgRG93bmxvYWRNZXRhZGF0YVN0b3JlIG1ldGFkYXRhU3RvcmUpIHsKKyAgICAgIHRoaXMub25EZXZpY2VVcmkgPSBvbkRldmljZVVyaTsKKyAgICAgIHRoaXMubWV0YWRhdGFTdG9yZSA9IG1ldGFkYXRhU3RvcmU7CisgICAgICB0aGlzLmZpbGVTdG9yYWdlID0gZmlsZVN0b3JhZ2U7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGxvbmcgbnVtRXhpc3RpbmdCeXRlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICByZXR1cm4gZmlsZVN0b3JhZ2UuZmlsZVNpemUob25EZXZpY2VVcmkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBEb3dubG9hZE1ldGFkYXRhIHJlYWRNZXRhZGF0YSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgT3B0aW9uYWw8RG93bmxvYWRNZXRhZGF0YT4gZXhpc3RpbmdNZXRhZGF0YSA9CisgICAgICAgICAgICBibG9ja2luZ0dldChtZXRhZGF0YVN0b3JlLnJlYWQob25EZXZpY2VVcmkpLCAiRmFpbGVkIHRvIHJlYWQgbWV0YWRhdGEuIik7CisKKyAgICAgICAgLy8gUmV0dXJuIGV4aXN0aW5nIG1ldGFkYXRhLCBvciBhIG5ldyBpbnN0YW5jZS4KKyAgICAgICAgcmV0dXJuIGV4aXN0aW5nTWV0YWRhdGEub3IoRG93bmxvYWRNZXRhZGF0YTo6Y3JlYXRlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgV3JpdGFibGVCeXRlQ2hhbm5lbCBvcGVuQnl0ZUNoYW5uZWwobG9uZyBieXRlT2Zmc2V0LCBEb3dubG9hZE1ldGFkYXRhIG1ldGFkYXRhKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgLy8gRW5zdXJlIHRoYXQgbWV0YWRhdGEgaXMgbm90IG51bGwKKyAgICAgIGNoZWNrQXJndW1lbnQobWV0YWRhdGEgIT0gbnVsbCwgIlJlY2VpdmVkIG51bGwgbWV0YWRhdGEgdG8gc3RvcmUiKTsKKyAgICAgIC8vIENoZWNrIHRoYXQgb2Zmc2V0IGlzIGluIHJhbmdlCisgICAgICBsb25nIGZpbGVTaXplID0gbnVtRXhpc3RpbmdCeXRlcygpOworICAgICAgY2hlY2tBcmd1bWVudCgKKyAgICAgICAgICBieXRlT2Zmc2V0ID49IDAgJiYgYnl0ZU9mZnNldCA8PSBmaWxlU2l6ZSwKKyAgICAgICAgICAiT2Zmc2V0IGZvciB3cml0ZSAoJXMpIG91dCBvZiByYW5nZSBvZiBleGlzdGluZyBmaWxlIHNpemUgKCVzIGJ5dGVzKSIsCisgICAgICAgICAgYnl0ZU9mZnNldCwKKyAgICAgICAgICBmaWxlU2l6ZSk7CisKKyAgICAgIHN5bmNocm9uaXplZCAobG9jaykgeworICAgICAgICAvLyBVcGRhdGUgbWV0YWRhdGEgZmlyc3QuCisgICAgICAgIGJsb2NraW5nR2V0KG1ldGFkYXRhU3RvcmUudXBzZXJ0KG9uRGV2aWNlVXJpLCBtZXRhZGF0YSksICJGYWlsZWQgdG8gdXBkYXRlIG1ldGFkYXRhLiIpOworCisgICAgICAgIC8vIFVzZSBSZWxlYXNhYmxlUmVzb3VyY2UgdG8gZW5zdXJlIGNoYW5uZWwgaXMgc2V0dXAgcHJvcGVybHkgYmVmb3JlIHJldHVybmluZyBpdC4KKyAgICAgICAgdHJ5IChSZWxlYXNhYmxlUmVzb3VyY2U8UmFuZG9tQWNjZXNzRmlsZT4gZmlsZSA9CisgICAgICAgICAgICBSZWxlYXNhYmxlUmVzb3VyY2UuY3JlYXRlKAorICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLm9wZW4ob25EZXZpY2VVcmksIFJhbmRvbUFjY2Vzc0ZpbGVPcGVuZXIuY3JlYXRlRm9yUmVhZFdyaXRlKCkpKSkgeworICAgICAgICAgIC8vIEdldCBjaGFubmVsIGFuZCBzZWVrIHRvIGNvcnJlY3Qgb2Zmc2V0LgorICAgICAgICAgIEZpbGVDaGFubmVsIGNoYW5uZWwgPSBmaWxlLmdldCgpLmdldENoYW5uZWwoKTsKKyAgICAgICAgICBjaGFubmVsLnBvc2l0aW9uKGJ5dGVPZmZzZXQpOworCisgICAgICAgICAgLy8gUmVsZWFzZSBvd25lcnNoaXAgLS0gY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBjbG9zaW5nIHRoZSBjaGFubmVsLgorICAgICAgICAgIGZpbGUucmVsZWFzZSgpOworCisgICAgICAgICAgcmV0dXJuIGNoYW5uZWw7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbGVhcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgLy8gY2xlYXIgbWV0YWRhdGEgYW5kIGRlbGV0ZSBmaWxlLgorICAgICAgICBibG9ja2luZ0dldChtZXRhZGF0YVN0b3JlLmRlbGV0ZShvbkRldmljZVVyaSksICJGYWlsZWQgdG8gY2xlYXIgbWV0YWRhdGEuIik7CisKKyAgICAgICAgZmlsZVN0b3JhZ2UuZGVsZXRlRmlsZShvbkRldmljZVVyaSk7CisgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogSGVscGVyIG1ldGhvZCBmb3IgYXN5bmMgY2FsbCBlcnJvciBoYW5kbGluZy4KKyAgICAgKgorICAgICAqIDxwPkV4Y2VwdGlvbnMgZHVlIHRvIGFuIGFzeW5jIGNhbGwgZmFpbHVyZSBhcmUgaGFuZGxlZCBhbmQgd3JhcHBlZCBpbiBhbiBJT0V4Y2VwdGlvbi4KKyAgICAgKi8KKyAgICBwcml2YXRlIHN0YXRpYyA8Vj4gViBibG9ja2luZ0dldChMaXN0ZW5hYmxlRnV0dXJlPFY+IGZ1dHVyZSwgU3RyaW5nIGVycm9yTWVzc2FnZSkKKyAgICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIHJldHVybiBmdXR1cmUuZ2V0KFRJTUVPVVRfTVMsIE1JTExJU0VDT05EUyk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuaW50ZXJydXB0KCk7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlcnJvck1lc3NhZ2UsIGUuZ2V0Q2F1c2UoKSk7CisgICAgICB9IGNhdGNoIChFeGVjdXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZXJyb3JNZXNzYWdlLCBlLmdldENhdXNlKCkpOworICAgICAgfSBjYXRjaCAoVGltZW91dEV4Y2VwdGlvbiB8IENhbmNlbGxhdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlcnJvck1lc3NhZ2UsIGUpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIHByaXZhdGUgZmluYWwgRG93bmxvYWRNZXRhZGF0YVN0b3JlIG1ldGFkYXRhU3RvcmU7CisKKyAgcHJpdmF0ZSBEb3dubG9hZERlc3RpbmF0aW9uT3BlbmVyKERvd25sb2FkTWV0YWRhdGFTdG9yZSBtZXRhZGF0YVN0b3JlKSB7CisgICAgdGhpcy5tZXRhZGF0YVN0b3JlID0gbWV0YWRhdGFTdG9yZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgRG93bmxvYWREZXN0aW5hdGlvbiBvcGVuKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChvcGVuQ29udGV4dC5oYXNUcmFuc2Zvcm1zKCkpIHsKKyAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKAorICAgICAgICAgICJUcmFuc2Zvcm1zIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgT3BlbmVyOiAiICsgb3BlbkNvbnRleHQub3JpZ2luYWxVcmkoKSk7CisgICAgfQorCisgICAgLy8gQ2hlY2sgd2hldGhlciBvciBub3QgdGhlIGZpbGUgdXJpIGlzIGEgZGlyZWN0b3J5LgorICAgIGlmIChvcGVuQ29udGV4dC5zdG9yYWdlKCkuaXNEaXJlY3Rvcnkob3BlbkNvbnRleHQub3JpZ2luYWxVcmkoKSkpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigKKyAgICAgICAgICBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJSZXF1ZXN0ZWQgZmlsZSBkb3dubG9hZCBpcyBhbHJlYWR5IGEgZGlyZWN0b3J5LiIpKTsKKyAgICB9CisKKyAgICByZXR1cm4gbmV3IERvd25sb2FkRGVzdGluYXRpb25JbXBsKAorICAgICAgICBvcGVuQ29udGV4dC5vcmlnaW5hbFVyaSgpLCBvcGVuQ29udGV4dC5zdG9yYWdlKCksIG1ldGFkYXRhU3RvcmUpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBEb3dubG9hZERlc3RpbmF0aW9uT3BlbmVyIGNyZWF0ZShEb3dubG9hZE1ldGFkYXRhU3RvcmUgbWV0YWRhdGFTdG9yZSkgeworICAgIHJldHVybiBuZXcgRG93bmxvYWREZXN0aW5hdGlvbk9wZW5lcihtZXRhZGF0YVN0b3JlKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXIvRG93bmxvYWRNZXRhZGF0YVN0b3JlLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvaW50ZWdyYXRpb24vZG93bmxvYWRlci9Eb3dubG9hZE1ldGFkYXRhU3RvcmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NWM3ODUzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXIvRG93bmxvYWRNZXRhZGF0YVN0b3JlLmphdmEKQEAgLTAsMCArMSwzMyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5pbnRlZ3JhdGlvbi5kb3dubG9hZGVyOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkTWV0YWRhdGE7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKKworLyoqIFN0b3JhZ2UgbWVjaGFuaXNtIGZvciBEb3dubG9hZE1ldGFkYXRhLiAqLworcHVibGljIGludGVyZmFjZSBEb3dubG9hZE1ldGFkYXRhU3RvcmUgeworICAvKiogUmV0dXJucyB0aGUgRG93bmxvYWRNZXRhZGF0YSBhc3NvY2lhdGVkIHdpdGgge0Bjb2RlIHVyaX0gaWYgaXQgZXhpc3RzLiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPE9wdGlvbmFsPERvd25sb2FkTWV0YWRhdGE+PiByZWFkKFVyaSB1cmkpOworCisgIC8qKiBJbnNlcnRzIG9yIHVwZGF0ZXMgdGhlIHtAY29kZSBtZXRhZGF0YX0gYXNzb2NpYXRlZCB3aXRoIHtAY29kZSB1cml9LiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHVwc2VydChVcmkgdXJpLCBEb3dubG9hZE1ldGFkYXRhIG1ldGFkYXRhKTsKKworICAvKiogRGVsZXRlcyB0aGUgRG93bmxvYWRNZXRhZGF0YSBhc3NvY2lhdGVkIHdpdGgge0Bjb2RlIHVyaX0gaWYgaXQgZXhpc3RzLiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRlbGV0ZShVcmkgdXJpKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9pbnRlZ3JhdGlvbi9kb3dubG9hZGVyL1NoYXJlZFByZWZlcmVuY2VzRG93bmxvYWRNZXRhZGF0YS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXIvU2hhcmVkUHJlZmVyZW5jZXNEb3dubG9hZE1ldGFkYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjQ1ODZhZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9pbnRlZ3JhdGlvbi9kb3dubG9hZGVyL1NoYXJlZFByZWZlcmVuY2VzRG93bmxvYWRNZXRhZGF0YS5qYXZhCkBAIC0wLDAgKzEsMTE1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmludGVncmF0aW9uLmRvd25sb2FkZXI7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuU2hhcmVkUHJlZmVyZW5jZXM7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkTWV0YWRhdGE7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKiBEb3dubG9hZE1ldGFkYXRhU3RvcmUgYmFzZWQgb24gU2hhcmVkUHJlZmVyZW5jZXMuICovCitwdWJsaWMgZmluYWwgY2xhc3MgU2hhcmVkUHJlZmVyZW5jZXNEb3dubG9hZE1ldGFkYXRhIGltcGxlbWVudHMgRG93bmxvYWRNZXRhZGF0YVN0b3JlIHsKKworICBwcml2YXRlIGZpbmFsIE9iamVjdCBsb2NrID0gbmV3IE9iamVjdCgpOworCisgIHByaXZhdGUgZmluYWwgU2hhcmVkUHJlZmVyZW5jZXMgc2hhcmVkUHJlZnM7CisgIHByaXZhdGUgZmluYWwgTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlIGJhY2tncm91bmRFeGVjdXRvcjsKKworICBwdWJsaWMgU2hhcmVkUHJlZmVyZW5jZXNEb3dubG9hZE1ldGFkYXRhKAorICAgICAgU2hhcmVkUHJlZmVyZW5jZXMgc2hhcmVkUHJlZnMsIExpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSBiYWNrZ3JvdW5kRXhlY3V0b3IpIHsKKyAgICB0aGlzLnNoYXJlZFByZWZzID0gc2hhcmVkUHJlZnM7CisgICAgdGhpcy5iYWNrZ3JvdW5kRXhlY3V0b3IgPSBiYWNrZ3JvdW5kRXhlY3V0b3I7CisgIH0KKworICAvKiogRGF0YSBmaWVsZHMgZm9yIGVhY2ggVVJJIHBlcnNpc3RlZCBpbiBTaGFyZWRQcmVmZXJlbmNlcy4gKi8KKyAgcHJpdmF0ZSBlbnVtIEtleSB7CisgICAgQ09OVEVOVF9UQUcoImN0IiksCisgICAgTEFTVF9NT0RJRklFRF9USU1FX1NFQ1MoImxtdHMiKTsKKworICAgIGZpbmFsIFN0cmluZyBzaGFyZWRQcmVmc1N1ZmZpeDsKKworICAgIEtleShTdHJpbmcgc2hhcmVkUHJlZnNTdWZmaXgpIHsKKyAgICAgIHRoaXMuc2hhcmVkUHJlZnNTdWZmaXggPSBzaGFyZWRQcmVmc1N1ZmZpeDsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BMSVRfQ0hBUiA9ICJ8IjsKKworICAvKiogUmV0dXJucyB0aGUgU2hhcmVkUHJlZmVyZW5jZXMga2V5IHVzZWQgdG8gc3RvcmUgdGhlIGdpdmVuIGRhdGEgZmllbGQgZm9yIHtAY29kZSB1cml9LiAqLworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0S2V5KFVyaSB1cmksIEtleSBrZXkpIHsKKyAgICByZXR1cm4gdXJpICsgU1BMSVRfQ0hBUiArIGtleS5zaGFyZWRQcmVmc1N1ZmZpeDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxPcHRpb25hbDxEb3dubG9hZE1ldGFkYXRhPj4gcmVhZChVcmkgdXJpKSB7CisgICAgcmV0dXJuIGJhY2tncm91bmRFeGVjdXRvci5zdWJtaXQoCisgICAgICAgICgpIC0+IHsKKyAgICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIC8vIENoZWNraW5nIGZvciBDT05URU5UX1RBRyBpcyBzdWZmaWNpZW50IHNpbmNlIHdlIHdpbGwgYWx3YXlzIHN0b3JlIGJvdGggdGhlIGNvbnRlbnQKKyAgICAgICAgICAgIC8vIHRhZyBhbmQgbGFzdCBtb2RpZmllZCB0aW1lc3RhbXAgaW4gdGhlIHNhbWUgY29tbWl0LgorICAgICAgICAgICAgaWYgKCFzaGFyZWRQcmVmcy5jb250YWlucyhnZXRLZXkodXJpLCBLZXkuQ09OVEVOVF9UQUcpKSkgeworICAgICAgICAgICAgICByZXR1cm4gT3B0aW9uYWwuYWJzZW50KCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFN0cmluZyBjb250ZW50VGFnID0gc2hhcmVkUHJlZnMuZ2V0U3RyaW5nKGdldEtleSh1cmksIEtleS5DT05URU5UX1RBRyksICIiKTsKKyAgICAgICAgICAgIGxvbmcgbGFzdE1vZGlmaWVkVGltZVNlY29uZHMgPQorICAgICAgICAgICAgICAgIHNoYXJlZFByZWZzLmdldExvbmcoZ2V0S2V5KHVyaSwgS2V5LkxBU1RfTU9ESUZJRURfVElNRV9TRUNTKSwgMCk7CisgICAgICAgICAgICByZXR1cm4gT3B0aW9uYWwub2YoRG93bmxvYWRNZXRhZGF0YS5jcmVhdGUoY29udGVudFRhZywgbGFzdE1vZGlmaWVkVGltZVNlY29uZHMpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0pOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHVwc2VydChVcmkgdXJpLCBEb3dubG9hZE1ldGFkYXRhIG1ldGFkYXRhKSB7CisgICAgcmV0dXJuIGJhY2tncm91bmRFeGVjdXRvci5zdWJtaXQoCisgICAgICAgICgpIC0+IHsKKyAgICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzLkVkaXRvciBlZGl0b3IgPSBzaGFyZWRQcmVmcy5lZGl0KCk7CisgICAgICAgICAgICBlZGl0b3IucHV0U3RyaW5nKGdldEtleSh1cmksIEtleS5DT05URU5UX1RBRyksIG1ldGFkYXRhLmdldENvbnRlbnRUYWcoKSk7CisgICAgICAgICAgICBlZGl0b3IucHV0TG9uZygKKyAgICAgICAgICAgICAgICBnZXRLZXkodXJpLCBLZXkuTEFTVF9NT0RJRklFRF9USU1FX1NFQ1MpLCBtZXRhZGF0YS5nZXRMYXN0TW9kaWZpZWRUaW1lU2Vjb25kcygpKTsKKyAgICAgICAgICAgIGNvbW1pdE9yVGhyb3coZWRpdG9yKTsKKworICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkZWxldGUoVXJpIHVyaSkgeworICAgIHJldHVybiBiYWNrZ3JvdW5kRXhlY3V0b3Iuc3VibWl0KAorICAgICAgICAoKSAtPiB7CisgICAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBTaGFyZWRQcmVmZXJlbmNlcy5FZGl0b3IgZWRpdG9yID0gc2hhcmVkUHJlZnMuZWRpdCgpOworICAgICAgICAgICAgZWRpdG9yLnJlbW92ZShnZXRLZXkodXJpLCBLZXkuQ09OVEVOVF9UQUcpKTsKKyAgICAgICAgICAgIGVkaXRvci5yZW1vdmUoZ2V0S2V5KHVyaSwgS2V5LkxBU1RfTU9ESUZJRURfVElNRV9TRUNTKSk7CisgICAgICAgICAgICBjb21taXRPclRocm93KGVkaXRvcik7CisKKyAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgIH0KKworICAvKiogQ2FsbHMge0Bjb2RlIGVkaXRvci5jb21taXQoKX0gYW5kIHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgY29tbWl0IGZhaWxlZC4gKi8KKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjb21taXRPclRocm93KFNoYXJlZFByZWZlcmVuY2VzLkVkaXRvciBlZGl0b3IpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKCFlZGl0b3IuY29tbWl0KCkpIHsKKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiRmFpbGVkIHRvIGNvbW1pdCIpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL21vbml0b3JzL0JVSUxEIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL21vbml0b3JzL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExZjBjYmQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvbW9uaXRvcnMvQlVJTEQKQEAgLTAsMCArMSwyOSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIm1vbml0b3JzIiwKKyAgICBzcmNzID0gWyJCeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL21vbml0b3JzL0J5dGVDb3VudGluZ091dHB1dE1vbml0b3IuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9tb25pdG9ycy9CeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjVkZjZjMQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9tb25pdG9ycy9CeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yLmphdmEKQEAgLTAsMCArMSw4NiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5tb25pdG9yczsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLk1vbml0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CisKKy8qKiBBbiBPdXRwdXRNb25pdG9yIHtAbGluayBNb25pdG9yLk91dHB1dE1vbml0b3J9IGNsYXNzIHRoYXQgY291bnRzIGJ5dGVzIHdyaXR0ZW4uICovCitwdWJsaWMgZmluYWwgY2xhc3MgQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvciBpbXBsZW1lbnRzIE1vbml0b3IuT3V0cHV0TW9uaXRvciB7CisKKyAgLyoqIEludGVyZmFjZSBvZiBTeXN0ZW1DbG9jay4gKi8KKyAgcHVibGljIGludGVyZmFjZSBDbG9jayB7CisgICAgLyoqIFJldHVybnMgdGhlIGN1cnJlbnQgc3lzdGVtIHRpbWUgaW4gbWlsbGlzZWNvbmRzIHNpbmNlIEphbnVhcnkgMSwgMTk3MCAwMDowMDowMCBVVEMuICovCisgICAgbG9uZyBjdXJyZW50VGltZU1pbGxpcygpOworICB9CisKKyAgcHJpdmF0ZSBmaW5hbCBDb3VudGVyIGNvdW50ZXI7CisgIHByaXZhdGUgZmluYWwgQ2xvY2sgY2xvY2s7CisKKyAgLy8gV2Ugd2lsbCBvbmx5IGZsdXNoIGNvdW50ZXJzIHRvIHN0b3JhZ2UgYXQgbW9zdCBvbmNlIGluIHRoaXMgdGltZSBmcmFtZS4KKyAgcHJpdmF0ZSBmaW5hbCBsb25nIGxvZ0ZyZXF1ZW5jeUluTWlsbGlzOworCisgIC8vIExhc3QgdGltZXN0YW1wIHRoYXQgd2UgZmx1c2hlZCBjb3VudGVycyB0byBzdG9yYWdlLgorICBwcml2YXRlIGxvbmcgbGFzdEZsdXNoVGltZXN0YW1wTXM7CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBCeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yIGluc3RhbmNlIHdpdGggdGhlIGdpdmVuIGNvdW50aW5nIGJlaGF2aW9yLgorICAgKgorICAgKiBAcGFyYW0gY291bnRlciBUaGUge0BsaW5rIENvdW50ZXJ9IGltcGxlbWVudGF0aW9uIGZvciBidWZmZXIgYW5kIGZsdXNoLgorICAgKiBAcGFyYW0gY2xvY2sgVGhlIHtAbGluayBDbG9ja30gaW5zdGFuY2UgdG8gYWxpZ24gYW5kIHRyYWNrIGNvdW50ZXIgb3BlcmF0aW9ucy4KKyAgICogQHBhcmFtIGxvZ0ZyZXF1ZW5jeSB7QGxpbmsgbG9uZ30gZGVzaXJlZCBpbnRlcnZhbCBiZXR3ZWVuIGVhY2ggc3VjY2Vzc2Z1bCBmbHVzaC4KKyAgICogQHBhcmFtIHRpbWVVbml0IHtAbGluayBUaW1lVW5pdH0gdW5pdCBvZiB0aW1lIGZvciBsb2dGcmVxdWVuY3kKKyAgICovCisgIHB1YmxpYyBCeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yKAorICAgICAgQ291bnRlciBjb3VudGVyLCBDbG9jayBjbG9jaywgbG9uZyBsb2dGcmVxdWVuY3ksIFRpbWVVbml0IHRpbWVVbml0KSB7CisgICAgdGhpcy5jb3VudGVyID0gY291bnRlcjsKKyAgICB0aGlzLmNsb2NrID0gY2xvY2s7CisgICAgdGhpcy5sb2dGcmVxdWVuY3lJbk1pbGxpcyA9IHRpbWVVbml0LnRvTWlsbGlzKGxvZ0ZyZXF1ZW5jeSk7CisgICAgbGFzdEZsdXNoVGltZXN0YW1wTXMgPSBjbG9jay5jdXJyZW50VGltZU1pbGxpcygpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBmaW5hbCB2b2lkIGJ5dGVzV3JpdHRlbihieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgeworICAgIGNvdW50ZXIuYnVmZmVyQ291bnRlcihsZW4pOworCisgICAgLy8gQ2hlY2sgaWYgZW5vdWdoIHRpbWUgaGFzIHBhc3NlZCBzaW5jZSB0aGUgbGFzdCBmbHVzaC4KKyAgICBpZiAoKGNsb2NrLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBsYXN0Rmx1c2hUaW1lc3RhbXBNcykgPj0gbG9nRnJlcXVlbmN5SW5NaWxsaXMpIHsKKyAgICAgIGNvdW50ZXIuZmx1c2hDb3VudGVyKCk7CisKKyAgICAgIC8vIFJlc2V0IHRpbWVzdGFtcC4KKyAgICAgIGxhc3RGbHVzaFRpbWVzdGFtcE1zID0gY2xvY2suY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgY2xvc2UoKSB7CisgICAgY291bnRlci5mbHVzaENvdW50ZXIoKTsKKyAgfQorCisgIHB1YmxpYyBDb3VudGVyIGdldENvdW50ZXIoKSB7CisgICAgcmV0dXJuIGNvdW50ZXI7CisgIH0KKworICAvKiogQSBDb3VudGVyIGludGVyZmFjZSB0byBoYW5kbGUgYnVmZmVyaW5nIGFuZCBmbHVzaGluZyBmb3IgcmF0ZS1saW1pdGluZyBiZWhhdmlvci4gKi8KKyAgcHVibGljIGludGVyZmFjZSBDb3VudGVyIHsKKworICAgIC8qKiBTYXZlcyBieXRlIGxlbmd0aCB0byBhbiBpbi1tZW1vcnkgYnVmZmVyIHRvIGxpbWl0IHdyaXRpbmcgdG8gZGlzay4gKi8KKyAgICB2b2lkIGJ1ZmZlckNvdW50ZXIoaW50IGxlbik7CisKKyAgICAvKiogTG9nIGN1cnJlbnRseSBjb3VudGVkIGJ5dGVzIHRvIGRpc2sgYW5kIHJlc2V0IHRoZSBjb3VudGVyLiAqLworICAgIHZvaWQgZmx1c2hDb3VudGVyKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL0FwcGVuZFN0cmVhbU9wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvQXBwZW5kU3RyZWFtT3BlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmZmNTU0MwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL0FwcGVuZFN0cmVhbU9wZW5lci5qYXZhCkBAIC0wLDAgKzEsNTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuQmVoYXZpb3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuQ29udGV4dDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5lcjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKiogQW4gb3BlbmVyIHRoYXQgcmV0dXJucyBhIHNpbXBsZSBPdXRwdXRTdHJlYW0gdGhhdCBhcHBlbmRzIHRvIHRoZSBmaWxlLiAqLworcHVibGljIGZpbmFsIGNsYXNzIEFwcGVuZFN0cmVhbU9wZW5lciBpbXBsZW1lbnRzIE9wZW5lcjxPdXRwdXRTdHJlYW0+IHsKKworICBwcml2YXRlIEJlaGF2aW9yW10gYmVoYXZpb3JzOworCisgIHByaXZhdGUgQXBwZW5kU3RyZWFtT3BlbmVyKCkge30KKworICBwdWJsaWMgc3RhdGljIEFwcGVuZFN0cmVhbU9wZW5lciBjcmVhdGUoKSB7CisgICAgcmV0dXJuIG5ldyBBcHBlbmRTdHJlYW1PcGVuZXIoKTsKKyAgfQorCisgIC8qKgorICAgKiBTdXBwb3J0cyBhZGRpbmcgb3B0aW9ucyB0byB3cml0ZXMuIEZvciBleGFtcGxlLCBTeW5jQmVoYXZpb3Igd2lsbCBmb3JjZSBkYXRhIHRvIGJlIGZsdXNoZWQgYW5kCisgICAqIGR1cmFibHkgcGVyc2lzdGVkLgorICAgKi8KKyAgcHVibGljIEFwcGVuZFN0cmVhbU9wZW5lciB3aXRoQmVoYXZpb3JzKEJlaGF2aW9yLi4uIGJlaGF2aW9ycykgeworICAgIHRoaXMuYmVoYXZpb3JzID0gYmVoYXZpb3JzOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBPdXRwdXRTdHJlYW0gb3BlbihPcGVuQ29udGV4dCBvcGVuQ29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBPdXRwdXRTdHJlYW0gYmFja2VuZE91dHB1dCA9IG9wZW5Db250ZXh0LmJhY2tlbmQoKS5vcGVuRm9yQXBwZW5kKG9wZW5Db250ZXh0LmVuY29kZWRVcmkoKSk7CisgICAgTGlzdDxPdXRwdXRTdHJlYW0+IGNoYWluID0gb3BlbkNvbnRleHQuY2hhaW5UcmFuc2Zvcm1zRm9yQXBwZW5kKGJhY2tlbmRPdXRwdXQpOworICAgIGlmIChiZWhhdmlvcnMgIT0gbnVsbCkgeworICAgICAgZm9yIChCZWhhdmlvciBiZWhhdmlvciA6IGJlaGF2aW9ycykgeworICAgICAgICBiZWhhdmlvci5mb3JPdXRwdXRDaGFpbihjaGFpbik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBjaGFpbi5nZXQoMCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL0Fzc2V0RmlsZURlc2NyaXB0b3JPcGVuZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL0Fzc2V0RmlsZURlc2NyaXB0b3JPcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjU4NDE0Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvQXNzZXRGaWxlRGVzY3JpcHRvck9wZW5lci5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5yZXMuQXNzZXRGaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBhbmRyb2lkLm9zLlBhcmNlbEZpbGVEZXNjcmlwdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBPcGVuZXIgdGhhdCByZXR1cm5zIGFuIEFzc2V0RmlsZURlc2NyaXB0b3IuIENhbGxlciBtdXN0IGNsb3NlIHRoZSBBc3NldEZpbGVEZXNjcmlwdG9yIHdoZW4gZG9uZQorICogcmVhZGluZyBmcm9tIGl0LiBEb2VzIG5vdCBzdXBwb3J0IE1vbml0b3JzIG9yIFRyYW5zZm9ybXMuCisgKgorICogPHA+VE9ETzogU3VwcG9ydCBvZmZzZXQgYW5kIGxlbmd0aC4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIEFzc2V0RmlsZURlc2NyaXB0b3JPcGVuZXIgaW1wbGVtZW50cyBPcGVuZXI8QXNzZXRGaWxlRGVzY3JpcHRvcj4geworCisgIHByaXZhdGUgQXNzZXRGaWxlRGVzY3JpcHRvck9wZW5lcigpIHt9CisKKyAgcHVibGljIHN0YXRpYyBBc3NldEZpbGVEZXNjcmlwdG9yT3BlbmVyIGNyZWF0ZSgpIHsKKyAgICByZXR1cm4gbmV3IEFzc2V0RmlsZURlc2NyaXB0b3JPcGVuZXIoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgQXNzZXRGaWxlRGVzY3JpcHRvciBvcGVuKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFBhcmNlbEZpbGVEZXNjcmlwdG9yT3BlbmVyIHBmZE9wZW5lciA9IFBhcmNlbEZpbGVEZXNjcmlwdG9yT3BlbmVyLmNyZWF0ZSgpOworICAgIFBhcmNlbEZpbGVEZXNjcmlwdG9yIHBmZCA9IHBmZE9wZW5lci5vcGVuKG9wZW5Db250ZXh0KTsKKyAgICAvLyBUT0RPKGIvMTE1OTMzMDE3KTogY29uc2lkZXIgd3JhcHBpbmcgdGhlIEFGRCB0byBmb3JjZSBpdCB0byBpbXBsZW1lbnQgQ2xvc2VhYmxlIG9uIGFsbCBzZGtzCisgICAgcmV0dXJuIG5ldyBBc3NldEZpbGVEZXNjcmlwdG9yKHBmZCwgMCwgcGZkLmdldFN0YXRTaXplKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1MTFkNTkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9CVUlMRApAQCAtMCwwICsxLDIxOSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImFzc2V0X2ZpbGVfZGVzY3JpcHRvciIsCisgICAgc3JjcyA9IFsiQXNzZXRGaWxlRGVzY3JpcHRvck9wZW5lci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpwYXJjZWxfZmlsZV9kZXNjcmlwdG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJyYW5kb21fYWNjZXNzX2ZpbGUiLAorICAgIHNyY3MgPSBbIlJhbmRvbUFjY2Vzc0ZpbGVPcGVuZXIuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiY2xvc2VhYmxlX3VyaSIsCisgICAgc3JjcyA9IFsiQ2xvc2VhYmxlVXJpLmphdmEiXSwKKykKKworIyBSZXF1aXJlcyBBUEkgbGV2ZWwgMjErCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJmaWxlIiwKKyAgICBzcmNzID0gWworICAgICAgICAiUGlwZXMuamF2YSIsCisgICAgICAgICJSZWFkRmlsZU9wZW5lci5qYXZhIiwKKyAgICAgICAgIldyaXRlRmlsZU9wZW5lci5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6c3RyZWFtIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICJAYW5kcm9pZHhfYW5ub3RhdGlvbl9hbm5vdGF0aW9uIiwgICMgYnVpbGRjbGVhbmVyOiBrZWVwCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAic3RyZWFtX211dGF0aW9uIiwKKyAgICBzcmNzID0gWyJTdHJlYW1NdXRhdGlvbk9wZW5lci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpsb2NrX2ZpbGUiLAorICAgICAgICAiOnNjcmF0Y2giLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIm5hdGl2ZSIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIk5hdGl2ZVJlYWRPcGVuZXIuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOmNsb3NlYWJsZV91cmkiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gInBhcmNlbF9maWxlX2Rlc2NyaXB0b3IiLAorICAgIHNyY3MgPSBbIlBhcmNlbEZpbGVEZXNjcmlwdG9yT3BlbmVyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZV9kZXNjcmlwdG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAicHJvdG8iLAorICAgIHNyY3MgPSBbCisgICAgICAgICJSZWFkUHJvdG9PcGVuZXIuamF2YSIsCisgICAgICAgICJXcml0ZVByb3RvT3BlbmVyLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpzY3JhdGNoIiwKKyAgICAgICAgIjpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzpwcm90b2J1Zl9saXRlIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJsb2NrX2ZpbGUiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJMb2NrRmlsZU9wZW5lci5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6cmFuZG9tX2FjY2Vzc19maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAicmVjdXJzaXZlX2RlbGV0ZSIsCisgICAgc3JjcyA9IFsiUmVjdXJzaXZlRGVsZXRlT3BlbmVyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsOmV4Y2VwdGlvbnMiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gInJlY3Vyc2l2ZV9zaXplIiwKKyAgICBzcmNzID0gWyJSZWN1cnNpdmVTaXplT3BlbmVyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gInN0cmVhbSIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkFwcGVuZFN0cmVhbU9wZW5lci5qYXZhIiwKKyAgICAgICAgIlJlYWRTdHJlYW1PcGVuZXIuamF2YSIsCisgICAgICAgICJXcml0ZVN0cmVhbU9wZW5lci5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImludGVncml0eV91cmlfY29tcHV0ZXIiLAorICAgIHNyY3MgPSBbIkludGVncml0eVVyaUNvbXB1dGluZ09wZW5lci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzOmNvbXB1dGVfdXJpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6aW50ZWdyaXR5IiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG9fZnJhZ21lbnRzIiwKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworIyBSZXF1aXJlcyBBUEkgbGV2ZWwgMjErCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJzeXN0ZW1fbGlicmFyeSIsCisgICAgc3JjcyA9IFsiU3lzdGVtTGlicmFyeU9wZW5lci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpmaWxlIiwKKyAgICAgICAgIjpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gInN0cmluZyIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlJlYWRTdHJpbmdPcGVuZXIuamF2YSIsCisgICAgICAgICJXcml0ZVN0cmluZ09wZW5lci5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6Ynl0ZXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsOmNoYXJzZXRzIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJieXRlcyIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlJlYWRCeXRlQXJyYXlPcGVuZXIuamF2YSIsCisgICAgICAgICJXcml0ZUJ5dGVBcnJheU9wZW5lci5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6c3RyZWFtIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAibWVtb3J5X21hcHBlZF9ieXRlcyIsCisgICAgc3JjcyA9IFsiTWFwcGVkQnl0ZUJ1ZmZlck9wZW5lci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJzY3JhdGNoIiwKKyAgICBzcmNzID0gWyJTY3JhdGNoRmlsZS5qYXZhIl0sCisgICAgdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9DbG9zZWFibGVVcmkuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL0Nsb3NlYWJsZVVyaS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEwNWVlNzEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9DbG9zZWFibGVVcmkuamF2YQpAQCAtMCwwICsxLDI0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CisKKy8qKiBBIHBhaXIgb2YgPFVSSSwgQ2xvc2VhYmxlPi4gT25jZSBjbG9zZWQgdGhlIFVSSSBpcyBubyBsb25nZXIgdmFsaWQuICovCitwdWJsaWMgaW50ZXJmYWNlIENsb3NlYWJsZVVyaSBleHRlbmRzIENsb3NlYWJsZSB7CisgIFVyaSB1cmkoKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL0ludGVncml0eVVyaUNvbXB1dGluZ09wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvSW50ZWdyaXR5VXJpQ29tcHV0aW5nT3BlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDY0M2E1MgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL0ludGVncml0eVVyaUNvbXB1dGluZ09wZW5lci5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmVoYXZpb3JzLlVyaUNvbXB1dGluZ0JlaGF2aW9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5JbnRlZ3JpdHlUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLlRyYW5zZm9ybVByb3RvRnJhZ21lbnRzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmlvLkJ5dGVTdHJlYW1zOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLlRyYW5zZm9ybVByb3RvOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CisKKy8qKiBBbiBvcGVuZXIgdGhhdCBwcm9kdWNlcyBhIFVSSSBhdWd1bWVudGVkIHdpdGggdGhlIEludGVncml0eVVyaUNvbXB1dGluZyBvZiB0aGUgaW5wdXQgVVJJLiAqLworcHVibGljIGZpbmFsIGNsYXNzIEludGVncml0eVVyaUNvbXB1dGluZ09wZW5lciBpbXBsZW1lbnRzIE9wZW5lcjxVcmk+IHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm0gREVGQVVMVF9TUEVDID0KKyAgICAgIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAuc2V0SW50ZWdyaXR5KFRyYW5zZm9ybVByb3RvLkludGVncml0eVRyYW5zZm9ybS5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAuYnVpbGQoKTsKKworICBwcml2YXRlIEludGVncml0eVVyaUNvbXB1dGluZ09wZW5lcigpIHt9CisKKyAgcHVibGljIHN0YXRpYyBJbnRlZ3JpdHlVcmlDb21wdXRpbmdPcGVuZXIgY3JlYXRlKCkgeworICAgIHJldHVybiBuZXcgSW50ZWdyaXR5VXJpQ29tcHV0aW5nT3BlbmVyKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFVyaSBvcGVuKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVyaSB1cmkgPSBvcGVuQ29udGV4dC5vcmlnaW5hbFVyaSgpOworCisgICAgdXJpID0gVHJhbnNmb3JtUHJvdG9GcmFnbWVudHMuYWRkT3JSZXBsYWNlVHJhbnNmb3JtKHVyaSwgREVGQVVMVF9TUEVDKTsKKyAgICBVcmlDb21wdXRpbmdCZWhhdmlvciB1cmlDb21wdXRlciA9IG5ldyBVcmlDb21wdXRpbmdCZWhhdmlvcih1cmkpOworICAgIHRyeSAoSW5wdXRTdHJlYW0gc3RyZWFtID0KKyAgICAgICAgb3BlbkNvbnRleHQuc3RvcmFnZSgpLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLndpdGhCZWhhdmlvcnModXJpQ29tcHV0ZXIpKSkgeworICAgICAgQnl0ZVN0cmVhbXMuZXhoYXVzdChzdHJlYW0pOworICAgICAgVXJpIHVyaVdpdGhEaWdlc3Q7CisgICAgICB0cnkgeworICAgICAgICB1cmlXaXRoRGlnZXN0ID0gdXJpQ29tcHV0ZXIudXJpRnV0dXJlKCkuZ2V0KCk7CisgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgIFRocmVhZC5jdXJyZW50VGhyZWFkKCkuaW50ZXJydXB0KCk7IC8vIHBlciA8aW50ZXJuYWw+CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlKTsKKyAgICAgIH0gY2F0Y2ggKEV4ZWN1dGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIGlmIChlLmdldENhdXNlKCkgaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikgeworICAgICAgICAgIHRocm93IChJT0V4Y2VwdGlvbikgZS5nZXRDYXVzZSgpOworICAgICAgICB9CisgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlKTsKKyAgICAgIH0KKyAgICAgIFN0cmluZyBiYXNlNjREaWdlc3QgPSBJbnRlZ3JpdHlUcmFuc2Zvcm0uZ2V0RGlnZXN0SWZQcmVzZW50KHVyaVdpdGhEaWdlc3QpOworICAgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtIG5ld1NwZWMgPQorICAgICAgICAgIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgLnNldEludGVncml0eShUcmFuc2Zvcm1Qcm90by5JbnRlZ3JpdHlUcmFuc2Zvcm0ubmV3QnVpbGRlcigpLnNldFNoYTI1NihiYXNlNjREaWdlc3QpKQorICAgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAgIHJldHVybiBUcmFuc2Zvcm1Qcm90b0ZyYWdtZW50cy5hZGRPclJlcGxhY2VUcmFuc2Zvcm0odXJpV2l0aERpZ2VzdCwgbmV3U3BlYyk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9Mb2NrRmlsZU9wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvTG9ja0ZpbGVPcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjA4ZWMyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvTG9ja0ZpbGVPcGVuZXIuamF2YQpAQCAtMCwwICsxLDE4MiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uRmlsZUNoYW5uZWxDb252ZXJ0aWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5SZWxlYXNhYmxlUmVzb3VyY2U7CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGU7CitpbXBvcnQgamF2YS5uaW8uY2hhbm5lbHMuRmlsZUNoYW5uZWw7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5OdWxsYWJsZTsKKworLyoqCisgKiBBbiBvcGVuZXIgZm9yIGFjcXVpcmluZyBsb2NrIGZpbGVzLgorICoKKyAqIDxwPkxvY2sgZmlsZXMgYXJlIHVzZWQgdG8gc2VwYXJhdGUgbG9jayBhY3F1aXNpdGlvbiBmcm9tIElPIG9uIHRoZSB0YXJnZXQgZmlsZSBpdHNlbGYuIEZvciBhCisgKiB0YXJnZXQgZmlsZSAiZGF0YS50eHQiLCBhbiBhc3NvY2lhdGVkIGxvY2sgZmlsZSAiZGF0YS50eHQubG9jayIgaXMgY3JlYXRlZCBhbmQgdXNlZCB0byBjb250cm9sCisgKiBsb2NraW5nIGluc3RlYWQgb2YgYWNxdWlyaW5nIGEgZmlsZSBsb2NrIG9uICJkYXRhLnR4dCIgaXRzZWxmLiBUaGlzIG1lYW5zIHRoZSBsb2NrIGhvbGRlciBjYW4KKyAqIHBlcmZvcm0gYSB3aWRlciByYW5nZSBvZiBvcGVyYXRpb25zIG9uIHRoZSB0YXJnZXQgZmlsZSB0aGFuIHdvdWxkIGhhdmUgYmVlbiBwb3NzaWJsZSB3aXRoIGEKKyAqIHNpbXBsZSBmaWxlIGxvY2sgb24gdGhlIHRhcmdldDsgdGhlIGxvY2sgYWN0cyBhcyBhbiBpbmRlcGVuZGVudCBzZW1hcGhvcmUuCisgKgorICogPHA+Tm90ZSB0aGF0IHRoaXMgb3BlbmVyIGlzIGluY29tcGF0aWJsZSB3aXRoIG9wYXF1ZSBVUklzLCBlLmcuICJmaWxlOi8vL2Zvby50eHQiIGlzIGNvbXBhdGlibGUKKyAqIHdoZXJlYXMgIm1lbW9yeTpmb28udHh0IiBpcyBub3QuCisgKgorICogPHA+VE9ETzogY29uc2lkZXIgYWxsb3dpbmcgY2xpZW50IHRvIHNwZWNpZnkgbG9jayBmaWxlIGluIG9yZGVyIHRvIHN1cHBvcnQgb3BhcXVlIFVSSXMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBMb2NrRmlsZU9wZW5lciBpbXBsZW1lbnRzIE9wZW5lcjxDbG9zZWFibGU+IHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9DS19TVUZGSVggPSAiLmxvY2siOworCisgIHByaXZhdGUgZmluYWwgYm9vbGVhbiBzaGFyZWQ7CisgIHByaXZhdGUgZmluYWwgYm9vbGVhbiByZWFkT25seTsKKyAgcHJpdmF0ZSBib29sZWFuIGlzTm9uQmxvY2tpbmc7CisKKyAgcHJpdmF0ZSBMb2NrRmlsZU9wZW5lcihib29sZWFuIHNoYXJlZCwgYm9vbGVhbiByZWFkT25seSkgeworICAgIHRoaXMuc2hhcmVkID0gc2hhcmVkOworICAgIHRoaXMucmVhZE9ubHkgPSByZWFkT25seTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIHRoYXQgd2lsbCBhY3F1aXJlIGFuIGV4Y2x1c2l2ZSBsb2NrIG9uIHRoZSBmaWxlLiB7QGxpbmsgI29wZW59IHdpbGwgY3JlYXRlCisgICAqIHRoZSBsb2NrIGZpbGUgaWYgaXQgZG9lc24ndCBhbHJlYWR5IGV4aXN0LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBMb2NrRmlsZU9wZW5lciBjcmVhdGVFeGNsdXNpdmUoKSB7CisgICAgcmV0dXJuIG5ldyBMb2NrRmlsZU9wZW5lcigvKiBzaGFyZWQ9ICovIGZhbHNlLCAvKiByZWFkT25seT0gKi8gZmFsc2UpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2UgdGhhdCB3aWxsIGFjcXVpcmUgYSBzaGFyZWQgbG9jayBvbiB0aGUgZmlsZSAoc2hhcmVkIGFjcm9zcyBwcm9jZXNzZXM7CisgICAqIG11bHRpcGxlIHRocmVhZHMgaW4gdGhlIHNhbWUgcHJvY2VzcyBleGNsdWRlIG9uZSBhbm90aGVyKS4ge0BsaW5rICNvcGVufSB3b24ndCBjcmVhdGUgdGhlIGxvY2sKKyAgICogZmlsZSBpZiBpdCBkb2Vzbid0IGFscmVhZHkgZXhpc3QgKGluc3RlYWQgdGhyb3dpbmcge0Bjb2RlIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbn0pLCBtZWFuaW5nIHRoaXMKKyAgICogb3BlbmVyIGlzIHJlYWQtb25seS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgTG9ja0ZpbGVPcGVuZXIgY3JlYXRlUmVhZE9ubHlTaGFyZWQoKSB7CisgICAgcmV0dXJuIG5ldyBMb2NrRmlsZU9wZW5lcigvKiBzaGFyZWQ9ICovIHRydWUsIC8qIHJlYWRPbmx5PSAqLyB0cnVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIHRoYXQgd2lsbCBhY3F1aXJlIGEgc2hhcmVkIGxvY2sgb24gdGhlIGZpbGUgKHNoYXJlZCBhY3Jvc3MgcHJvY2Vzc2VzOworICAgKiBtdWx0aXBsZSB0aHJlYWRzIGluIHRoZSBzYW1lIHByb2Nlc3MgZXhjbHVkZSBvbmUgYW5vdGhlcikuIHtAbGluayAjb3Blbn0gKndpbGwqIGNyZWF0ZSB0aGUgbG9jaworICAgKiBmaWxlIGlmIGl0IGRvZXNuJ3QgYWxyZWFkeSBleGlzdC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgTG9ja0ZpbGVPcGVuZXIgY3JlYXRlU2hhcmVkKCkgeworICAgIHJldHVybiBuZXcgTG9ja0ZpbGVPcGVuZXIoLyogc2hhcmVkPSAqLyB0cnVlLCAvKiByZWFkT25seT0gKi8gZmFsc2UpOworICB9CisKKyAgLyoqCisgICAqIElmIGVuYWJsZWQgYW5kIHRoZSBsb2NrIGNhbm5vdCBiZSBhY3F1aXJlZCBpbW1lZGlhdGVseSwge0BsaW5rICNvcGVufSB3aWxsIHJldHVybiB7QGNvZGUgbnVsbH0KKyAgICogaW5zdGVhZCBvZiB3YWl0aW5nIHVudGlsIHRoZSBsb2NrIGNhbiBiZSBhY3F1aXJlZC4KKyAgICovCisgIHB1YmxpYyBMb2NrRmlsZU9wZW5lciBub25CbG9ja2luZyhib29sZWFuIGlzTm9uQmxvY2tpbmcpIHsKKyAgICB0aGlzLmlzTm9uQmxvY2tpbmcgPSBpc05vbkJsb2NraW5nOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLy8gVE9ETyhiLzEzMTE4MDcyMik6IGNvbnNpZGVyIGFkZGluZyBvcHRpb24gZm9yIGJsb2NraW5nIHdpdGggdGltZW91dAorCisgIEBPdmVycmlkZQorICBATnVsbGFibGUKKyAgcHVibGljIENsb3NlYWJsZSBvcGVuKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIC8vIENsZWFyaW5nIGZyYWdtZW50IGlzIG5lY2Vzc2FyeSB0byBvcGVuIGEgRmlsZUNoYW5uZWxDb252ZXJ0aWJsZSBzdHJlYW0uCisgICAgVXJpIGxvY2tVcmkgPQorICAgICAgICBvcGVuQ29udGV4dAorICAgICAgICAgICAgLm9yaWdpbmFsVXJpKCkKKyAgICAgICAgICAgIC5idWlsZFVwb24oKQorICAgICAgICAgICAgLnBhdGgob3BlbkNvbnRleHQuZW5jb2RlZFVyaSgpLmdldFBhdGgoKSArIExPQ0tfU1VGRklYKQorICAgICAgICAgICAgLmZyYWdtZW50KCIiKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICB0cnkgKFJlbGVhc2FibGVSZXNvdXJjZTxDbG9zZWFibGU+IHRocmVhZExvY2tSZXNvdXJjZSA9CisgICAgICAgIFJlbGVhc2FibGVSZXNvdXJjZS5jcmVhdGUob3BlblRocmVhZExvY2sob3BlbkNvbnRleHQsIGxvY2tVcmkpKSkgeworICAgICAgaWYgKHRocmVhZExvY2tSZXNvdXJjZS5nZXQoKSA9PSBudWxsKSB7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorCisgICAgICB0cnkgKFJlbGVhc2FibGVSZXNvdXJjZTxDbG9zZWFibGU+IHN0cmVhbVJlc291cmNlID0KKyAgICAgICAgICAgICAgUmVsZWFzYWJsZVJlc291cmNlLmNyZWF0ZShvcGVuU3RyZWFtRm9yTG9ja2luZyhvcGVuQ29udGV4dCwgbG9ja1VyaSkpOworICAgICAgICAgIFJlbGVhc2FibGVSZXNvdXJjZTxDbG9zZWFibGU+IGZpbGVMb2NrUmVzb3VyY2UgPQorICAgICAgICAgICAgICBSZWxlYXNhYmxlUmVzb3VyY2UuY3JlYXRlKG9wZW5GaWxlTG9jayhvcGVuQ29udGV4dCwgc3RyZWFtUmVzb3VyY2UuZ2V0KCkpKSkgeworICAgICAgICBpZiAoZmlsZUxvY2tSZXNvdXJjZS5nZXQoKSA9PSBudWxsKSB7CisgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0KKworICAgICAgICAvLyBUaGUgdGhyZWFkIGxvY2sgZ3VhcmRzIGFjY2VzcyB0byB0aGUgc3RyZWFtIGFuZCBmaWxlIGxvY2sgc28gKm11c3QqIGJlIGNsb3NlZCBsYXN0LCBhbmQKKyAgICAgICAgLy8gYSBmaWxlIGxvY2sgbXVzdCBiZSBjbG9zZWQgYmVmb3JlIGl0cyB1bmRlcmx5aW5nIGZpbGUgc28gKm11c3QqIGJlIGNsb3NlZCBmaXJzdC4KKyAgICAgICAgQ2xvc2VhYmxlIHRocmVhZExvY2sgPSB0aHJlYWRMb2NrUmVzb3VyY2UucmVsZWFzZSgpOworICAgICAgICBDbG9zZWFibGUgc3RyZWFtID0gc3RyZWFtUmVzb3VyY2UucmVsZWFzZSgpOworICAgICAgICBDbG9zZWFibGUgZmlsZUxvY2sgPSBmaWxlTG9ja1Jlc291cmNlLnJlbGVhc2UoKTsKKyAgICAgICAgcmV0dXJuICgpIC0+IHsKKyAgICAgICAgICB0cnkgKENsb3NlYWJsZSBsYXN0ID0gdGhyZWFkTG9jazsKKyAgICAgICAgICAgICAgQ2xvc2VhYmxlIG1pZGRsZSA9IHN0cmVhbTsKKyAgICAgICAgICAgICAgQ2xvc2VhYmxlIGZpcnN0ID0gZmlsZUxvY2spIHt9CisgICAgICAgIH07CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEFjcXVpcmVzIChvciB0cmllcyB0byBhY3F1aXJlKSB0aGUgY3Jvc3MtdGhyZWFkIGxvY2sgZm9yIHtAY29kZSBsb2NrVXJpfS4gVGhpcyBpcyBhCisgICAqIHN1Yi1vcGVyYXRpb24gb2Yge0BsaW5rICNvcGVufS4KKyAgICovCisgIEBOdWxsYWJsZQorICBwcml2YXRlIENsb3NlYWJsZSBvcGVuVGhyZWFkTG9jayhPcGVuQ29udGV4dCBvcGVuQ29udGV4dCwgVXJpIGxvY2tVcmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGlzTm9uQmxvY2tpbmcpIHsKKyAgICAgIHJldHVybiBvcGVuQ29udGV4dC5iYWNrZW5kKCkubG9ja1Njb3BlKCkudHJ5VGhyZWFkTG9jayhsb2NrVXJpKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIG9wZW5Db250ZXh0LmJhY2tlbmQoKS5sb2NrU2NvcGUoKS50aHJlYWRMb2NrKGxvY2tVcmkpOworICAgIH0KKyAgfQorCisgIC8qKiBPcGVucyBhIHN0cmVhbSB0byB7QGNvZGUgbG9ja1VyaX0uIFRoaXMgaXMgYSBzdWItb3BlcmF0aW9uIG9mIHtAbGluayAjb3Blbn0uICovCisgIHByaXZhdGUgQ2xvc2VhYmxlIG9wZW5TdHJlYW1Gb3JMb2NraW5nKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0LCBVcmkgbG9ja1VyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoc2hhcmVkICYmIHJlYWRPbmx5KSB7CisgICAgICByZXR1cm4gb3BlbkNvbnRleHQuYmFja2VuZCgpLm9wZW5Gb3JSZWFkKGxvY2tVcmkpOworICAgIH0gZWxzZSBpZiAoc2hhcmVkICYmICFyZWFkT25seSkgeworICAgICAgcmV0dXJuIG9wZW5Db250ZXh0LnN0b3JhZ2UoKS5vcGVuKGxvY2tVcmksIFJhbmRvbUFjY2Vzc0ZpbGVPcGVuZXIuY3JlYXRlRm9yUmVhZFdyaXRlKCkpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gb3BlbkNvbnRleHQuYmFja2VuZCgpLm9wZW5Gb3JXcml0ZShsb2NrVXJpKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQWNxdWlyZXMgKG9yIHRyaWVzIHRvIGFjcXVpcmUpIHRoZSBjcm9zcy1wcm9jZXNzIGxvY2sgZm9yIHtAY29kZSBzdHJlYW19LiBGYWlscyBpZiB0aGUgc3RyZWFtCisgICAqIGNhbid0IGJlIGNvbnZlcnRlZCB0byBGaWxlQ2hhbm5lbC4gVGhpcyBpcyBhIHN1Yi1vcGVyYXRpb24gb2Yge0BsaW5rICNvcGVufS4KKyAgICovCisgIEBOdWxsYWJsZQorICBwcml2YXRlIENsb3NlYWJsZSBvcGVuRmlsZUxvY2soT3BlbkNvbnRleHQgb3BlbkNvbnRleHQsIENsb3NlYWJsZSBjbG9zZWFibGUpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZUNoYW5uZWwgY2hhbm5lbCA9IGdldEZpbGVDaGFubmVsRnJvbUNsb3NlYWJsZShjbG9zZWFibGUpOworICAgIGlmIChpc05vbkJsb2NraW5nKSB7CisgICAgICByZXR1cm4gb3BlbkNvbnRleHQuYmFja2VuZCgpLmxvY2tTY29wZSgpLnRyeUZpbGVMb2NrKGNoYW5uZWwsIHNoYXJlZCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBvcGVuQ29udGV4dC5iYWNrZW5kKCkubG9ja1Njb3BlKCkuZmlsZUxvY2soY2hhbm5lbCwgc2hhcmVkKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBGaWxlQ2hhbm5lbCBnZXRGaWxlQ2hhbm5lbEZyb21DbG9zZWFibGUoQ2xvc2VhYmxlIGNsb3NlYWJsZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBUT0RPKGIvMTgxMTE5NjQyKTogVXBkYXRlIGNvZGUgc28gd2UgYXJlIG5vdCBjYXNpbmcgb24gaW5zdGFuY2VvZi4KKyAgICBpZiAoY2xvc2VhYmxlIGluc3RhbmNlb2YgRmlsZUNoYW5uZWxDb252ZXJ0aWJsZSkgeworICAgICAgcmV0dXJuICgoRmlsZUNoYW5uZWxDb252ZXJ0aWJsZSkgY2xvc2VhYmxlKS50b0ZpbGVDaGFubmVsKCk7CisgICAgfSBlbHNlIGlmIChjbG9zZWFibGUgaW5zdGFuY2VvZiBSYW5kb21BY2Nlc3NGaWxlKSB7CisgICAgICByZXR1cm4gKChSYW5kb21BY2Nlc3NGaWxlKSBjbG9zZWFibGUpLmdldENoYW5uZWwoKTsKKyAgICB9IGVsc2UgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJMb2NrIHN0cmVhbSBub3QgY29udmVydGlibGUgdG8gRmlsZUNoYW5uZWwiKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL01hcHBlZEJ5dGVCdWZmZXJPcGVuZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL01hcHBlZEJ5dGVCdWZmZXJPcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMzkwZTMxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvTWFwcGVkQnl0ZUJ1ZmZlck9wZW5lci5qYXZhCkBAIC0wLDAgKzEsNTggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uRmlsZUNoYW5uZWxDb252ZXJ0aWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5VbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5pby5NYXBwZWRCeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsOworaW1wb3J0IGphdmEubmlvLmNoYW5uZWxzLkZpbGVDaGFubmVsLk1hcE1vZGU7CisKKy8qKgorICogT3BlbmVyIHRoYXQgbWFwcyBhIGZpbGUgZGlyZWN0bHkgaW50byBtZW1vcnkgKHJlYWQgb25seSkuCisgKgorICogPHA+V2FybmluZzogTWFwcGVkQnl0ZUJ1ZmZlciBpcyBrbm93biB0byBzdWZmZXIgZnJvbSBwb29yIGdhcmJhZ2UgY29sbGVjdGlvbjsgc2VlIHtAbGluaworICogPGludGVybmFsPn0uCisgKgorICogPHA+VXNhZ2U6IDxjb2RlPgorICogTWFwcGVkQnl0ZUJ1ZmZlciBidWZmZXIgPSBzdG9yYWdlLm9wZW4odXJpLCBNYXBwZWRCeXRlQnVmZmVyT3BlbmVyLmNyZWF0ZSgpKTsKKyAqIDwvY29kZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE1hcHBlZEJ5dGVCdWZmZXJPcGVuZXIgaW1wbGVtZW50cyBPcGVuZXI8TWFwcGVkQnl0ZUJ1ZmZlcj4geworCisgIHByaXZhdGUgTWFwcGVkQnl0ZUJ1ZmZlck9wZW5lcigpIHt9CisKKyAgcHVibGljIHN0YXRpYyBNYXBwZWRCeXRlQnVmZmVyT3BlbmVyIGNyZWF0ZUZvclJlYWQoKSB7CisgICAgcmV0dXJuIG5ldyBNYXBwZWRCeXRlQnVmZmVyT3BlbmVyKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE1hcHBlZEJ5dGVCdWZmZXIgb3BlbihPcGVuQ29udGV4dCBvcGVuQ29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBGaWxlQ2hhbm5lbENvbnZlcnRpYmxlICh2cyBSZWFkRmlsZU9wZW5lcikgYWxsb3dzIHRoaXMgb3BlbmVyIHRvIGJlIHVzZWQgb3ZlciBJUEMuCisgICAgdHJ5IChJbnB1dFN0cmVhbSBzdHJlYW0gPSBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLm9wZW4ob3BlbkNvbnRleHQpKSB7CisgICAgICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgRmlsZUNoYW5uZWxDb252ZXJ0aWJsZSkgeworICAgICAgICBGaWxlQ2hhbm5lbCBmaWxlQ2hhbm5lbCA9ICgoRmlsZUNoYW5uZWxDb252ZXJ0aWJsZSkgc3RyZWFtKS50b0ZpbGVDaGFubmVsKCk7CisgICAgICAgIHJldHVybiBmaWxlQ2hhbm5lbC5tYXAoTWFwTW9kZS5SRUFEX09OTFksIDAsIGZpbGVDaGFubmVsLnNpemUoKSk7CisgICAgICB9CisgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbigKKyAgICAgICAgICAiVVJJIG5vdCBjb252ZXJ0aWJsZSB0byBGaWxlQ2hhbm5lbCBmb3IgbWFwcGluZzogIiArIG9wZW5Db250ZXh0Lm9yaWdpbmFsVXJpKCkpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvTmF0aXZlUmVhZE9wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvTmF0aXZlUmVhZE9wZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFhN2QzOGMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9OYXRpdmVSZWFkT3BlbmVyLmphdmEKQEAgLTAsMCArMSw2OSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqCisgKiBBbiBvcGVuZXIgdGhhdCBwcm9kdWNlcyBhIGZpbGUgZGVzY3JpcHRvciBVUkkgKGxpa2UgImZkOjEyMyIpLiBUaGlzIGlzIHVzZWZ1bCBmb3Igb3BlbmluZyBhIGZpbGUKKyAqIGluIEphdmEgYW5kIHBhc3NpbmcgYSBoYW5kbGUgdG8gaXQgZG93biB0byBDKysuCisgKgorICogPHA+VHJhbnNmb3JtcyBhcmUgbm90IGFwcGxpZWQgaW4gdGhlIEphdmEgY29kZSBhbmQgYXJlIHJldGFpbmVkIGluIHRoZSByZXR1cm5lZCBVUkkgc28gdGhleSBjYW4KKyAqIGJlIGFwcGxpZWQgaW4gbmF0aXZlIGNvZGUuCisgKgorICogPHA+VGhlIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgY2xvc2luZyB0aGUgZmlsZSBkZXNjcmlwdG9yLiBUaGUgbmF0aXZlIGNvZGUgaXMgZXhwZWN0ZWQgdG8gZHVwCisgKiB0aGUgZGVzY3JpcHRvciBpZiBpdCBuZWVkcyB0byBob2xkIGl0LCBzbyB0aGV5IGNhbiBib3RoIGNhbGwgY2xvc2UgaW5kZXBlbmRlbnRseS4KKyAqCisgKiA8cD5Vc2FnZTogPGNvZGU+CisgKiB0cnkgKENsb3NlYWJsZVVyaSBmZFVyaSA9IHN0b3JhZ2Uub3Blbih1cmksIE5hdGl2ZVJlYWRPcGVuZXIuY3JlYXRlKCkpKSB7CisgKiAgIC8vIFVzZSBVUkkgaW4gbmF0aXZlIGNvZGUKKyAqIH0KKyAqIDwvY29kZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIE5hdGl2ZVJlYWRPcGVuZXIgaW1wbGVtZW50cyBPcGVuZXI8Q2xvc2VhYmxlVXJpPiB7CisgIHByaXZhdGUgTmF0aXZlUmVhZE9wZW5lcigpIHt9CisKKyAgcHVibGljIHN0YXRpYyBOYXRpdmVSZWFkT3BlbmVyIGNyZWF0ZSgpIHsKKyAgICByZXR1cm4gbmV3IE5hdGl2ZVJlYWRPcGVuZXIoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgQ2xvc2VhYmxlVXJpIG9wZW4oT3BlbkNvbnRleHQgb3BlbkNvbnRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUGFpcjxVcmksIENsb3NlYWJsZT4gcmVzdWx0ID0gb3BlbkNvbnRleHQuYmFja2VuZCgpLm9wZW5Gb3JOYXRpdmVSZWFkKG9wZW5Db250ZXh0LmVuY29kZWRVcmkoKSk7CisgICAgVXJpIHVyaVdpdGhGcmFnbWVudCA9CisgICAgICAgIHJlc3VsdAorICAgICAgICAgICAgLmZpcnN0CisgICAgICAgICAgICAuYnVpbGRVcG9uKCkKKyAgICAgICAgICAgIC5lbmNvZGVkRnJhZ21lbnQob3BlbkNvbnRleHQub3JpZ2luYWxVcmkoKS5nZXRFbmNvZGVkRnJhZ21lbnQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHJldHVybiBuZXcgQ2xvc2VhYmxlVXJpKCkgeworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgVXJpIHVyaSgpIHsKKyAgICAgICAgcmV0dXJuIHVyaVdpdGhGcmFnbWVudDsKKyAgICAgIH0KKworICAgICAgQE92ZXJyaWRlCisgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgIHJlc3VsdC5zZWNvbmQuY2xvc2UoKTsKKyAgICAgIH0KKyAgICB9OworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9QYXJjZWxGaWxlRGVzY3JpcHRvck9wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUGFyY2VsRmlsZURlc2NyaXB0b3JPcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MTI1Y2E2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUGFyY2VsRmlsZURlc2NyaXB0b3JPcGVuZXIuamF2YQpAQCAtMCwwICsxLDU5IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5QYXJjZWxGaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuRmlsZURlc2NyaXB0b3JVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworCisvKioKKyAqIE9wZW5lciB0aGF0IHJldHVybnMgYW4gUGFyY2VsRmlsZURlc2NyaXB0b3IuIENhbGxlciBtdXN0IGNsb3NlIHRoZSBQYXJjZWxGaWxlRGVzY3JpcHRvciB3aGVuIGRvbmUKKyAqIHJlYWRpbmcgZnJvbSBpdC4gRG9lcyBub3Qgc3VwcG9ydCBNb25pdG9ycyBvciBUcmFuc2Zvcm1zLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUGFyY2VsRmlsZURlc2NyaXB0b3JPcGVuZXIgaW1wbGVtZW50cyBPcGVuZXI8UGFyY2VsRmlsZURlc2NyaXB0b3I+IHsKKworICBwcml2YXRlIFBhcmNlbEZpbGVEZXNjcmlwdG9yT3BlbmVyKCkge30KKworICBwdWJsaWMgc3RhdGljIFBhcmNlbEZpbGVEZXNjcmlwdG9yT3BlbmVyIGNyZWF0ZSgpIHsKKyAgICByZXR1cm4gbmV3IFBhcmNlbEZpbGVEZXNjcmlwdG9yT3BlbmVyKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFBhcmNlbEZpbGVEZXNjcmlwdG9yIG9wZW4oT3BlbkNvbnRleHQgb3BlbkNvbnRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUGFpcjxVcmksIENsb3NlYWJsZT4gcmVzdWx0ID0gb3BlbkNvbnRleHQuYmFja2VuZCgpLm9wZW5Gb3JOYXRpdmVSZWFkKG9wZW5Db250ZXh0LmVuY29kZWRVcmkoKSk7CisgICAgdHJ5IHsKKyAgICAgIGlmIChvcGVuQ29udGV4dC5oYXNUcmFuc2Zvcm1zKCkpIHsKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oCisgICAgICAgICAgICAiQWNjZXNzaW5nIGZpbGUgZGVzY3JpcHRvciBkaXJlY3RseSB3b3VsZCBza2lwIHRyYW5zZm9ybXMgZm9yICIKKyAgICAgICAgICAgICAgICArIG9wZW5Db250ZXh0Lm9yaWdpbmFsVXJpKCkpOworICAgICAgfQorCisgICAgICBpbnQgbmF0aXZlRmQgPSBGaWxlRGVzY3JpcHRvclVyaS5nZXRGZChyZXN1bHQuZmlyc3QpOworICAgICAgLy8gTk9URTogQ291bGQgYWxzbyB1c2UgYWRvcHRGZCB0byBhdm9pZCBkdXAgYW5kIGNsb3Npbmcgb3JpZ2luYWwsIGJ1dCBpdCdzIHNsaWdodGx5CisgICAgICAvLyBjbGVhbmVyIHRoaXMgd2F5IHRvIGVuc3VyZSB0aGF0IHdlIGNhbm5vdCBsZWFrIGZpbGUgZGVzY3JpcHRvcnMgd2hlbiBleGNlcHRpb24gaXMgdGhyb3duLgorICAgICAgLy8gVE9ETyhiLzExNTkzMzAxNyk6IGNvbnNpZGVyIHdyYXBwaW5nIHRoZSBQRkQgdG8gZm9yY2UgaXQgdG8gaW1wbGVtZW50IENsb3NlYWJsZSBvbiBhbGwgc2RrcworICAgICAgcmV0dXJuIFBhcmNlbEZpbGVEZXNjcmlwdG9yLmZyb21GZChuYXRpdmVGZCk7CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIHJlc3VsdC5zZWNvbmQuY2xvc2UoKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1BpcGVzLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9QaXBlcy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRiNDZlODQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9QaXBlcy5qYXZhCkBAIC0wLDAgKzEsODcgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IGFuZHJvaWQuYW5ub3RhdGlvbi5UYXJnZXRBcGk7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZDsKK2ltcG9ydCBhbmRyb2lkLm9zLlByb2Nlc3M7CitpbXBvcnQgYW5kcm9pZC5zeXN0ZW0uRXJybm9FeGNlcHRpb247CitpbXBvcnQgYW5kcm9pZC5zeXN0ZW0uT3M7CitpbXBvcnQgYW5kcm9pZC5zeXN0ZW0uT3NDb25zdGFudHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRnV0dXJlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworCisvKiogU3RhdGljIHV0aWxpdHkgbWV0aG9kcyBwZXJ0YWluaW5nIHRvIFBvc2l4IHBpcGVzIGFuZCBzdHJlYW1pbmcgZGF0YSB0aHJvdWdoIHRoZW0uICovCitmaW5hbCBjbGFzcyBQaXBlcyB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1ZX1BJRCA9IFByb2Nlc3MubXlQaWQoKTsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIG5hbWVkIHBpcGUgKEZJRk8pIGluIHtAY29kZSBkaXJlY3Rvcnl9IHRoYXQncyBndWFyYW50ZWVkIHRvIG5vdCBjb2xsaWRlIHdpdGggYW55CisgICAqIG90aGVyIHJ1bm5pbmcgcHJvY2Vzcy4ge0Bjb2RlIHRhZ30gYW5kIHtAY29kZSBpZEdlbmVyYXRvcn0gc2hvdWxkIGJlIHN0YXRpYyBhbmQgc3BlY2lmaWMgdG8gdGhlCisgICAqIGNhbGxlcidzIGNsYXNzIGluIG9yZGVyIHRvIGF2b2lkIG5hbWluZyBjb2xsaXNpb25zIHdpdGggb3RoZXIgY2FsbGVycyB3aXRoaW4gdGhlIHNhbWUgcHJvY2Vzcy4KKyAgICoKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgRklGTyBjYW5ub3QgYmUgY3JlYXRlZCBvciBpcyBub3Qgc3VwcG9ydGVkIGF0IHRoaXMgU0RLIGxldmVsICgyMSspCisgICAqLworICBAVGFyZ2V0QXBpKEJ1aWxkLlZFUlNJT05fQ09ERVMuTE9MTElQT1ApIC8vIGZvciBFcnJub0V4Y2VwdGlvbiwgT3MsIGFuZCBPc0NvbnN0YW50cworICBzdGF0aWMgRmlsZSBtYWtlRmlmbyhGaWxlIGRpcmVjdG9yeSwgU3RyaW5nIHRhZywgQXRvbWljSW50ZWdlciBpZEdlbmVyYXRvcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoQnVpbGQuVkVSU0lPTi5TREtfSU5UIDwgQnVpbGQuVkVSU0lPTl9DT0RFUy5MT0xMSVBPUCkgeworICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oCisgICAgICAgICAgU3RyaW5nLmZvcm1hdCgiRklGT3MgcmVxdWlyZSBTREsgbGV2ZWwgMjErOyBjdXJyZW50IGxldmVsIGlzICVkIiwgQnVpbGQuVkVSU0lPTi5TREtfSU5UKSk7CisgICAgfQorICAgIGludCBmaWZvSWQgPSBpZEdlbmVyYXRvci5nZXRBbmRJbmNyZW1lbnQoKTsKKyAgICBTdHJpbmcgZmlmb05hbWUgPSAiLm1vYnN0b3JlLSIgKyB0YWcgKyAiLSIgKyBNWV9QSUQgKyAiLSIgKyBmaWZvSWQgKyAiLmZpZm8iOworICAgIEZpbGUgZmlmb0ZpbGUgPSBuZXcgRmlsZShkaXJlY3RvcnksIGZpZm9OYW1lKTsKKyAgICBmaWZvRmlsZS5kZWxldGUoKTsgLy8gRGVsZXRlIHN0YWxlIEZJRk8gaWYgaXQgZXhpc3RzIChpdCBzaG91bGRuJ3QpCisgICAgdHJ5IHsKKyAgICAgIE9zLm1rZmlmbyhmaWZvRmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSwgT3NDb25zdGFudHMuU19JUlVTUiB8IE9zQ29uc3RhbnRzLlNfSVdVU1IpOworICAgICAgcmV0dXJuIGZpZm9GaWxlOworICAgIH0gY2F0Y2ggKEVycm5vRXhjZXB0aW9uIGUpIHsKKyAgICAgIGZpZm9GaWxlLmRlbGV0ZSgpOworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBCbG9ja3Mgb24ge0Bjb2RlIHB1bXBGdXR1cmUuZ2V0KCl9IGFuZCBwcm9wYWdhdGVzIGFueSBleGNlcHRpb24gaXQgbWF5IGhhdmUgZW5jb3VudGVyZWQgYXMgYW4KKyAgICoge0Bjb2RlIElPRXhjZXB0aW9ufS4KKyAgICovCisgIHN0YXRpYyB2b2lkIGdldEFuZFByb3BhZ2F0ZUFzSU9FeGNlcHRpb24oRnV0dXJlPFRocm93YWJsZT4gcHVtcEZ1dHVyZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgVGhyb3dhYmxlIHRocm93YWJsZSA9IHB1bXBGdXR1cmUuZ2V0KCk7CisgICAgICBpZiAodGhyb3dhYmxlICE9IG51bGwpIHsKKyAgICAgICAgaWYgKHRocm93YWJsZSBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7CisgICAgICAgICAgdGhyb3cgKElPRXhjZXB0aW9uKSB0aHJvd2FibGU7CisgICAgICAgIH0KKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKHRocm93YWJsZSk7CisgICAgICB9CisgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgeworICAgICAgVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5pbnRlcnJ1cHQoKTsgLy8gcGVyIDxpbnRlcm5hbD4KKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihlKTsKKyAgICB9IGNhdGNoIChFeGVjdXRpb25FeGNlcHRpb24gZSkgeworICAgICAgaWYgKGUuZ2V0Q2F1c2UoKSBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7CisgICAgICAgIHRocm93IChJT0V4Y2VwdGlvbikgZS5nZXRDYXVzZSgpOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGUpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgUGlwZXMoKSB7fQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmFuZG9tQWNjZXNzRmlsZU9wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmFuZG9tQWNjZXNzRmlsZU9wZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1ZTE4MzkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9SYW5kb21BY2Nlc3NGaWxlT3BlbmVyLmphdmEKQEAgLTAsMCArMSw2MyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuQ29udGV4dDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5GaWxlczsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlJhbmRvbUFjY2Vzc0ZpbGU7CisKKy8qKiBPcGVuZXIgdGhhdCByZXR1cm5zIGEgUmFuZG9tQWNjZXNzRmlsZS4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBSYW5kb21BY2Nlc3NGaWxlT3BlbmVyIGltcGxlbWVudHMgT3BlbmVyPFJhbmRvbUFjY2Vzc0ZpbGU+IHsKKworICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gd3JpdGVTdXBwb3J0OworCisgIC8qKgorICAgKiBJZiB3cml0ZVN1cHBvcnQgaXMgZmFsc2UsIHRoZSBSQUYgaXMgcmVhZCBvbmx5LiBJZiB3cml0ZVN1cHBvcnQgaXMgZW5hYmxlZCwgdGhlIFJBRiBpcyByZWFkIGFuZAorICAgKiB3cml0ZSwgYW5kIHRoZSBkaXJlY3RvcnkgaXMgY3JlYXRlZCBpZiBuZWNlc3NhcnkuCisgICAqLworICBwcml2YXRlIFJhbmRvbUFjY2Vzc0ZpbGVPcGVuZXIoYm9vbGVhbiB3cml0ZVN1cHBvcnQpIHsKKyAgICB0aGlzLndyaXRlU3VwcG9ydCA9IHdyaXRlU3VwcG9ydDsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgUmFuZG9tQWNjZXNzRmlsZU9wZW5lciBjcmVhdGVGb3JSZWFkKCkgeworICAgIHJldHVybiBuZXcgUmFuZG9tQWNjZXNzRmlsZU9wZW5lcigvKndyaXRlU3VwcG9ydD0qLyBmYWxzZSk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlIGFuIG9wZW5lciB0aGF0IHJldHVybnMgYSBSYW5kb21BY2Nlc3NGaWxlIG9wZW5lZCBmb3IgcmVhZCBhbmQgd3JpdGUuIElmIHRoZSBGaWxlIG9yIGl0cworICAgKiBwYXJlbnQgZGlyZWN0b3JpZXMgZG8gbm90IGV4aXN0LCB0aGV5IHdpbGwgYmUgY3JlYXRlZC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgUmFuZG9tQWNjZXNzRmlsZU9wZW5lciBjcmVhdGVGb3JSZWFkV3JpdGUoKSB7CisgICAgcmV0dXJuIG5ldyBSYW5kb21BY2Nlc3NGaWxlT3BlbmVyKC8qd3JpdGVTdXBwb3J0PSovIHRydWUpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBSYW5kb21BY2Nlc3NGaWxlIG9wZW4oT3BlbkNvbnRleHQgb3BlbkNvbnRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKHdyaXRlU3VwcG9ydCkgeworICAgICAgUmVhZEZpbGVPcGVuZXIgcmVhZEZpbGVPcGVuZXIgPSBSZWFkRmlsZU9wZW5lci5jcmVhdGUoKS53aXRoU2hvcnRDaXJjdWl0KCk7CisgICAgICBGaWxlIGZpbGUgPSByZWFkRmlsZU9wZW5lci5vcGVuKG9wZW5Db250ZXh0KTsKKyAgICAgIEZpbGVzLmNyZWF0ZVBhcmVudERpcnMoZmlsZSk7CisgICAgICByZXR1cm4gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZmlsZSwgInJ3Iik7CisgICAgfSBlbHNlIC8qIGlmICghd3JpdGVTdXBwb3J0KSAqLyB7CisgICAgICBSZWFkRmlsZU9wZW5lciByZWFkRmlsZU9wZW5lciA9IFJlYWRGaWxlT3BlbmVyLmNyZWF0ZSgpOworICAgICAgRmlsZSBmaWxlID0gcmVhZEZpbGVPcGVuZXIub3BlbihvcGVuQ29udGV4dCk7CisgICAgICByZXR1cm4gbmV3IFJhbmRvbUFjY2Vzc0ZpbGUoZmlsZSwgInIiKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlYWRCeXRlQXJyYXlPcGVuZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlYWRCeXRlQXJyYXlPcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMmQwM2IwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZEJ5dGVBcnJheU9wZW5lci5qYXZhCkBAIC0wLDAgKzEsODMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uU2l6YWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5VbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmlvLkJ5dGVTdHJlYW1zOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnByaW1pdGl2ZXMuSW50czsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CisKKy8qKgorICogQW4gb3BlbmVyIHRoYXQgcmV0dXJucyBhIGJ5dGVbXSBmb3IgYSBVcmkuIEF0dGVtcHRzIHRvIGdldCB0aGUgZmlsZSBzaXplIHNvIGl0IGNhbiBwZXJmb3JtIGEKKyAqIHNpbmdsZSBhbGxvY2F0aW9uLCBidXQgZmFsbHMgYmFjayB0byBhIGR5bmFtaWMgYWxsb2NhdGlvbiB3aGVuIHRoZSBzaXplIGlzIHVua25vd24uCisgKgorICogPHA+V2FybmluZzogTGFyZ2UgbWVtb3J5IGFsbG9jYXRpb25zIGNhbiBPT00uIFdlIHJlY29tbWVuZCBldmFsdWF0aW5nIHJlbGlhYmlsaXR5IGFuZCBwZXJmb3JtYW5jZQorICogb24gdGFyZ2V0IHBsYXRmb3JtcyB3aGVuIGFsbG9jYXRpbmcgPiAxTS4KKyAqCisgKiA8cD5Vc2FnZTogPGNvZGU+CisgKiBieXRlW10gYnl0ZXMgPSBzdG9yYWdlLm9wZW4odXJpLCBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpKTsKKyAqIDwvY29kZT4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFJlYWRCeXRlQXJyYXlPcGVuZXIgaW1wbGVtZW50cyBPcGVuZXI8Ynl0ZVtdPiB7CisKKyAgcHJpdmF0ZSBSZWFkQnl0ZUFycmF5T3BlbmVyKCkge30KKworICAvKiogQ3JlYXRlcyBhIG5ldyBvcGVuZXIgaW5zdGFuY2UgdG8gcmVhZCBhIGJ5dGUgYXJyYXkuICovCisgIHB1YmxpYyBzdGF0aWMgUmVhZEJ5dGVBcnJheU9wZW5lciBjcmVhdGUoKSB7CisgICAgcmV0dXJuIG5ldyBSZWFkQnl0ZUFycmF5T3BlbmVyKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJ5dGVbXSBvcGVuKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLm9wZW4ob3BlbkNvbnRleHQpKSB7CisgICAgICBMb25nIHNpemUgPSBudWxsOworICAgICAgLy8gVHJ5IHRvIGdldCB0aGUgbGVuZ3RoIGZyb20gdGhlIFNpemFibGUgaW50ZXJmYWNlLiBUaGlzIGNhbiBwb3RlbnRpYWxseSB3b3JrIHdpdGgKKyAgICAgIC8vIG1vbml0b3JzIGFuZCB0cmFuc2Zvcm1zIHRoYXQgZG8gbm90IGNoYW5nZSB0aGUgZmlsZSBzaXplLCBvciBkbyBzbyBpbiBhIHdheSB0aGF0CisgICAgICAvLyBzdXBwb3J0cyBlZmZpY2llbnQgY2FsY3VsYXRpb24gb2YgdGhlIGxvZ2ljYWwgc2l6ZSAoZWcgZmlsZSBzaXplIC0gaGVhZGVyIHNpemUgPSBsb2dpY2FsCisgICAgICAvLyBzaXplKS4KKyAgICAgIGlmIChpbiBpbnN0YW5jZW9mIFNpemFibGUpIHsKKyAgICAgICAgc2l6ZSA9ICgoU2l6YWJsZSkgaW4pLnNpemUoKTsKKyAgICAgIH0KKworICAgICAgLy8gSWYgU2l6YWJsZSBmYWlsZWQgYW5kIHRoZXJlIGFyZSBub3QgdHJhbnNmb3JtcyB0aGF0IGNvdWxkIG1hbmlwdWxhdGUgdGhlIGZpbGUgc2l6ZSwKKyAgICAgIC8vIHRoZW4gdHJ5IGNhbGxpbmcgZmlsZVNpemUoKS4KKyAgICAgIGlmIChzaXplID09IG51bGwgJiYgIW9wZW5Db250ZXh0Lmhhc1RyYW5zZm9ybXMoKSkgeworICAgICAgICB0cnkgeworICAgICAgICAgIGxvbmcgZmlsZVNpemUgPSBvcGVuQ29udGV4dC5zdG9yYWdlKCkuZmlsZVNpemUob3BlbkNvbnRleHQub3JpZ2luYWxVcmkoKSk7CisgICAgICAgICAgaWYgKGZpbGVTaXplID4gMCkgeworICAgICAgICAgICAgLy8gVHJlYXQgMCBhcyAidW5rbm93biBmaWxlIHNpemUiLgorICAgICAgICAgICAgc2l6ZSA9IGZpbGVTaXplOworICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbiBleCkgeworICAgICAgICAgIC8vIElnbm9yZS4KKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBpZiAoc2l6ZSA9PSBudWxsKSB7CisgICAgICAgIC8vIEJ1bW1lci4gUmVhZCBzdHJlYW0gb2YgdW5rbm93biBsZW5ndGguIEluZWZmaWNpZW50IGJ1dCBhbHdheXMgd29ya3MuCisgICAgICAgIHJldHVybiBCeXRlU3RyZWFtcy50b0J5dGVBcnJheShpbik7CisgICAgICB9CisKKyAgICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW0ludHMuY2hlY2tlZENhc3Qoc2l6ZSldOworICAgICAgQnl0ZVN0cmVhbXMucmVhZEZ1bGx5KGluLCBieXRlcyk7CisgICAgICByZXR1cm4gYnl0ZXM7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9SZWFkRmlsZU9wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZEZpbGVPcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMDJiOWJiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZEZpbGVPcGVuZXIuamF2YQpAQCAtMCwwICsxLDE2NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC51dGlsLkxvZzsKK2ltcG9ydCBhbmRyb2lkeC5hbm5vdGF0aW9uLlZpc2libGVGb3JUZXN0aW5nOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uRmlsZUNvbnZlcnRpYmxlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlJlbGVhc2FibGVSZXNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5VbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5GdXR1cmU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0ludGVnZXI7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5OdWxsYWJsZTsKKworLyoqCisgKiBPcGVuZXIgZm9yIHJlYWRpbmcgZGF0YSBmcm9tIGEge0BsaW5rIGphdmEuaW8uRmlsZX0gb2JqZWN0LiBEZXBlbmRpbmcgb24gdGhlIGJhY2tlbmQsIHRoaXMgbWF5CisgKiByZXR1cm4uLi4KKyAqCisgKiA8b2w+CisgKiAgIDxsaT5UaGUgc2ltcGxlIHBvc2l4IHBhdGguCisgKiAgIDxsaT5BIHBhdGggdG8gYSBGSUZPIChuYW1lZCBwaXBlKSBmcm9tIHdoaWNoIGRhdGEgY2FuIGJlIHN0cmVhbWVkLgorICogPC9vbD4KKyAqCisgKiBOb3RlIHRoYXQgdGhlIHNlY29uZCBvcHRpb24gaXMgZGlzYWJsZWQgYnkgZGVmYXVsdCwgYW5kIG11c3QgYmUgdHVybmVkIG9uIHdpdGgge0BsaW5rCisgKiAjd2l0aEZhbGxiYWNrVG9QaXBlVXNpbmdFeGVjdXRvcn0uCisgKgorICogPHA+VXNhZ2U6IDxjb2RlPgorICogRmlsZSBmaWxlID0gc3RvcmFnZS5vcGVuKHVyaSwKKyAqICAgIFJlYWRGaWxlT3BlbmVyLmNyZWF0ZSgpLndpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoZXhlY3V0b3IsIGNvbnRleHQpKSk7CisgKiB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZSkpIHsKKyAqICAgLy8gUmVhZCBmaWxlCisgKiB9CisgKiA8L2NvZGU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBSZWFkRmlsZU9wZW5lciBpbXBsZW1lbnRzIE9wZW5lcjxGaWxlPiB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJSZWFkRmlsZU9wZW5lciI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTVFJFQU1fQlVGRkVSX1NJWkUgPSA0MDk2OworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBBdG9taWNJbnRlZ2VyIEZJRk9fQ09VTlRFUiA9IG5ldyBBdG9taWNJbnRlZ2VyKCk7CisKKyAgQE51bGxhYmxlIHByaXZhdGUgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yOworICBATnVsbGFibGUgcHJpdmF0ZSBDb250ZXh0IGNvbnRleHQ7CisgIEBOdWxsYWJsZSBwcml2YXRlIEZ1dHVyZTxUaHJvd2FibGU+IHB1bXBGdXR1cmU7CisgIHByaXZhdGUgYm9vbGVhbiBzaG9ydENpcmN1aXQgPSBmYWxzZTsKKworICBwcml2YXRlIFJlYWRGaWxlT3BlbmVyKCkge30KKworICBwdWJsaWMgc3RhdGljIFJlYWRGaWxlT3BlbmVyIGNyZWF0ZSgpIHsKKyAgICByZXR1cm4gbmV3IFJlYWRGaWxlT3BlbmVyKCk7CisgIH0KKworICAvKioKKyAgICogSWYgZW5hYmxlZCwgc3RpbGwgdHJ5IHRvIHJldHVybiBhIHJhdyBmaWxlIHBhdGggYnV0LCBpZiB0aGF0IGZhaWxzLCByZXR1cm4gYSBGSUZPIChha2EgbmFtZWQKKyAgICogcGlwZSkgZnJvbSB3aGljaCB0aGUgZGF0YSBjYW4gYmUgY29uc3VtZWQgYXMgYSBzdHJlYW0uIFJhdyBmaWxlIHBhdGhzIGFyZSBub3QgYXZhaWxhYmxlIGlmCisgICAqIHRoZXJlIGFyZSBhbnkgdHJhbnNmb3JtcyBpbnN0YWxsZWQ7IGlmIHRoZXJlIGFyZSBhbnkgbW9uaXRvcnMgaW5zdGFsbGVkOyBvciBpZiB0aGUgYmFja2VuZAorICAgKiBsYWNrcyBzdWNoIHN1cHBvcnQuCisgICAqCisgICAqIDxwPlRoZSBjYWxsZXIgTVVTVCBvcGVuIHRoZSByZXR1cm5lZCBmaWxlIGluIG9yZGVyIHRvIGF2b2lkIGEgdGhyZWFkIGxlYWsuIEl0IG1heSBvbmx5IG9wZW4gaXQKKyAgICogb25jZS4KKyAgICoKKyAgICogPHA+VGhlIGNhbGxlciBtYXkgYmxvY2sgb24ge0BsaW5rICN3YWl0Rm9yUHVtcH0gYW5kIGhhbmRsZSBhbnkgZXhjZXB0aW9ucyBpbiBvcmRlciB0byBtb25pdG9yCisgICAqIGZhaWx1cmVzLgorICAgKgorICAgKiA8cD5XQVJOSU5HOiBGSUZPcyByZXF1aXJlIFNESyBsZXZlbCAyMSsgKExvbGxpcG9wKS4gSWYgdGhlIHJhdyBmaWxlIHBhdGggaXMgdW5hdmFpbGFibGUgYW5kIHRoZQorICAgKiBjdXJyZW50IFNESyBsZXZlbCBpcyBpbnN1ZmZpY2llbnQgZm9yIEZJRk9zLCB0aGUgZmFsbGJhY2sgd2lsbCBmYWlsICh0aHJvdyBJT0V4Y2VwdGlvbikuCisgICAqCisgICAqIEBwYXJhbSBleGVjdXRvciBFeGVjdXRvciBmb3IgcHVtcCB0aHJlYWRzLgorICAgKiBAcGFyYW0gY29udGV4dCBBbmRyb2lkIGNvbnRleHQgZm9yIHRoZSByb290IGRpcmVjdG9yeSB3aGVyZSBmaWZvcyBhcmUgc3RvcmVkLgorICAgKiBAcmV0dXJuIFRoaXMgb3BlbmVyLgorICAgKi8KKyAgcHVibGljIFJlYWRGaWxlT3BlbmVyIHdpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yLCBDb250ZXh0IGNvbnRleHQpIHsKKyAgICB0aGlzLmV4ZWN1dG9yID0gZXhlY3V0b3I7CisgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBJZiBlbmFibGVkLCB3aWxsIE9OTFkgYXR0ZW1wdCB0byBjb252ZXJ0IHRoZSBVUkkgdG8gYSBwYXRoIHVzaW5nIHN0cmluZyBwcm9jZXNzaW5nLiBGYWlscyBpZgorICAgKiB0aGVyZSBhcmUgYW55IHRyYW5zZm9ybXMgZW5hYmxlZC4gVGhpcyBpcyBsaWtlIHRoZSB7QGxpbmsgVXJpQWRhcHRlcn0gaW50ZXJmYWNlLCBidXQgd2l0aCBtb3JlCisgICAqIGd1YXJkIHJhaWxzIHRvIG1ha2UgaXQgc2FmZSB0byBleHBvc2UgcHVibGljbHkuCisgICAqLworICBwdWJsaWMgUmVhZEZpbGVPcGVuZXIgd2l0aFNob3J0Q2lyY3VpdCgpIHsKKyAgICB0aGlzLnNob3J0Q2lyY3VpdCA9IHRydWU7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEZpbGUgb3BlbihPcGVuQ29udGV4dCBvcGVuQ29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBpZiAoc2hvcnRDaXJjdWl0KSB7CisgICAgICBpZiAob3BlbkNvbnRleHQuaGFzVHJhbnNmb3JtcygpKSB7CisgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJTaG9ydCBjaXJjdWl0IHdvdWxkIHNraXAgdHJhbnNmb3Jtcy4iKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBvcGVuQ29udGV4dC5iYWNrZW5kKCkudG9GaWxlKG9wZW5Db250ZXh0LmVuY29kZWRVcmkoKSk7CisgICAgfQorCisgICAgdHJ5IChSZWxlYXNhYmxlUmVzb3VyY2U8SW5wdXRTdHJlYW0+IGluID0KKyAgICAgICAgUmVsZWFzYWJsZVJlc291cmNlLmNyZWF0ZShSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLm9wZW4ob3BlbkNvbnRleHQpKSkgeworICAgICAgLy8gVE9ETyhiLzExODg4ODA0NCk6IEZpbGVDb252ZXJ0aWJsZSBwcm9iYWJseSBjYW4gYmUgZGVwcmVjYXRlZC4KKyAgICAgIGlmIChpbi5nZXQoKSBpbnN0YW5jZW9mIEZpbGVDb252ZXJ0aWJsZSkgeworICAgICAgICByZXR1cm4gKChGaWxlQ29udmVydGlibGUpIGluLmdldCgpKS50b0ZpbGUoKTsKKyAgICAgIH0KKyAgICAgIGlmIChleGVjdXRvciAhPSBudWxsKSB7CisgICAgICAgIHJldHVybiBwaXBlVG9GaWxlKGluLnJlbGVhc2UoKSk7CisgICAgICB9CisgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIk5vdCBjb252ZXJ0aWJsZSBhbmQgZmFsbGJhY2sgdG8gcGlwZSBpcyBkaXNhYmxlZC4iKTsKKyAgICB9CisgIH0KKworICAvKiogV2FpdCBmb3IgcHVtcCBhbmQgcHJvcGFnYXRlIGFueSBleGNlcHRpb25zIGl0IG1heSBoYXZlIGVuY291bnRlcmVkLiAqLworICBAVmlzaWJsZUZvclRlc3RpbmcKKyAgdm9pZCB3YWl0Rm9yUHVtcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUGlwZXMuZ2V0QW5kUHJvcGFnYXRlQXNJT0V4Y2VwdGlvbihwdW1wRnV0dXJlKTsKKyAgfQorCisgIHByaXZhdGUgRmlsZSBwaXBlVG9GaWxlKElucHV0U3RyZWFtIGluKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZpbGUgZmlmbyA9IFBpcGVzLm1ha2VGaWZvKGNvbnRleHQuZ2V0Q2FjaGVEaXIoKSwgVEFHLCBGSUZPX0NPVU5URVIpOworICAgIHB1bXBGdXR1cmUgPQorICAgICAgICBleGVjdXRvci5zdWJtaXQoCisgICAgICAgICAgICAoKSAtPiB7CisgICAgICAgICAgICAgIHRyeSAoRmlsZU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShmaWZvKSkgeworICAgICAgICAgICAgICAgIC8vIEluIG9yZGVyIHRvIHJlYWNoIHRoaXMgcG9pbnQsIHJlYWRlciBtdXN0IGhhdmUgb3BlbmVkIHRoZSBGSUZPLCBzbyBpdCdzIG9rCisgICAgICAgICAgICAgICAgLy8gdG8gZGVsZXRlIGl0LgorICAgICAgICAgICAgICAgIGZpZm8uZGVsZXRlKCk7CisgICAgICAgICAgICAgICAgYnl0ZVtdIHRtcCA9IG5ldyBieXRlW1NUUkVBTV9CVUZGRVJfU0laRV07CisgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgIGludCBsZW47CisgICAgICAgICAgICAgICAgICB3aGlsZSAoKGxlbiA9IGluLnJlYWQodG1wKSkgIT0gLTEpIHsKKyAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlKHRtcCwgMCwgbGVuKTsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIG91dC5mbHVzaCgpOworICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CisgICAgICAgICAgICAgICAgICBpbi5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIExvZy53KFRBRywgInB1bXAiLCBlKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZTsKKyAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICBMb2cuZShUQUcsICJwdW1wIiwgdCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHQ7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9KTsKKyAgICByZXR1cm4gZmlmbzsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZFByb3RvT3BlbmVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9SZWFkUHJvdG9PcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NzYyODAzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZFByb3RvT3BlbmVyLmphdmEKQEAgLTAsMCArMSw3NCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuQ29udGV4dDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKKworLyoqCisgKiBPcGVuZXIgZm9yIHJlYWRpbmcgUHJvdG9jb2wgQnVmZmVycyBmcm9tIGZpbGUuIEl0IGlzIGJhc2VkIG9uIHRoZSBKYXZhIFByb3RvIExpdGUgaW1wbGVtZW50YXRpb247CisgKiBzZWUgPGludGVybmFsPiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4gTm90ZSB0aGF0IHRoaXMgb3BlbmVyIHJlYWRzIHRoZSBlbnRpcmUgc3RyZWFtIGludG8gYSBzaW5nbGUKKyAqIG1lc3NhZ2UsIG1lYW5pbmcgdGhhdCBkZWxpbWl0ZWQgZmlsZXMgYXJlIG5vdCBzdXBwb3J0ZWQuIElmIHRoZSBieXRlIGNvbnRlbnRzIG9mIHRoZSBVcmkgY2Fubm90CisgKiBiZSBwYXJzZWQgYXMgYSB2YWxpZCBwcm90b2NvbCBtZXNzYWdlLCB0aHJvd3Mge0BsaW5rIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbn0uCisgKgorICogPHA+VXNhZ2U6IDxjb2RlPgorICogTXlQcm90byBwcm90byA9IHN0b3JhZ2Uub3Blbih1cmksIFJlYWRQcm90b09wZW5lci5jcmVhdGUoTXlQcm90by5wYXJzZXIoKSkpOworICogPC9jb2RlPgorICoKKyAqIDxwPlRPRE8oYi83NTkwOTI4Nyk6IGNvbnNpZGVyIGFkZGluZyBhbHRlcm5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBmb3IgbXVsdGktcHJvdG8gZmlsZXMKKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFJlYWRQcm90b09wZW5lcjxUIGV4dGVuZHMgTWVzc2FnZUxpdGU+IGltcGxlbWVudHMgT3BlbmVyPFQ+IHsKKworICBwcml2YXRlIGZpbmFsIFBhcnNlcjxUPiBwYXJzZXI7CisgIHByaXZhdGUgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5ID0gRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmdldEVtcHR5UmVnaXN0cnkoKTsKKworICBwcml2YXRlIFJlYWRQcm90b09wZW5lcihQYXJzZXI8VD4gcGFyc2VyKSB7CisgICAgdGhpcy5wYXJzZXIgPSBwYXJzZXI7CisgIH0KKworICAvKiogQ3JlYXRlcyBhIG5ldyBvcGVuZXIgaW5zdGFuY2UgdGhhdCByZWFkcyBwcm90b3MgdXNpbmcgdGhlIGdpdmVuIHtAY29kZSBwYXJzZXJ9LiAqLworICBwdWJsaWMgc3RhdGljIDxUIGV4dGVuZHMgTWVzc2FnZUxpdGU+IFJlYWRQcm90b09wZW5lcjxUPiBjcmVhdGUoUGFyc2VyPFQ+IHBhcnNlcikgeworICAgIHJldHVybiBuZXcgUmVhZFByb3RvT3BlbmVyPFQ+KHBhcnNlcik7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhIG5ldyBvcGVuZXIgaW5zdGFuY2UgdGhhdCByZWFkcyBwcm90b3MgdXNpbmcgdGhlIHBhcnNlciBvZiB0aGUgZ2l2ZW4ge0Bjb2RlIG1lc3NhZ2V9LgorICAgKiBUaGlzIGNhbiBiZSB1c2VmdWwgaWYgdGhlIHR5cGUgb2YgVCBpcyB1bmF2YWlsYWJsZSBhdCBjb21waWxlIHRpbWUgKGkuZS4gaXQncyBhIGdlbmVyaWMpLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyA8VCBleHRlbmRzIE1lc3NhZ2VMaXRlPiBSZWFkUHJvdG9PcGVuZXI8VD4gY3JlYXRlKFQgbWVzc2FnZSkgeworICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKSAvLyBzYWZlIGNhc3QgYmVjYXVzZSBnZXRQYXJzZXJGb3JUeXBlIEFQSSBtdXN0IHJldHVybiBhIFBhcnNlcjxUPgorICAgIFBhcnNlcjxUPiBwYXJzZXIgPSAoUGFyc2VyPFQ+KSBtZXNzYWdlLmdldFBhcnNlckZvclR5cGUoKTsKKyAgICByZXR1cm4gbmV3IFJlYWRQcm90b09wZW5lcjxUPihwYXJzZXIpOworICB9CisKKyAgLyoqIEFkZHMgYW4gZXh0ZW5zaW9uIHJlZ2lzdHJ5IHVzZWQgd2hpbGUgcGFyc2luZyB0aGUgcHJvdG8uICovCisgIHB1YmxpYyBSZWFkUHJvdG9PcGVuZXI8VD4gd2l0aEV4dGVuc2lvblJlZ2lzdHJ5KEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgeworICAgIHRoaXMucmVnaXN0cnkgPSByZWdpc3RyeTsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgVCBvcGVuKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLm9wZW4ob3BlbkNvbnRleHQpKSB7CisgICAgICByZXR1cm4gcGFyc2VyLnBhcnNlRnJvbShpbiwgcmVnaXN0cnkpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZFN0cmVhbU9wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZFN0cmVhbU9wZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk0ODQ4ZWUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9SZWFkU3RyZWFtT3BlbmVyLmphdmEKQEAgLTAsMCArMSw3MCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5CZWhhdmlvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbmVyOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKiBBbiBvcGVuZXIgdGhhdCByZXR1cm5zIGEgc2ltcGxlIElucHV0U3RyZWFtIG9wZW5lZCBmb3IgcmVhZC4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBSZWFkU3RyZWFtT3BlbmVyIGltcGxlbWVudHMgT3BlbmVyPElucHV0U3RyZWFtPiB7CisKKyAgcHJpdmF0ZSBib29sZWFuIGJ1ZmZlcklvID0gZmFsc2U7CisgIHByaXZhdGUgQmVoYXZpb3JbXSBiZWhhdmlvcnM7CisKKyAgcHJpdmF0ZSBSZWFkU3RyZWFtT3BlbmVyKCkge30KKworICBwdWJsaWMgc3RhdGljIFJlYWRTdHJlYW1PcGVuZXIgY3JlYXRlKCkgeworICAgIHJldHVybiBuZXcgUmVhZFN0cmVhbU9wZW5lcigpOworICB9CisKKyAgcHVibGljIFJlYWRTdHJlYW1PcGVuZXIgd2l0aEJlaGF2aW9ycyhCZWhhdmlvci4uLiBiZWhhdmlvcnMpIHsKKyAgICB0aGlzLmJlaGF2aW9ycyA9IGJlaGF2aW9yczsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIC8qKgorICAgKiBJZiBlbmFibGVkLCB1c2VzIHtAbGluayBCdWZmZXJlZElucHV0U3RyZWFtfSB0byBidWZmZXIgSU8gZnJvbSB0aGUgYmFja2VuZC4gRGVwZW5kaW5nIG9uIHRoZQorICAgKiBzaXR1YXRpb24gdGhpcyBjYW4gaGVscCBvciBodXJ0IHBlcmZvcm1hbmNlLCBzbyBwbGVhc2UgY29udGFjdCA8aW50ZXJuYWw+IGJlZm9yZSB1c2luZyBpdC4KKyAgICoKKyAgICogPHA+RW5jb3VyYWdlZDogemlwIGZpbGVzLgorICAgKgorICAgKiA8cD5EaXNjb3VyYWdlZDogcHJvdG9zIChhbHJlYWR5IGJ1ZmZlcmVkIGludGVybmFsbHkpLgorICAgKi8KKyAgcHVibGljIFJlYWRTdHJlYW1PcGVuZXIgd2l0aEJ1ZmZlcmVkSW8oKSB7CisgICAgdGhpcy5idWZmZXJJbyA9IHRydWU7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIG9wZW4oT3BlbkNvbnRleHQgb3BlbkNvbnRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgSW5wdXRTdHJlYW0gYmFja2VuZElucHV0ID0gb3BlbkNvbnRleHQuYmFja2VuZCgpLm9wZW5Gb3JSZWFkKG9wZW5Db250ZXh0LmVuY29kZWRVcmkoKSk7CisgICAgaWYgKGJ1ZmZlcklvKSB7CisgICAgICBiYWNrZW5kSW5wdXQgPSBuZXcgQnVmZmVyZWRJbnB1dFN0cmVhbShiYWNrZW5kSW5wdXQpOworICAgIH0KKyAgICBMaXN0PElucHV0U3RyZWFtPiBjaGFpbiA9IG9wZW5Db250ZXh0LmNoYWluVHJhbnNmb3Jtc0ZvclJlYWQoYmFja2VuZElucHV0KTsKKyAgICBpZiAoYmVoYXZpb3JzICE9IG51bGwpIHsKKyAgICAgIGZvciAoQmVoYXZpb3IgYmVoYXZpb3IgOiBiZWhhdmlvcnMpIHsKKyAgICAgICAgYmVoYXZpb3IuZm9ySW5wdXRDaGFpbihjaGFpbik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBjaGFpbi5nZXQoMCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlYWRTdHJpbmdPcGVuZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlYWRTdHJpbmdPcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZjQzNGFhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZFN0cmluZ09wZW5lci5qYXZhCkBAIC0wLDAgKzEsNDQgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuQ2hhcnNldHM7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CisKKy8qKiBBbiBvcGVuZXIgdGhhdCByZWFkcyBlbnRpcmUgY29udGVudHMgb2YgZmlsZSBpbnRvIGEgU3RyaW5nLiAqLworcHVibGljIGZpbmFsIGNsYXNzIFJlYWRTdHJpbmdPcGVuZXIgaW1wbGVtZW50cyBPcGVuZXI8U3RyaW5nPiB7CisgIHByaXZhdGUgQ2hhcnNldCBjaGFyc2V0ID0gQ2hhcnNldHMuVVRGXzg7CisKKyAgcHJvdGVjdGVkIFJlYWRTdHJpbmdPcGVuZXIoKSB7fQorCisgIHB1YmxpYyBzdGF0aWMgUmVhZFN0cmluZ09wZW5lciBjcmVhdGUoKSB7CisgICAgcmV0dXJuIG5ldyBSZWFkU3RyaW5nT3BlbmVyKCk7CisgIH0KKworICBwdWJsaWMgUmVhZFN0cmluZ09wZW5lciB3aXRoQ2hhcnNldChDaGFyc2V0IGNoYXJzZXQpIHsKKyAgICB0aGlzLmNoYXJzZXQgPSBjaGFyc2V0OworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgb3BlbihPcGVuQ29udGV4dCBvcGVuQ29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBieXRlW10gYnl0ZXMgPSBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpLm9wZW4ob3BlbkNvbnRleHQpOworICAgIHJldHVybiBuZXcgU3RyaW5nKGJ5dGVzLCBjaGFyc2V0KTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVjdXJzaXZlRGVsZXRlT3BlbmVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9SZWN1cnNpdmVEZWxldGVPcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MGZlMjdmCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVjdXJzaXZlRGVsZXRlT3BlbmVyLmphdmEKQEAgLTAsMCArMSw4MSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLkV4Y2VwdGlvbnM7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIERlbGV0ZXMgdGhlIGZpbGUgb3IgZGlyZWN0b3J5IGF0IHRoZSBnaXZlbiBVUkkgcmVjdXJzaXZlbHkuIFRoaXMgYmVoYXZlcyBzaW1pbGFybHkgdG8ge0BsaW5rCisgKiBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlI2RlbGV0ZVJlY3Vyc2l2ZWx5fSBleGNlcHQgYXMgZGVzY3JpYmVkIGluIHRoZSBmb2xsb3dpbmcgcGFyYWdyYXBoLgorICoKKyAqIDxwPklmIGFuIElPIGV4Y2VwdGlvbiBvY2N1cnMgYXR0ZW1wdGluZyB0byByZWFkLCBvcGVuLCBvciBkZWxldGUgYW55IGZpbGUgdW5kZXIgdGhlIGdpdmVuCisgKiBkaXJlY3RvcnksIHRoaXMgbWV0aG9kIHNraXBzIHRoYXQgZmlsZSBhbmQgY29udGludWVzLiBBbGwgc3VjaCBleGNlcHRpb25zIGFyZSBjb2xsZWN0ZWQgYW5kLAorICogYWZ0ZXIgYXR0ZW1wdGluZyB0byBkZWxldGUgYWxsIGZpbGVzLCBhbiB7QGNvZGUgSU9FeGNlcHRpb259IGlzIHRocm93biBjb250YWluaW5nIHRob3NlCisgKiBleGNlcHRpb25zIGFzIHtAbGlua3BsYWluIFRocm93YWJsZSNnZXRTdXBwcmVzc2VkKCkgc3VwcHJlc3NlZCBleGNlcHRpb25zfS4KKyAqCisgKiA8cD5XQVJOSU5HOiB0aGlzIG9wZW5lciBzdWZmZXJzIGZyb20gdGhlIGZvbGxvd2luZyBjYXZlYXRzIGFuZCBzaG91bGQgYmUgdXNlZCB3aXRoIGNhdXRpb246CisgKgorICogPHVsPgorICogICA8bGk+RGlyZWN0b3J5IHRyZWUgdHJhdmVyc2FsIGlzIG5vdCBhbiBhdG9taWMgb3BlcmF0aW9uCisgKiAgIDxsaT5UaGVyZSBhcmUgbm8gc3BlY2lhbCBjb25zaWRlcmF0aW9ucyBmb3Igc3ltbGlua3MsIG1lYW5pbmcgdGhlIG9wZW5lciBjb3VsZCBnZXQgY2F1Z2h0IGluIGEKKyAqICAgICAgIHJlY3Vyc2l2ZSBkaXJlY3RvcnkgbG9vcCAoaS5lLiBhIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIGEgc3ltbGluayB0byBpdHNlbGYpCisgKiA8L3VsPgorICoKKyAqIDxwPlVzYWdlOiA8Y29kZT4KKyAqIHN0b3JhZ2Uub3Blbih1cmksIFJlY3Vyc2l2ZURlbGV0ZU9wZW5lci5jcmVhdGUoKSk7CisgKiA8L2NvZGU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBSZWN1cnNpdmVEZWxldGVPcGVuZXIgaW1wbGVtZW50cyBPcGVuZXI8Vm9pZD4geworICBwcml2YXRlIFJlY3Vyc2l2ZURlbGV0ZU9wZW5lcigpIHt9CisKKyAgcHVibGljIHN0YXRpYyBSZWN1cnNpdmVEZWxldGVPcGVuZXIgY3JlYXRlKCkgeworICAgIHJldHVybiBuZXcgUmVjdXJzaXZlRGVsZXRlT3BlbmVyKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFZvaWQgb3BlbihPcGVuQ29udGV4dCBvcGVuQ29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMaXN0PElPRXhjZXB0aW9uPiBleGNlcHRpb25zID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgZGVsZXRlUmVjdXJzaXZlbHkob3BlbkNvbnRleHQuc3RvcmFnZSgpLCBvcGVuQ29udGV4dC5lbmNvZGVkVXJpKCksIGV4Y2VwdGlvbnMpOworICAgIGlmICghZXhjZXB0aW9ucy5pc0VtcHR5KCkpIHsKKyAgICAgIHRocm93IEV4Y2VwdGlvbnMuY29tYmluZWRJT0V4Y2VwdGlvbigiRmFpbGVkIHRvIGRlbGV0ZSBvbmUgb3IgbW9yZSBmaWxlcyIsIGV4Y2VwdGlvbnMpOworICAgIH0KKworICAgIHJldHVybiBudWxsOyAvLyBmb3IgVm9pZCByZXR1cm4gdHlwZQorICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBkZWxldGVSZWN1cnNpdmVseSgKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSwgVXJpIHVyaSwgTGlzdDxJT0V4Y2VwdGlvbj4gZXhjZXB0aW9ucykgeworICAgIHRyeSB7CisgICAgICBpZiAoc3RvcmFnZS5pc0RpcmVjdG9yeSh1cmkpKSB7CisgICAgICAgIGZvciAoVXJpIGNoaWxkIDogc3RvcmFnZS5jaGlsZHJlbih1cmkpKSB7CisgICAgICAgICAgZGVsZXRlUmVjdXJzaXZlbHkoc3RvcmFnZSwgY2hpbGQsIGV4Y2VwdGlvbnMpOworICAgICAgICB9CisgICAgICAgIHN0b3JhZ2UuZGVsZXRlRGlyZWN0b3J5KHVyaSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzdG9yYWdlLmRlbGV0ZUZpbGUodXJpKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBleGNlcHRpb25zLmFkZChlKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlY3Vyc2l2ZVNpemVPcGVuZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlY3Vyc2l2ZVNpemVPcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYzZjMjQ0Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVjdXJzaXZlU2l6ZU9wZW5lci5qYXZhCkBAIC0wLDAgKzEsNzcgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0Lkl0ZXJhYmxlczsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheURlcXVlOworaW1wb3J0IGphdmEudXRpbC5EZXF1ZTsKKworLyoqCisgKiBDYWxjdWxhdGVzIHRoZSBzaXplIG9mIGEgZGlyZWN0b3J5IGJ5IHJlY3Vyc2l2ZWx5IHN1bW1pbmcgdGhlIHNpemUgb2YgYWxsIG9mIGl0cyBjaGlsZHJlbi4gSWYgdGhlCisgKiBVcmkgcmVmZXJzIHRvIGFuIGVtcHR5IGRpcmVjdG9yeSwgcmV0dXJucyAwLiBJZiB0aGUgVXJpIHJlZmVycyB0byBhIGZpbGUgb3IgZG9lcyBub3QgZXhpc3QsCisgKiB0aHJvd3Mge0BsaW5rIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbn0uCisgKgorICogPHA+V0FSTklORzogdGhpcyBvcGVuZXIgc3VmZmVycyBmcm9tIHRoZSBmb2xsb3dpbmcgY2F2ZWF0cyBhbmQgc2hvdWxkIGJlIHVzZWQgd2l0aCBjYXV0aW9uOgorICoKKyAqIDx1bD4KKyAqICAgPGxpPkRpcmVjdG9yeSB0cmVlIHRyYXZlcnNhbCBpcyBub3QgYW4gYXRvbWljIG9wZXJhdGlvbgorICogICA8bGk+VGhlcmUgYXJlIG5vIHNwZWNpYWwgY29uc2lkZXJhdGlvbnMgZm9yIHN5bWxpbmtzLCBtZWFuaW5nIHRoZSBvcGVuZXIgY291bGQgZ2V0IGNhdWdodCBpbiBhCisgKiAgICAgICByZWN1cnNpdmUgZGlyZWN0b3J5IGxvb3AgKGkuZS4gYSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyBhIHN5bWxpbmsgdG8gaXRzZWxmKQorICogICA8bGk+RmFpbHMgZmFzdCBpZiB0aGVyZSBpcyBhbiBJL08gZXJyb3Igd2hpbGUgcHJvY2Vzc2luZyBhIGdpdmVuIGNoaWxkIFVyaQorICogPC91bD4KKyAqCisgKiA8cD5Vc2FnZTogbG9uZyBzaXplID0gc3RvcmFnZS5vcGVuKHVyaSwgUmVjdXJzaXZlU2l6ZU9wZW5lci5jcmVhdGUoKSk7CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBSZWN1cnNpdmVTaXplT3BlbmVyIGltcGxlbWVudHMgT3BlbmVyPExvbmc+IHsKKyAgcHJpdmF0ZSBSZWN1cnNpdmVTaXplT3BlbmVyKCkge30KKworICBwdWJsaWMgc3RhdGljIFJlY3Vyc2l2ZVNpemVPcGVuZXIgY3JlYXRlKCkgeworICAgIHJldHVybiBuZXcgUmVjdXJzaXZlU2l6ZU9wZW5lcigpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMb25nIG9wZW4oT3BlbkNvbnRleHQgY29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBsb25nIHRvdGFsU2l6ZSA9IDA7CisgICAgRGVxdWU8VXJpPiB0b1Byb2Nlc3MgPSBuZXcgQXJyYXlEZXF1ZTw+KCk7CisgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlID0gY29udGV4dC5zdG9yYWdlKCk7CisKKyAgICAvLyBTdHJpcHBpbmcgdGhlIFVyaSBmcmFnbWVudCBtZWFucyBjaGlsZHJlbiBmaWxlbmFtZXMgZG9uJ3QgZ2V0IGVuY29kZWQgYnkgdHJhbnNmb3Jtcy4gVGhpcyBpcworICAgIC8vIGludGVudGlvbmFsOiB3ZSdyZSBzaW1wbHkgY2FsY3VsYXRpbmcgdGhlIHRvdGFsIGZpbGUgc2l6ZSByZWdhcmRsZXNzIG9mIHRoZSAiY29ycmVjdCIgbmFtZXMuCisgICAgLy8gQ2hpbGRyZW4gQVBJIGNhbGwgdGhyb3dzIEZORiBpZiB0aGUgVXJpIGlzIGEgZmlsZSBvciBkb2VzIG5vdCBleGlzdC4KKyAgICBVcmkgdXJpV2l0aG91dEZyYWdtZW50ID0gY29udGV4dC5vcmlnaW5hbFVyaSgpLmJ1aWxkVXBvbigpLmZyYWdtZW50KG51bGwpLmJ1aWxkKCk7CisgICAgSXRlcmFibGVzLmFkZEFsbCh0b1Byb2Nlc3MsIHN0b3JhZ2UuY2hpbGRyZW4odXJpV2l0aG91dEZyYWdtZW50KSk7CisKKyAgICAvLyBOT1RFOiBicmVhZHRoLWZpcnN0IHRyYXZlcnNhbCBpcyBhbiBhcmJpdHJhcnkgaW1wbGVtZW50YXRpb24gY2hvaWNlCisgICAgd2hpbGUgKCF0b1Byb2Nlc3MuaXNFbXB0eSgpKSB7CisgICAgICBVcmkgdXJpID0gdG9Qcm9jZXNzLnJlbW92ZSgpOworICAgICAgaWYgKHN0b3JhZ2UuaXNEaXJlY3RvcnkodXJpKSkgeworICAgICAgICBJdGVyYWJsZXMuYWRkQWxsKHRvUHJvY2Vzcywgc3RvcmFnZS5jaGlsZHJlbih1cmkpKTsKKyAgICAgIH0gZWxzZSBpZiAoc3RvcmFnZS5leGlzdHModXJpKSkgeworICAgICAgICB0b3RhbFNpemUgKz0gc3RvcmFnZS5maWxlU2l6ZSh1cmkpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdGhyb3cgbmV3IEZpbGVOb3RGb3VuZEV4Y2VwdGlvbihTdHJpbmcuZm9ybWF0KCJDaGlsZCAlcyBjb3VsZCBub3QgYmUgb3BlbmVkIiwgdXJpKSk7CisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHRvdGFsU2l6ZTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvU2NyYXRjaEZpbGUuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1NjcmF0Y2hGaWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ3NTQ2YgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1NjcmF0Y2hGaWxlLmphdmEKQEAgLTAsMCArMSwzOCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuUHJvY2VzczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljTG9uZzsKKworLyoqIFV0aWxpdHkgZm9yIGNyZWF0aW5nIGEgdGVtcCBmaWxlIGJhc2VkIG9uIFBJRCBhbmQgVGhyZWFkSUQuICovCisvLyBUT0RPOiBjb25zb2xpZGF0ZSB3aXRoIFBpcGVzLmphdmEKK2ZpbmFsIGNsYXNzIFNjcmF0Y2hGaWxlIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBBdG9taWNMb25nIFNDUkFUQ0hfQ09VTlRFUiA9IG5ldyBBdG9taWNMb25nKCk7CisKKyAgc3RhdGljIFVyaSBzY3JhdGNoVXJpKFVyaSBmaWxlKSB7CisgICAgaW50IHByb2Nlc3MgPSBQcm9jZXNzLm15UGlkKCk7CisgICAgbG9uZyB0aHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpLmdldElkKCk7CisgICAgbG9uZyB0aW1lc3RhbXAgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBsb25nIGNvdW50ID0gU0NSQVRDSF9DT1VOVEVSLmdldEFuZEluY3JlbWVudCgpOworICAgIFN0cmluZyBzdWZmaXggPSAiLm1vYnN0b3JlX3RtcC0iICsgcHJvY2VzcyArICItIiArIHRocmVhZCArICItIiArIHRpbWVzdGFtcCArICItIiArIGNvdW50OworICAgIHJldHVybiBmaWxlLmJ1aWxkVXBvbigpLnBhdGgoZmlsZS5nZXRQYXRoKCkgKyBzdWZmaXgpLmJ1aWxkKCk7CisgIH0KKworICBwcml2YXRlIFNjcmF0Y2hGaWxlKCkge30KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1N0cmVhbU11dGF0aW9uT3BlbmVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TdHJlYW1NdXRhdGlvbk9wZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyNjUzOGYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TdHJlYW1NdXRhdGlvbk9wZW5lci5qYXZhCkBAIC0wLDAgKzEsMTY1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5CZWhhdmlvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbmVyOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKgorICogQW4gb3BlbmVyIGZvciB1cGRhdGluZyBhIGZpbGUgYXRvbWljYWxseTogZG9lcyBub3QgbW9kaWZ5IHRoZSBkZXN0aW5hdGlvbiBmaWxlIHVudGlsIGFsbCBvZiB0aGUKKyAqIGRhdGEgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHdyaXR0ZW4uIEluc3RlYWQsIGl0IHdyaXRlcyBpbnRvIGEgc2NyYXRjaCBmaWxlIHdoaWNoIGl0IHJlbmFtZXMgdG8KKyAqIHRoZSBkZXN0aW5hdGlvbiBmaWxlIG9uY2UgdGhlIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBzdWNjZXNzZnVsbHkuCisgKgorICogPHA+SW4gb3JkZXIgdG8gaW1wbGVtZW50IGlzb2xhdGlvbiAocHJldmVudGluZyBvdGhlciBwcm9jZXNzZXMgZnJvbSBtb2RpZnlpbmcgdGhpcyBmaWxlIGR1cmluZworICogcmVhZC1tb2RpZnktd3JpdGUgdHJhbnNhY3Rpb24pLCBwYXNzIGluIGEgTG9ja0ZpbGVPcGVuZXIgaW5zdGFuY2UgdG8ge0BsaW5rICN3aXRoTG9ja2luZ30gY2FsbC4KKyAqCisgKiA8cD5JbiBvcmRlciB0byBpbXBsZW1lbnQgZHVyYWJpbGl0eSAoZW5zdXJpbmcgdGhlIGRhdGEgaXMgaW4gcGVyc2lzdGVudCBzdG9yYWdlKSwgcGFzcworICogU3luY0JlaGF2aW9yIHRvIHRoZSBvcmlnaW5hbCBvcGVuIGNhbGwuCisgKgorICogPHA+Tk9URTogVGhpcyBkb2VzIG5vdCBmc3luYyB0aGUgZGlyZWN0b3J5IGl0c2VsZi4gU2VlIDxpbnRlcm5hbD4gZm9yIHBvc3NpYmxlIGltcGxlbWVudGF0aW9uCisgKiB1c2luZyBOSU8uCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJlYW1NdXRhdGlvbk9wZW5lciBpbXBsZW1lbnRzIE9wZW5lcjxTdHJlYW1NdXRhdGlvbk9wZW5lci5NdXRhdG9yPiB7CisKKyAgcHJpdmF0ZSBCZWhhdmlvcltdIGJlaGF2aW9yczsKKworICAvKioKKyAgICogT3ZlcnJpZGUgdGhpcyBpbnRlcmZhY2UgdG8gaW1wbGVtZW50IHRoZSB0cmFuc2Zvcm1hdGlvbi4gSXQgaXMgb2sgdG8gcmVhZCBpbnB1dCBhbmQgb3V0cHV0IGluCisgICAqIHBhcmFsbGVsLiBJZiBhbiBleGNlcHRpb24gaXMgdGhyb3duLCBleGVjdXRpb24gc3RvcHMgYW5kIHRoZSBkZXN0aW5hdGlvbiBmaWxlIHJlbWFpbnMKKyAgICogdW50b3VjaGVkLgorICAgKi8KKyAgcHVibGljIGludGVyZmFjZSBNdXRhdGlvbiB7CisgICAgYm9vbGVhbiBhcHBseShJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uOworICB9CisKKyAgQE51bGxhYmxlIHByaXZhdGUgTG9ja0ZpbGVPcGVuZXIgbG9ja2luZyA9IG51bGw7CisKKyAgcHJpdmF0ZSBTdHJlYW1NdXRhdGlvbk9wZW5lcigpIHt9CisKKyAgLyoqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGlzIG9wZW5lci4gKi8KKyAgcHVibGljIHN0YXRpYyBTdHJlYW1NdXRhdGlvbk9wZW5lciBjcmVhdGUoKSB7CisgICAgcmV0dXJuIG5ldyBTdHJlYW1NdXRhdGlvbk9wZW5lcigpOworICB9CisKKyAgLyoqCisgICAqIEVuYWJsZSBleGNsdXNpdmUgbG9ja2luZyB3aXRoIHRoaXMgb3BlbmVyLiBUaGlzIGlzIHVzZWZ1bCBpZiBtdWx0aXBsZSBwcm9jZXNzZXMgb3IgdGhyZWFkcyBuZWVkCisgICAqIHRvIG1haW50YWluIHRyYW5zYWN0aW9uYWwgaXNvbGF0aW9uLgorICAgKi8KKyAgcHVibGljIFN0cmVhbU11dGF0aW9uT3BlbmVyIHdpdGhMb2NraW5nKExvY2tGaWxlT3BlbmVyIGxvY2tpbmcpIHsKKyAgICB0aGlzLmxvY2tpbmcgPSBsb2NraW5nOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqIEFwcGx5IHRoZXNlIGJlaGF2aW9ycyB3aGlsZSB3cml0aW5nIG9ubHkuICovCisgIHB1YmxpYyBTdHJlYW1NdXRhdGlvbk9wZW5lciB3aXRoQmVoYXZpb3JzKEJlaGF2aW9yLi4uIGJlaGF2aW9ycykgeworICAgIHRoaXMuYmVoYXZpb3JzID0gYmVoYXZpb3JzOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqIE9wZW4gdGhpcyBVUkkgZm9yIG11dGF0aW5nLiBJZiB0aGUgZmlsZSBkb2VzIG5vdCBleGlzdCwgY3JlYXRlIGl0LiAqLworICBAT3ZlcnJpZGUKKyAgcHVibGljIE11dGF0b3Igb3BlbihPcGVuQ29udGV4dCBvcGVuQ29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gbmV3IE11dGF0b3Iob3BlbkNvbnRleHQsIGxvY2tpbmcsIGJlaGF2aW9ycyk7CisgIH0KKworICAvKiogQW4gaW50ZXJtZWRpYXRlIHJlc3VsdCByZXR1cm5lZCBieSB0aGlzIG9wZW5lci4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNdXRhdG9yIGltcGxlbWVudHMgQ2xvc2VhYmxlIHsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJbnB1dFN0cmVhbSBFTVBUWV9JTlBVVFNUUkVBTSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSk7CisgICAgcHJpdmF0ZSBmaW5hbCBPcGVuQ29udGV4dCBvcGVuQ29udGV4dDsKKyAgICBwcml2YXRlIGZpbmFsIENsb3NlYWJsZSBsb2NrOworICAgIHByaXZhdGUgZmluYWwgQmVoYXZpb3JbXSBiZWhhdmlvcnM7CisKKyAgICBwcml2YXRlIE11dGF0b3IoCisgICAgICAgIE9wZW5Db250ZXh0IG9wZW5Db250ZXh0LCBATnVsbGFibGUgTG9ja0ZpbGVPcGVuZXIgbG9ja2luZywgQE51bGxhYmxlIEJlaGF2aW9yW10gYmVoYXZpb3JzKQorICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdGhpcy5vcGVuQ29udGV4dCA9IG9wZW5Db250ZXh0OworICAgICAgdGhpcy5iZWhhdmlvcnMgPSBiZWhhdmlvcnM7CisgICAgICBpZiAobG9ja2luZyAhPSBudWxsKSB7CisgICAgICAgIGxvY2sgPSBsb2NraW5nLm9wZW4ob3BlbkNvbnRleHQpOworICAgICAgICBpZiAobG9jayA9PSBudWxsKSB7CisgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb3VsZG4ndCBhY3F1aXJlIGxvY2siKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIHsKKyAgICAgICAgbG9jayA9IG51bGw7CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgbXV0YXRlKE11dGF0aW9uIG11dGF0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgdHJ5IChJbnB1dFN0cmVhbSBiYWNrZW5kSW4gPSBvcGVuRm9yUmVhZE9yRW1wdHkob3BlbkNvbnRleHQuZW5jb2RlZFVyaSgpKTsKKyAgICAgICAgICBJbnB1dFN0cmVhbSBpbiA9IG9wZW5Db250ZXh0LmNoYWluVHJhbnNmb3Jtc0ZvclJlYWQoYmFja2VuZEluKS5nZXQoMCkpIHsKKyAgICAgICAgVXJpIHRlbXBVcmkgPSBTY3JhdGNoRmlsZS5zY3JhdGNoVXJpKG9wZW5Db250ZXh0Lm9yaWdpbmFsVXJpKCkpOworICAgICAgICBib29sZWFuIGNvbW1pdCA9IGZhbHNlOworICAgICAgICB0cnkgKE91dHB1dFN0cmVhbSBiYWNrZW5kT3V0ID0gb3BlbkNvbnRleHQuYmFja2VuZCgpLm9wZW5Gb3JXcml0ZSh0ZW1wVXJpKSkgeworICAgICAgICAgIExpc3Q8T3V0cHV0U3RyZWFtPiBvdXRwdXRDaGFpbiA9IG9wZW5Db250ZXh0LmNoYWluVHJhbnNmb3Jtc0ZvcldyaXRlKGJhY2tlbmRPdXQpOworICAgICAgICAgIGlmIChiZWhhdmlvcnMgIT0gbnVsbCkgeworICAgICAgICAgICAgZm9yIChCZWhhdmlvciBiZWhhdmlvciA6IGJlaGF2aW9ycykgeworICAgICAgICAgICAgICBiZWhhdmlvci5mb3JPdXRwdXRDaGFpbihvdXRwdXRDaGFpbik7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IG91dHB1dENoYWluLmdldCgwKSkgeworICAgICAgICAgICAgY29tbWl0ID0gbXV0YXRpb24uYXBwbHkoaW4sIG91dCk7CisgICAgICAgICAgICBpZiAoY29tbWl0KSB7CisgICAgICAgICAgICAgIGlmIChiZWhhdmlvcnMgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgIGZvciAoQmVoYXZpb3IgYmVoYXZpb3IgOiBiZWhhdmlvcnMpIHsKKyAgICAgICAgICAgICAgICAgIGJlaGF2aW9yLmNvbW1pdCgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG9wZW5Db250ZXh0LnN0b3JhZ2UoKS5kZWxldGVGaWxlKHRlbXBVcmkpOworICAgICAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleDIpIHsKKyAgICAgICAgICAgIC8vIElnbm9yZS4KKyAgICAgICAgICB9CisgICAgICAgICAgaWYgKGV4IGluc3RhbmNlb2YgSU9FeGNlcHRpb24pIHsKKyAgICAgICAgICAgIHRocm93IChJT0V4Y2VwdGlvbikgZXg7CisgICAgICAgICAgfQorICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihleCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNvbW1pdCkgeworICAgICAgICAgIG9wZW5Db250ZXh0LnN0b3JhZ2UoKS5yZW5hbWUodGVtcFVyaSwgb3BlbkNvbnRleHQub3JpZ2luYWxVcmkoKSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBpZiAobG9jayAhPSBudWxsKSB7CisgICAgICAgIGxvY2suY2xvc2UoKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBPcGVuIHRoZSBmaWxlIGZvciByZWFkIGlmIGl0J3MgcHJlc2VudCwgb3RoZXJ3aXNlIHJldHVybiBhbiBlbXB0eSBzdHJlYW0uCisgICAgcHJpdmF0ZSBJbnB1dFN0cmVhbSBvcGVuRm9yUmVhZE9yRW1wdHkoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHRyeSB7CisgICAgICAgIHJldHVybiBvcGVuQ29udGV4dC5iYWNrZW5kKCkub3BlbkZvclJlYWQodXJpKTsKKyAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleCkgeworICAgICAgICByZXR1cm4gRU1QVFlfSU5QVVRTVFJFQU07CisgICAgICB9CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TeXN0ZW1MaWJyYXJ5T3BlbmVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TeXN0ZW1MaWJyYXJ5T3BlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGY5MGI0MQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1N5c3RlbUxpYnJhcnlPcGVuZXIuamF2YQpAQCAtMCwwICsxLDExMCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgYW5kcm9pZC5hbm5vdGF0aW9uLlN1cHByZXNzTGludDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC51dGlsLkJhc2U2NDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmlvLkJ5dGVTdHJlYW1zOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKgorICogT3BlbmVyIGZvciBsb2FkaW5nIFVSSXMgYXMgc2hhcmVkIGxpYnJhcmllcy4KKyAqCisgKiA8cD5JbiBtYW55IGNhc2VzLCB0aGUgVVJJIGNhbm5vdCBiZSBsb2FkZWQgZGlyZWN0bHkgYW5kIG11c3QgYmUgY29waWVkIHRvIGEgY2FjaGUgZGlyZWN0b3J5CisgKiBmaXJzdC4gQ2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBlbnN1cmluZyB0aGF0IHRoaXMgY2FjaGUgZGlyZWN0b3J5IGlzIGNsZWFuZWQgcGVyaW9kaWNhbGx5LCBidXQKKyAqIHRoZXkgY2FuIGRvIHNvIHVzaW5nIGEgTW9iU3RvcmUgVVJJIHdpdGggVFRMLCBMUlUsIG9yIG90aGVyIGdhcmJhZ2UgY29sbGVjdGlvbiBtZXRob2QuCisgKgorICogPHA+V0FSTklORzogVGhpcyBvcGVuZXIgZG9lcyBubyB2YWxpZGF0aW9uIGFuZCBhc3N1bWVzIHRoYXQgdGhlIGRhdGEgaXQgcmVjZWl2ZXMgaXMgZ29vZC4gTm90ZQorICogdGhhdCBNb2JTdG9yZSBjYW4gdmFsaWRhdGUgYSBjaGVja3N1bSBwcmVzZW50IGluIHRoZSBVUkkuCisgKgorICogPHA+VE9ETyBDb25zaWRlciByZXF1aXJpbmcgdmFsaWRhdGlvbiBvZiBjaGVja3N1bS4KKyAqCisgKiA8cD5Vc2FnZTogPGNvZGU+CisgKiBzdG9yYWdlLm9wZW4odXJpLCBTeXN0ZW1MaWJyYXJ5T3BlbmVyLmNyZWF0ZSgpLndpdGhDYWNoZURpcmVjdG9yeShjYWNoZVJvb3RVcmkpKQorICogPC9jb2RlPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU3lzdGVtTGlicmFyeU9wZW5lciBpbXBsZW1lbnRzIE9wZW5lcjxWb2lkPiB7CisKKyAgQE51bGxhYmxlIHByaXZhdGUgVXJpIGNhY2hlRGlyZWN0b3J5OworCisgIHByaXZhdGUgU3lzdGVtTGlicmFyeU9wZW5lcigpIHt9CisKKyAgcHVibGljIFN5c3RlbUxpYnJhcnlPcGVuZXIgd2l0aENhY2hlRGlyZWN0b3J5KFVyaSBkaXIpIHsKKyAgICB0aGlzLmNhY2hlRGlyZWN0b3J5ID0gZGlyOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgcHVibGljIHN0YXRpYyBTeXN0ZW1MaWJyYXJ5T3BlbmVyIGNyZWF0ZSgpIHsKKyAgICByZXR1cm4gbmV3IFN5c3RlbUxpYnJhcnlPcGVuZXIoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBAU3VwcHJlc3NMaW50KCJVbnNhZmVEeW5hbWljYWxseUxvYWRlZENvZGUiKSAvLyBTeXN0ZW0ubG9hZCBpcyBuZWVkZWQgdG8gbG9hZCBmcm9tIGFyYml0cmFyeSBVcmlzCisgIHB1YmxpYyBWb2lkIG9wZW4oT3BlbkNvbnRleHQgb3BlbkNvbnRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZSBmaWxlID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgLy8gTk9URTogY291bGQgYmUgYmFja2VuZCgpLm9wZW5GaWxlKCkgaWYgd2UgYWRkZWQgdG8gQmFja2VuZCBpbnRlcmZhY2UuCisgICAgICBmaWxlID0gUmVhZEZpbGVPcGVuZXIuY3JlYXRlKCkub3BlbihvcGVuQ29udGV4dCk7CisgICAgICBTeXN0ZW0ubG9hZChmaWxlLmdldEFic29sdXRlUGF0aCgpKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBpZiAoY2FjaGVEaXJlY3RvcnkgPT0gbnVsbCkgeworICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkNhbm5vdCBkaXJlY3RseSBvcGVuIGZpbGUgYW5kIG5vIGNhY2hlIGRpcmVjdG9yeSBhdmFpbGFibGUuIik7CisgICAgICB9CisgICAgICBVcmkgY2FjaGVkVXJpID0KKyAgICAgICAgICBjYWNoZURpcmVjdG9yeQorICAgICAgICAgICAgICAuYnVpbGRVcG9uKCkKKyAgICAgICAgICAgICAgLmFwcGVuZFBhdGgoaGFzaGVkTGlicmFyeU5hbWUob3BlbkNvbnRleHQub3JpZ2luYWxVcmkoKSkpCisgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgdHJ5IHsKKyAgICAgICAgZmlsZSA9IG9wZW5Db250ZXh0LnN0b3JhZ2UoKS5vcGVuKGNhY2hlZFVyaSwgUmVhZEZpbGVPcGVuZXIuY3JlYXRlKCkpOworICAgICAgICBTeXN0ZW0ubG9hZChmaWxlLmdldEFic29sdXRlUGF0aCgpKTsKKyAgICAgIH0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlMikgeworICAgICAgICAvLyBOT1RFOiB0aGlzIGNvdWxkIGJlIGV4dHJhY3RlZCBhcyBDb3B5T3BlbmVyIGlmIHRoZSBuZWVkIGFyaXNlcworICAgICAgICB0cnkgKElucHV0U3RyZWFtIGZyb20gPQorICAgICAgICAgICAgICAgIG9wZW5Db250ZXh0LnN0b3JhZ2UoKS5vcGVuKG9wZW5Db250ZXh0Lm9yaWdpbmFsVXJpKCksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpOworICAgICAgICAgICAgT3V0cHV0U3RyZWFtIHRvID0gb3BlbkNvbnRleHQuc3RvcmFnZSgpLm9wZW4oY2FjaGVkVXJpLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgICAgICBCeXRlU3RyZWFtcy5jb3B5KGZyb20sIHRvKTsKKyAgICAgICAgICB0by5mbHVzaCgpOworICAgICAgICB9CisgICAgICAgIGZpbGUgPSBvcGVuQ29udGV4dC5zdG9yYWdlKCkub3BlbihjYWNoZWRVcmksIFJlYWRGaWxlT3BlbmVyLmNyZWF0ZSgpKTsKKyAgICAgICAgU3lzdGVtLmxvYWQoZmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBudWxsOyAvLyBSZXF1aXJlZCBieSBWb2lkIHJldHVybiB0eXBlLgorICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGhhc2hlZExpYnJhcnlOYW1lKFVyaSB1cmkpIHsKKyAgICB0cnkgeworICAgICAgTWVzc2FnZURpZ2VzdCBkaWdlc3QgPSBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJNRDUiKTsKKyAgICAgIGJ5dGVbXSBieXRlcyA9IGRpZ2VzdC5kaWdlc3QodXJpLnRvU3RyaW5nKCkuZ2V0Qnl0ZXMoKSk7CisgICAgICBTdHJpbmcgaGFzaCA9IEJhc2U2NC5lbmNvZGVUb1N0cmluZyhieXRlcywgQmFzZTY0Lk5PX1dSQVAgfCBCYXNlNjQuVVJMX1NBRkUpOworICAgICAgcmV0dXJuICIubW9ic3RvcmUtbGliLiIgKyBoYXNoICsgIi5zbyI7CisgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFVucmVhY2hhYmxlLgorICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIk1pc3NpbmcgTUQ1IGFsZ29yaXRobSBpbXBsZW1lbnRhdGlvbiIsIGUpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvV3JpdGVCeXRlQXJyYXlPcGVuZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1dyaXRlQnl0ZUFycmF5T3BlbmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDY3NmU3ZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1dyaXRlQnl0ZUFycmF5T3BlbmVyLmphdmEKQEAgLTAsMCArMSw2MiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5CZWhhdmlvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbmVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKKy8qKgorICogQW4gb3BlbmVyIHRoYXQgd3JpdGVzIGEgYnl0ZVtdIG9mIGRhdGEgZm9yIGEgVXJpLgorICoKKyAqIDxwPlVzYWdlOiA8Y29kZT4KKyAqIHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZShieXRlcykpOworICogPC9jb2RlPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgV3JpdGVCeXRlQXJyYXlPcGVuZXIgaW1wbGVtZW50cyBPcGVuZXI8Vm9pZD4geworCisgIHByaXZhdGUgZmluYWwgYnl0ZVtdIGJ5dGVzVG9Xcml0ZTsKKyAgcHJpdmF0ZSBCZWhhdmlvcltdIGJlaGF2aW9yczsKKworICBwcml2YXRlIFdyaXRlQnl0ZUFycmF5T3BlbmVyKGJ5dGVbXSBieXRlc1RvV3JpdGUpIHsKKyAgICB0aGlzLmJ5dGVzVG9Xcml0ZSA9IGJ5dGVzVG9Xcml0ZTsKKyAgfQorCisgIHB1YmxpYyBXcml0ZUJ5dGVBcnJheU9wZW5lciB3aXRoQmVoYXZpb3JzKEJlaGF2aW9yLi4uIGJlaGF2aW9ycykgeworICAgIHRoaXMuYmVoYXZpb3JzID0gYmVoYXZpb3JzOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqIENyZWF0ZXMgYSBuZXcgb3BlbmVyIGluc3RhbmNlIHRvIHdyaXRlIGEgYnl0ZSBhcnJheS4gKi8KKyAgcHVibGljIHN0YXRpYyBXcml0ZUJ5dGVBcnJheU9wZW5lciBjcmVhdGUoYnl0ZVtdIGJ5dGVzVG9Xcml0ZSkgeworICAgIHJldHVybiBuZXcgV3JpdGVCeXRlQXJyYXlPcGVuZXIoYnl0ZXNUb1dyaXRlKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgVm9pZCBvcGVuKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLndpdGhCZWhhdmlvcnMoYmVoYXZpb3JzKS5vcGVuKG9wZW5Db250ZXh0KSkgeworICAgICAgb3V0LndyaXRlKGJ5dGVzVG9Xcml0ZSk7CisgICAgICBpZiAoYmVoYXZpb3JzICE9IG51bGwpIHsKKyAgICAgICAgZm9yIChCZWhhdmlvciBiZWhhdmlvciA6IGJlaGF2aW9ycykgeworICAgICAgICAgIGJlaGF2aW9yLmNvbW1pdCgpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBudWxsOyAvLyBSZXF1aXJlZCBieSBWb2lkIHJldHVybiB0eXBlLgorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9Xcml0ZUZpbGVPcGVuZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1dyaXRlRmlsZU9wZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM5MzBmMTEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9Xcml0ZUZpbGVPcGVuZXIuamF2YQpAQCAtMCwwICsxLDIwMyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC51dGlsLkxvZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkZpbGVDb252ZXJ0aWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5SZWxlYXNhYmxlUmVzb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLldyaXRlRmlsZU9wZW5lci5GaWxlQ2xvc2VyOworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRnV0dXJlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNJbnRlZ2VyOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKgorICogT3BlbmVyIGZvciB3cml0aW5nIGRhdGEgdG8gYSB7QGxpbmsgamF2YS5pby5GaWxlfSBvYmplY3QuIERlcGVuZGluZyBvbiB0aGUgYmFja2VuZCwgdGhpcyBtYXkgd29yaworICogb25lIG9mIHRocmVlIHdheXMsCisgKgorICogPG9sPgorICogICA8bGk+VGhlIHNpbXBsZSBwb3NpeCBwYXRoLgorICogICA8bGk+QSAvcHJvYy9zZWxmL2ZkLyBwYXRoIHJlZmVycmluZyB0byBhIGZpbGUgZGVzY3JpcHRvciBmb3IgdGhlIG9yaWdpbmFsIGZpbGUuCisgKiAgIDxsaT5BIHBhdGggdG8gYSBGSUZPIChuYW1lZCBwaXBlKSB0byB3aGljaCBkYXRhIGNhbiBiZSB3cml0dGVuLgorICogPC9vbD4KKyAqCisgKiBOb3RlIHRoYXQgdGhlIHRoaXJkIG9wdGlvbiBpcyBkaXNhYmxlZCBieSBkZWZhdWx0LCBhbmQgbXVzdCBiZSB0dXJuZWQgb24gd2l0aCB7QGxpbmsKKyAqICN3aXRoRmFsbGJhY2tUb1BpcGVVc2luZ0V4ZWN1dG9yfS4KKyAqCisgKiA8cD5Vc2FnZTogPGNvZGU+CisgKiB0cnkgKFdyaXRlRmlsZU9wZW5lci5GaWxlQ2xvc2VyIGNsb3NlciA9CisgKiAgICAgc3RvcmFnZS5vcGVuKAorICogICAgICAgICB1cmksIFdyaXRlRmlsZU9wZW5lci5jcmVhdGUoKS53aXRoRmFsbGJhY2tUb1BpcGVVc2luZ0V4ZWN1dG9yKGV4ZWN1dG9yLCBjb250ZXh0KSkpIHsKKyAqICAgLy8gV3JpdGUgdG8gY2xvc2VyLmZpbGUoKQorICogfQorICogPC9jb2RlPgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgV3JpdGVGaWxlT3BlbmVyIGltcGxlbWVudHMgT3BlbmVyPEZpbGVDbG9zZXI+IHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIldyaXRlRmlsZU9wZW5lciI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBTVFJFQU1fQlVGRkVSX1NJWkUgPSA0MDk2OworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBBdG9taWNJbnRlZ2VyIEZJRk9fQ09VTlRFUiA9IG5ldyBBdG9taWNJbnRlZ2VyKCk7CisKKyAgLyoqIEEgZmlsZSwgY2xvc2VhYmxlIHBhaXIuICovCisgIHB1YmxpYyBpbnRlcmZhY2UgRmlsZUNsb3NlciBleHRlbmRzIENsb3NlYWJsZSB7CisgICAgRmlsZSBmaWxlKCk7CisgIH0KKworICAvKiogQSBGaWxlQ2xvc2VyIHRoYXQgY29udGFpbnMgYSBzdHJlYW0uICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIFN0cmVhbUZpbGVDbG9zZXIgaW1wbGVtZW50cyBGaWxlQ2xvc2VyIHsKKworICAgIHByaXZhdGUgZmluYWwgRmlsZSBmaWxlOworICAgIHByaXZhdGUgZmluYWwgT3V0cHV0U3RyZWFtIHN0cmVhbTsKKworICAgIFN0cmVhbUZpbGVDbG9zZXIoRmlsZSBmaWxlLCBPdXRwdXRTdHJlYW0gc3RyZWFtKSB7CisgICAgICB0aGlzLmZpbGUgPSBmaWxlOworICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIEZpbGUgZmlsZSgpIHsKKyAgICAgIHJldHVybiBmaWxlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIHN0cmVhbS5jbG9zZSgpOworICAgIH0KKyAgfQorCisgIC8qKiBBIEZpbGVDbG9zZXIgdGhhdCBjb250YWlucyBhIG5hbWVkIHBpcGUgYW5kIGEgZnV0dXJlIHRvIHRoZSB0aHJlYWQgcHVtcGluZyBkYXRhIHRocm91Z2ggaXQuICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIFBpcGVGaWxlQ2xvc2VyIGltcGxlbWVudHMgRmlsZUNsb3NlciB7CisKKyAgICBwcml2YXRlIGZpbmFsIEZpbGUgZmlmbzsKKyAgICBwcml2YXRlIGZpbmFsIEZ1dHVyZTxUaHJvd2FibGU+IHB1bXBGdXR1cmU7CisKKyAgICBQaXBlRmlsZUNsb3NlcihGaWxlIGZpZm8sIEZ1dHVyZTxUaHJvd2FibGU+IHB1bXBGdXR1cmUpIHsKKyAgICAgIHRoaXMuZmlmbyA9IGZpZm87CisgICAgICB0aGlzLnB1bXBGdXR1cmUgPSBwdW1wRnV0dXJlOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBGaWxlIGZpbGUoKSB7CisgICAgICByZXR1cm4gZmlmbzsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDbG9zZXMgdGhlIHdyYXBwZWQgZmlsZSBhbmQgYW55IGFzc29jaWF0ZWQgc3lzdGVtIHJlc291cmNlcy4gVGhpcyBtZXRob2Qgd2lsbCBibG9jayBvbiBzeXN0ZW0KKyAgICAgKiBJTyBpZiB0aGUgZmlsZSBpcyBwaXBlZCBhbmQgdGhlcmUgaXMgcmVtYWluaW5nIGRhdGEgdG8gYmUgd3JpdHRlbiB0byB0aGUgc3RyZWFtLgorICAgICAqCisgICAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgICAqLworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIElmIHRoZSBwaXBlJ3Mgd3JpdGUtc2lkZSB3YXMgbmV2ZXIgb3BlbmVkLCBvcGVuIGl0IGluIG9yZGVyIHRvIHVuYmxvY2sgdGhlIHB1bXAgdGhyZWFkLgorICAgICAgLy8gT3RoZXJ3aXNlLCB0aGlzIGlzIGhhcm1sZXNzIHRvIHRoZSBleGlzdGluZyBzdHJlYW0uCisgICAgICB0cnkgKEZpbGVPdXRwdXRTdHJlYW0gdW51c2VkID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZmlmbykpIHsKKyAgICAgICAgLy8gRG8gbm90aGluZy4KKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgTG9nLncoVEFHLCAiY2xvc2UoKSB0aHJldyBleGNlcHRpb24gd2hlbiB0cnlpbmcgdG8gdW5ibG9jayBwdW1wIiwgZSk7CisgICAgICB9IGZpbmFsbHkgeworICAgICAgICBmaWZvLmRlbGV0ZSgpOworICAgICAgfQorICAgICAgUGlwZXMuZ2V0QW5kUHJvcGFnYXRlQXNJT0V4Y2VwdGlvbihwdW1wRnV0dXJlKTsKKyAgICB9CisgIH0KKworICBATnVsbGFibGUgcHJpdmF0ZSBFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3I7CisgIEBOdWxsYWJsZSBwcml2YXRlIENvbnRleHQgY29udGV4dDsKKworICBwcml2YXRlIFdyaXRlRmlsZU9wZW5lcigpIHt9CisKKyAgcHVibGljIHN0YXRpYyBXcml0ZUZpbGVPcGVuZXIgY3JlYXRlKCkgeworICAgIHJldHVybiBuZXcgV3JpdGVGaWxlT3BlbmVyKCk7CisgIH0KKworICAvKioKKyAgICogSWYgZW5hYmxlZCwgc3RpbGwgdHJ5IHRvIHJldHVybiBhIHJhdyBmaWxlIHBhdGggYnV0LCBpZiB0aGF0IGZhaWxzLCByZXR1cm4gYSBGSUZPIChha2EgbmFtZWQKKyAgICogcGlwZSkgdG8gd2hpY2ggdGhlIGRhdGEgY2FuIGJlIHdyaXR0ZW4gYXMgYSBzdHJlYW0uIFJhdyBmaWxlIHBhdGhzIGFyZSBub3QgYXZhaWxhYmxlIGlmIHRoZXJlCisgICAqIGFyZSBhbnkgdHJhbnNmb3JtcyBpbnN0YWxsZWQ7IGlmIHRoZXJlIGFyZSBhbnkgbW9uaXRvcnMgaW5zdGFsbGVkOyBvciBpZiB0aGUgYmFja2VuZCBsYWNrcyBzdWNoCisgICAqIHN1cHBvcnQuCisgICAqCisgICAqIDxwPlRoZSBjYWxsZXIgTVVTVCBjbG9zZSB0aGUgcmV0dXJuZWQgY2xvc2VhYmxlIGluIG9yZGVyIHRvIGF2b2lkIGEgcG9zc2libGUgdGhyZWFkIGxlYWsuCisgICAqCisgICAqIDxwPldBUk5JTkc6IEZJRk9zIHJlcXVpcmUgU0RLIGxldmVsIDIxKyAoTG9sbGlwb3ApLiBJZiB0aGUgcmF3IGZpbGUgcGF0aCBpcyB1bmF2YWlsYWJsZSBhbmQgdGhlCisgICAqIGN1cnJlbnQgU0RLIGxldmVsIGlzIGluc3VmZmljaWVudCBmb3IgRklGT3MsIHRoZSBmYWxsYmFjayB3aWxsIGZhaWwgKHRocm93IElPRXhjZXB0aW9uKS4KKyAgICoKKyAgICogQHBhcmFtIGV4ZWN1dG9yIEV4ZWN1dG9yIHRoYXQgcHVtcHMgZGF0YS4KKyAgICogQHBhcmFtIGNvbnRleHQgQW5kcm9pZCBjb250ZXh0IGZvciB0aGUgcm9vdCBkaXJlY3Rvcnkgd2hlcmUgZmlmb3MgYXJlIHN0b3JlZC4KKyAgICogQHJldHVybiBUaGlzIG9wZW5lci4KKyAgICovCisgIHB1YmxpYyBXcml0ZUZpbGVPcGVuZXIgd2l0aEZhbGxiYWNrVG9QaXBlVXNpbmdFeGVjdXRvcigKKyAgICAgIEV4ZWN1dG9yU2VydmljZSBleGVjdXRvciwgQ29udGV4dCBjb250ZXh0KSB7CisgICAgdGhpcy5leGVjdXRvciA9IGV4ZWN1dG9yOworICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CisgICAgcmV0dXJuIHRoaXM7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEZpbGVDbG9zZXIgb3BlbihPcGVuQ29udGV4dCBvcGVuQ29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0cnkgKFJlbGVhc2FibGVSZXNvdXJjZTxPdXRwdXRTdHJlYW0+IG91dCA9CisgICAgICAgIFJlbGVhc2FibGVSZXNvdXJjZS5jcmVhdGUoV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkub3BlbihvcGVuQ29udGV4dCkpKSB7CisgICAgICBpZiAob3V0LmdldCgpIGluc3RhbmNlb2YgRmlsZUNvbnZlcnRpYmxlKSB7CisgICAgICAgIEZpbGUgZmlsZSA9ICgoRmlsZUNvbnZlcnRpYmxlKSBvdXQuZ2V0KCkpLnRvRmlsZSgpOworICAgICAgICByZXR1cm4gbmV3IFN0cmVhbUZpbGVDbG9zZXIoZmlsZSwgb3V0LnJlbGVhc2UoKSk7CisgICAgICB9CisgICAgICBpZiAoZXhlY3V0b3IgIT0gbnVsbCkgeworICAgICAgICByZXR1cm4gcGlwZUZyb21GaWxlKG91dC5yZWxlYXNlKCkpOworICAgICAgfQorICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJOb3QgY29udmVydGlibGUgYW5kIGZhbGxiYWNrIHRvIHBpcGUgaXMgZGlzYWJsZWQuIik7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBGaWxlQ2xvc2VyIHBpcGVGcm9tRmlsZShPdXRwdXRTdHJlYW0gb3V0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZpbGUgZmlmbyA9IFBpcGVzLm1ha2VGaWZvKGNvbnRleHQuZ2V0Q2FjaGVEaXIoKSwgVEFHLCBGSUZPX0NPVU5URVIpOworICAgIEZ1dHVyZTxUaHJvd2FibGU+IGZ1dHVyZSA9CisgICAgICAgIGV4ZWN1dG9yLnN1Ym1pdCgKKyAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpZm8pKSB7CisgICAgICAgICAgICAgICAgLy8gSW4gb3JkZXIgdG8gcmVhY2ggdGhpcyBwb2ludCwgd3JpdGVyIG11c3QgaGF2ZSBvcGVuZWQgdGhlIEZJRk8sIHNvIGl0J3Mgb2sKKyAgICAgICAgICAgICAgICAvLyB0byBkZWxldGUgaXQuCisgICAgICAgICAgICAgICAgZmlmby5kZWxldGUoKTsKKyAgICAgICAgICAgICAgICBieXRlW10gdG1wID0gbmV3IGJ5dGVbU1RSRUFNX0JVRkZFUl9TSVpFXTsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgaW50IGxlbjsKKyAgICAgICAgICAgICAgICAgIHdoaWxlICgobGVuID0gaW4ucmVhZCh0bXApKSAhPSAtMSkgeworICAgICAgICAgICAgICAgICAgICBvdXQud3JpdGUodG1wLCAwLCBsZW4pOworICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgb3V0LmZsdXNoKCk7CisgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHsKKyAgICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgIExvZy53KFRBRywgInB1bXAiLCBlKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gZTsKKyAgICAgICAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICBMb2cuZShUQUcsICJwdW1wIiwgdCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHQ7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICB9KTsKKyAgICByZXR1cm4gbmV3IFBpcGVGaWxlQ2xvc2VyKGZpZm8sIGZ1dHVyZSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1dyaXRlUHJvdG9PcGVuZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1dyaXRlUHJvdG9PcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MWYzZWI2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvV3JpdGVQcm90b09wZW5lci5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLkJlaGF2aW9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTGl0ZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKiogV3JpdGVzIGEgcHJvdG8gdG8gYSBmaWxlIGF0b21pY2FsbHkuICovCitwdWJsaWMgZmluYWwgY2xhc3MgV3JpdGVQcm90b09wZW5lciBpbXBsZW1lbnRzIE9wZW5lcjxWb2lkPiB7CisKKyAgcHJpdmF0ZSBmaW5hbCBNZXNzYWdlTGl0ZSBwcm90bzsKKyAgcHJpdmF0ZSBCZWhhdmlvcltdIGJlaGF2aW9yczsKKworICBwcml2YXRlIFdyaXRlUHJvdG9PcGVuZXIoTWVzc2FnZUxpdGUgcHJvdG8pIHsKKyAgICB0aGlzLnByb3RvID0gcHJvdG87CisgIH0KKworICBwdWJsaWMgc3RhdGljIFdyaXRlUHJvdG9PcGVuZXIgY3JlYXRlKE1lc3NhZ2VMaXRlIHByb3RvKSB7CisgICAgcmV0dXJuIG5ldyBXcml0ZVByb3RvT3BlbmVyKHByb3RvKTsKKyAgfQorCisgIC8qKgorICAgKiBTdXBwb3J0cyBhZGRpbmcgb3B0aW9ucyB0byB3cml0ZXMuIEZvciBleGFtcGxlLCBTeW5jQmVoYXZpb3Igd2lsbCBmb3JjZSBkYXRhIHRvIGJlIGZsdXNoZWQgYW5kCisgICAqIGR1cmFibHkgcGVyc2lzdGVkLgorICAgKi8KKyAgcHVibGljIFdyaXRlUHJvdG9PcGVuZXIgd2l0aEJlaGF2aW9ycyhCZWhhdmlvci4uLiBiZWhhdmlvcnMpIHsKKyAgICB0aGlzLmJlaGF2aW9ycyA9IGJlaGF2aW9yczsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgVm9pZCBvcGVuKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVyaSB0ZW1wVXJpID0gU2NyYXRjaEZpbGUuc2NyYXRjaFVyaShvcGVuQ29udGV4dC5lbmNvZGVkVXJpKCkpOworICAgIE91dHB1dFN0cmVhbSBiYWNrZW5kT3V0cHV0ID0gb3BlbkNvbnRleHQuYmFja2VuZCgpLm9wZW5Gb3JXcml0ZSh0ZW1wVXJpKTsKKyAgICBMaXN0PE91dHB1dFN0cmVhbT4gY2hhaW4gPSBvcGVuQ29udGV4dC5jaGFpblRyYW5zZm9ybXNGb3JXcml0ZShiYWNrZW5kT3V0cHV0KTsKKyAgICBpZiAoYmVoYXZpb3JzICE9IG51bGwpIHsKKyAgICAgIGZvciAoQmVoYXZpb3IgYmVoYXZpb3IgOiBiZWhhdmlvcnMpIHsKKyAgICAgICAgYmVoYXZpb3IuZm9yT3V0cHV0Q2hhaW4oY2hhaW4pOworICAgICAgfQorICAgIH0KKyAgICB0cnkgKE91dHB1dFN0cmVhbSBvdXQgPSBjaGFpbi5nZXQoMCkpIHsKKyAgICAgIHByb3RvLndyaXRlVG8ob3V0KTsKKyAgICAgIGlmIChiZWhhdmlvcnMgIT0gbnVsbCkgeworICAgICAgICBmb3IgKEJlaGF2aW9yIGJlaGF2aW9yIDogYmVoYXZpb3JzKSB7CisgICAgICAgICAgYmVoYXZpb3IuY29tbWl0KCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgIHRyeSB7CisgICAgICAgIG9wZW5Db250ZXh0LmJhY2tlbmQoKS5kZWxldGVGaWxlKHRlbXBVcmkpOworICAgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGV4MikgeworICAgICAgICAvLyBJZ25vcmUuCisgICAgICB9CisgICAgICBpZiAoZXggaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikgeworICAgICAgICB0aHJvdyAoSU9FeGNlcHRpb24pIGV4OworICAgICAgfQorICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGV4KTsKKyAgICB9CisgICAgb3BlbkNvbnRleHQuYmFja2VuZCgpLnJlbmFtZSh0ZW1wVXJpLCBvcGVuQ29udGV4dC5lbmNvZGVkVXJpKCkpOworICAgIHJldHVybiBudWxsOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9Xcml0ZVN0cmVhbU9wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvV3JpdGVTdHJlYW1PcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNmU2YzM3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvV3JpdGVTdHJlYW1PcGVuZXIuamF2YQpAQCAtMCwwICsxLDU0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLkJlaGF2aW9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBBbiBvcGVuZXIgdGhhdCByZXR1cm5zIGEgc2ltcGxlIE91dHB1dFN0cmVhbSBvcGVuZWQgZm9yIHdyaXRlLiBBbnkgZXhpc3RpbmcgY29udGVudCBpcyB0cnVuY2F0ZWQuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBXcml0ZVN0cmVhbU9wZW5lciBpbXBsZW1lbnRzIE9wZW5lcjxPdXRwdXRTdHJlYW0+IHsKKworICBwcml2YXRlIEJlaGF2aW9yW10gYmVoYXZpb3JzOworCisgIHByaXZhdGUgV3JpdGVTdHJlYW1PcGVuZXIoKSB7fQorCisgIHB1YmxpYyBzdGF0aWMgV3JpdGVTdHJlYW1PcGVuZXIgY3JlYXRlKCkgeworICAgIHJldHVybiBuZXcgV3JpdGVTdHJlYW1PcGVuZXIoKTsKKyAgfQorCisgIHB1YmxpYyBXcml0ZVN0cmVhbU9wZW5lciB3aXRoQmVoYXZpb3JzKEJlaGF2aW9yLi4uIGJlaGF2aW9ycykgeworICAgIHRoaXMuYmVoYXZpb3JzID0gYmVoYXZpb3JzOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBPdXRwdXRTdHJlYW0gb3BlbihPcGVuQ29udGV4dCBvcGVuQ29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBPdXRwdXRTdHJlYW0gYmFja2VuZE91dHB1dCA9IG9wZW5Db250ZXh0LmJhY2tlbmQoKS5vcGVuRm9yV3JpdGUob3BlbkNvbnRleHQuZW5jb2RlZFVyaSgpKTsKKyAgICBMaXN0PE91dHB1dFN0cmVhbT4gY2hhaW4gPSBvcGVuQ29udGV4dC5jaGFpblRyYW5zZm9ybXNGb3JXcml0ZShiYWNrZW5kT3V0cHV0KTsKKyAgICBpZiAoYmVoYXZpb3JzICE9IG51bGwpIHsKKyAgICAgIGZvciAoQmVoYXZpb3IgYmVoYXZpb3IgOiBiZWhhdmlvcnMpIHsKKyAgICAgICAgYmVoYXZpb3IuZm9yT3V0cHV0Q2hhaW4oY2hhaW4pOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gY2hhaW4uZ2V0KDApOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9Xcml0ZVN0cmluZ09wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvV3JpdGVTdHJpbmdPcGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzJhOThjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvV3JpdGVTdHJpbmdPcGVuZXIuamF2YQpAQCAtMCwwICsxLDU2IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLkJlaGF2aW9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuQ2hhcnNldHM7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CisKKy8qKiBBbiBvcGVuZXIgdGhhdCByZWFkcyBlbnRpcmUgY29udGVudHMgb2YgZmlsZSBpbnRvIGEgU3RyaW5nLiAqLworcHVibGljIGZpbmFsIGNsYXNzIFdyaXRlU3RyaW5nT3BlbmVyIGltcGxlbWVudHMgT3BlbmVyPFZvaWQ+IHsKKyAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgc3RyaW5nOworICBwcml2YXRlIENoYXJzZXQgY2hhcnNldCA9IENoYXJzZXRzLlVURl84OworICBwcml2YXRlIEJlaGF2aW9yW10gYmVoYXZpb3JzOworCisgIFdyaXRlU3RyaW5nT3BlbmVyKFN0cmluZyBzdHJpbmcpIHsKKyAgICB0aGlzLnN0cmluZyA9IHN0cmluZzsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgV3JpdGVTdHJpbmdPcGVuZXIgY3JlYXRlKFN0cmluZyBzdHJpbmcpIHsKKyAgICByZXR1cm4gbmV3IFdyaXRlU3RyaW5nT3BlbmVyKHN0cmluZyk7CisgIH0KKworICBwdWJsaWMgV3JpdGVTdHJpbmdPcGVuZXIgd2l0aENoYXJzZXQoQ2hhcnNldCBjaGFyc2V0KSB7CisgICAgdGhpcy5jaGFyc2V0ID0gY2hhcnNldDsKKyAgICByZXR1cm4gdGhpczsKKyAgfQorCisgIHB1YmxpYyBXcml0ZVN0cmluZ09wZW5lciB3aXRoQmVoYXZpb3JzKEJlaGF2aW9yLi4uIGJlaGF2aW9ycykgeworICAgIHRoaXMuYmVoYXZpb3JzID0gYmVoYXZpb3JzOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBWb2lkIG9wZW4oT3BlbkNvbnRleHQgb3BlbkNvbnRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgV3JpdGVCeXRlQXJyYXlPcGVuZXIuY3JlYXRlKHN0cmluZy5nZXRCeXRlcyhjaGFyc2V0KSkKKyAgICAgICAgLndpdGhCZWhhdmlvcnMoYmVoYXZpb3JzKQorICAgICAgICAub3BlbihvcGVuQ29udGV4dCk7CisgICAgcmV0dXJuIG51bGw7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zYW1wbGVzL0JVSUxEIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NhbXBsZXMvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGQyMTIzMAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zYW1wbGVzL0JVSUxECkBAIC0wLDAgKzEsMzUgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJzYW1wbGVzIiwKKyAgICBzcmNzID0gZ2xvYigKKyAgICAgICAgWyIqLmphdmEiXSwKKyAgICAgICAgZXhjbHVkZSA9IFsiRGVtb0FjdGl2aXR5LmphdmEiXSwKKyAgICApLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6Y2hhcnNldHMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIkBhbmRyb2lkeF9hcHBjb21wYXRfYXBwY29tcGF0IiwgICMgYnVpbGRjbGVhbmVyOiBrZWVwCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zYW1wbGVzL0Jhc2U2NEJhY2tlbmQuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zYW1wbGVzL0Jhc2U2NEJhY2tlbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNjVkZTBiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NhbXBsZXMvQmFzZTY0QmFja2VuZC5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc2FtcGxlczsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5CYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkZvcndhcmRpbmdCYWNrZW5kOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqIEFuIGV4YW1wbGUgYmFja2VuZCB0aGF0IHdyYXBzIGFub3RoZXIgYmFja2VuZCBhbmQgYSB0cmFuc2Zvcm0uIEVuY29kZXMgYWxsIGRhdGEgYXMgYmFzZTY0LiAqLworcHVibGljIGNsYXNzIEJhc2U2NEJhY2tlbmQgZXh0ZW5kcyBGb3J3YXJkaW5nQmFja2VuZCB7CisgIHByaXZhdGUgZmluYWwgQmFzZTY0VHJhbnNmb3JtIGJhc2U2NCA9IG5ldyBCYXNlNjRUcmFuc2Zvcm0oKTsKKyAgcHJpdmF0ZSBmaW5hbCBCYWNrZW5kIGphdmFCYWNrZW5kID0gbmV3IEphdmFGaWxlQmFja2VuZCgpOworCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgQmFja2VuZCBkZWxlZ2F0ZSgpIHsKKyAgICByZXR1cm4gamF2YUJhY2tlbmQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgIHJldHVybiAiYmFzZTY0IjsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgSW5wdXRTdHJlYW0gb3BlbkZvclJlYWQoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gYmFzZTY0LndyYXBGb3JSZWFkKHVyaSwgc3VwZXIub3BlbkZvclJlYWQodXJpKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE91dHB1dFN0cmVhbSBvcGVuRm9yV3JpdGUoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gYmFzZTY0LndyYXBGb3JXcml0ZSh1cmksIHN1cGVyLm9wZW5Gb3JXcml0ZSh1cmkpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3V0cHV0U3RyZWFtIG9wZW5Gb3JBcHBlbmQoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gYmFzZTY0LndyYXBGb3JBcHBlbmQodXJpLCBzdXBlci5vcGVuRm9yQXBwZW5kKHVyaSkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcy9CYXNlNjRUcmFuc2Zvcm0uamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zYW1wbGVzL0Jhc2U2NFRyYW5zZm9ybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExZjE2NDEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcy9CYXNlNjRUcmFuc2Zvcm0uamF2YQpAQCAtMCwwICsxLDY3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNhbXBsZXM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuQ2hhcnNldHMuVVNfQVNDSUk7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLkNoYXJzZXRzLlVURl84OworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmlvLkJhc2VFbmNvZGluZzsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLldyaXRlcjsKKworLyoqIEEgZGVtbyB0cmFuc2Zvcm0gdGhhdCBlbmNvZGVzL2RlY29kZXMgdG8gYmFzZTY0LiAqLworcHVibGljIGZpbmFsIGNsYXNzIEJhc2U2NFRyYW5zZm9ybSBpbXBsZW1lbnRzIFRyYW5zZm9ybSB7CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgbmFtZSgpIHsKKyAgICByZXR1cm4gImJhc2U2NCI7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIHdyYXBGb3JSZWFkKFVyaSB1cmksIElucHV0U3RyZWFtIHdyYXBwZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgUmVhZGVyIHJlYWRlciA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcih3cmFwcGVkLCBVU19BU0NJSS5uZXdEZWNvZGVyKCkpOworICAgIHJldHVybiBCYXNlRW5jb2RpbmcuYmFzZTY0KCkuZGVjb2RpbmdTdHJlYW0ocmVhZGVyKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3V0cHV0U3RyZWFtIHdyYXBGb3JXcml0ZShVcmkgdXJpLCBPdXRwdXRTdHJlYW0gd3JhcHBlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBXcml0ZXIgd3JpdGVyID0gbmV3IE91dHB1dFN0cmVhbVdyaXRlcih3cmFwcGVkLCBVU19BU0NJSS5uZXdFbmNvZGVyKCkpOworICAgIHJldHVybiBCYXNlRW5jb2RpbmcuYmFzZTY0KCkuZW5jb2RpbmdTdHJlYW0od3JpdGVyKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3V0cHV0U3RyZWFtIHdyYXBGb3JBcHBlbmQoVXJpIHVyaSwgT3V0cHV0U3RyZWFtIHdyYXBwZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oIkNhbm5vdCBhcHBlbmQgdG8gZW5jb2RlZCBmaWxlIGJlY2F1c2Ugb2YgcGFkZGluZy4iKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIGVuY29kZShVcmkgdXJpLCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICByZXR1cm4gQmFzZUVuY29kaW5nLmJhc2U2NCgpLmVuY29kZShmaWxlbmFtZS5nZXRCeXRlcygpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIGRlY29kZShVcmkgdXJpLCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICByZXR1cm4gbmV3IFN0cmluZyhCYXNlRW5jb2RpbmcuYmFzZTY0KCkuZGVjb2RlKGZpbGVuYW1lKSwgVVRGXzgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcy9CeXRlQ291bnRpbmdNb25pdG9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcy9CeXRlQ291bnRpbmdNb25pdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmFjZjljOAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zYW1wbGVzL0J5dGVDb3VudGluZ01vbml0b3IuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNhbXBsZXM7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZHguYW5ub3RhdGlvbi5WaXNpYmxlRm9yVGVzdGluZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5Nb25pdG9yOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNMb25nOworCisvKiogQSBtb25pdG9yIHRoYXQgY291bnRzIGJ5dGVzIHJlYWQgYW5kIHdyaXR0ZW4uICovCitwdWJsaWMgY2xhc3MgQnl0ZUNvdW50aW5nTW9uaXRvciBpbXBsZW1lbnRzIE1vbml0b3IgeworICBwcml2YXRlIGZpbmFsIEF0b21pY0xvbmcgYnl0ZXNSZWFkID0gbmV3IEF0b21pY0xvbmcoKTsKKyAgcHJpdmF0ZSBmaW5hbCBBdG9taWNMb25nIGJ5dGVzV3JpdHRlbiA9IG5ldyBBdG9taWNMb25nKCk7CisKKyAgLy8gTk9URTogQSByZWFsIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgd291bGQgdHJhbnNtaXQgdGhlc2Ugc3RhdHMgdG8gYSBsb2dnaW5nCisgIC8vIHN5c3RlbSBzdWNoIGFzIDxpbnRlcm5hbD4uIFRoZSBjb3VudGVycyBhcmUgYXRvbWljIHNvIHRoYXQgc3VjaCBhIG1vbml0b3JpbmcKKyAgLy8gdGFzayBjYW4gaGFwcGVuIGluIGFub3RoZXIgdGhyZWFkIHNhZmVseS4KKyAgQFZpc2libGVGb3JUZXN0aW5nCisgIHB1YmxpYyBsb25nW10gc3RhdHMoKSB7CisgICAgcmV0dXJuIG5ldyBsb25nW10ge2J5dGVzUmVhZC5sb25nVmFsdWUoKSwgYnl0ZXNXcml0dGVuLmxvbmdWYWx1ZSgpfTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTW9uaXRvci5JbnB1dE1vbml0b3IgbW9uaXRvclJlYWQoVXJpIHVyaSkgeworICAgIHJldHVybiBuZXcgSW5wdXRDb3VudGVyKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE1vbml0b3IuT3V0cHV0TW9uaXRvciBtb25pdG9yV3JpdGUoVXJpIHVyaSkgeworICAgIHJldHVybiBuZXcgT3V0cHV0Q291bnRlcigpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBNb25pdG9yLk91dHB1dE1vbml0b3IgbW9uaXRvckFwcGVuZChVcmkgdXJpKSB7CisgICAgcmV0dXJuIG5ldyBPdXRwdXRDb3VudGVyKCk7CisgIH0KKworICBjbGFzcyBJbnB1dENvdW50ZXIgaW1wbGVtZW50cyBNb25pdG9yLklucHV0TW9uaXRvciB7CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYnl0ZXNSZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICBieXRlc1JlYWQuZ2V0QW5kQWRkKGxlbik7CisgICAgfQorICB9CisKKyAgY2xhc3MgT3V0cHV0Q291bnRlciBpbXBsZW1lbnRzIE1vbml0b3IuT3V0cHV0TW9uaXRvciB7CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYnl0ZXNXcml0dGVuKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB7CisgICAgICBieXRlc1dyaXR0ZW4uZ2V0QW5kQWRkKGxlbik7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcy9DYXBpdGFsaXphdGlvblRyYW5zZm9ybS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NhbXBsZXMvQ2FwaXRhbGl6YXRpb25UcmFuc2Zvcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43M2Q5OWQ4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NhbXBsZXMvQ2FwaXRhbGl6YXRpb25UcmFuc2Zvcm0uamF2YQpAQCAtMCwwICsxLDEwMSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zYW1wbGVzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlNpemFibGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuVHJhbnNmb3JtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqCisgKiBUaGlzIGlzIGEgdG95IHRyYW5zZm9ybSB0aGF0IGlzIHVzZWZ1bCB0byBpbGx1c3RyYXRlIHRoYXQgdGhlIGludm9jYXRpb24gb3JkZXIgaXMgY29ycmVjdCB3aGVuCisgKiBjb21iaW5lZCB3aXRoIGEgYmFzZTY0IHRyYW5zZm9ybS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIENhcGl0YWxpemF0aW9uVHJhbnNmb3JtIGltcGxlbWVudHMgVHJhbnNmb3JtIHsKKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgIHJldHVybiAiY2FwaXRhbGl6ZSI7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIHdyYXBGb3JSZWFkKFVyaSB1cmksIElucHV0U3RyZWFtIHdyYXBwZWQpIHsKKyAgICByZXR1cm4gbmV3IENhcGl0YWxpemF0aW9uSW5wdXRTdHJlYW0od3JhcHBlZCk7CisgIH0KKworICBAU3VwcHJlc3NXYXJuaW5ncygiSW5wdXRTdHJlYW1TbG93TXVsdGlieXRlUmVhZCIpCisgIC8vIE5PVEU6IE5vdCBib3RoZXJpbmcgdG8gb3ZlcnJpZGUgcmVhZChieXRlW10saW50LGludCkgYi9jIHRoaXMgdHJhbnNmb3JtCisgIC8vIGlzIG5ldmVyIGludGVuZGVkIHRvIGJlIHVzZWQgZm9yIGFueXRoaW5nIGJlc2lkZXMgYW4gZXhhbXBsZS4KKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ2FwaXRhbGl6YXRpb25JbnB1dFN0cmVhbSBleHRlbmRzIElucHV0U3RyZWFtIGltcGxlbWVudHMgU2l6YWJsZSB7CisKKyAgICBwcml2YXRlIGZpbmFsIElucHV0U3RyZWFtIGluOworCisgICAgcHJpdmF0ZSBDYXBpdGFsaXphdGlvbklucHV0U3RyZWFtKElucHV0U3RyZWFtIGluKSB7CisgICAgICB0aGlzLmluID0gaW47CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGludCBiID0gaW4ucmVhZCgpOworICAgICAgaWYgKGIgPT0gLTEpIHsKKyAgICAgICAgcmV0dXJuIGI7CisgICAgICB9CisgICAgICByZXR1cm4gQ2hhcmFjdGVyLnRvU3RyaW5nKChjaGFyKSBiKS50b1VwcGVyQ2FzZSgpLmNoYXJBdCgwKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTG9uZyBzaXplKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmICghKGluIGluc3RhbmNlb2YgU2l6YWJsZSkpIHsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgICByZXR1cm4gKChTaXphYmxlKSBpbikuc2l6ZSgpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3V0cHV0U3RyZWFtIHdyYXBGb3JXcml0ZShVcmkgdXJpLCBPdXRwdXRTdHJlYW0gd3JhcHBlZCkgeworICAgIE91dHB1dFN0cmVhbSBzdHJlYW0gPQorICAgICAgICBuZXcgT3V0cHV0U3RyZWFtKCkgeworICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlKGludCBiKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAgICAgd3JhcHBlZC53cml0ZShDaGFyYWN0ZXIudG9TdHJpbmcoKGNoYXIpIGIpLnRvTG93ZXJDYXNlKCkuY2hhckF0KDApKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICAgICAgICB3cmFwcGVkLmNsb3NlKCk7CisgICAgICAgICAgfQorICAgICAgICB9OworICAgIHJldHVybiBzdHJlYW07CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE91dHB1dFN0cmVhbSB3cmFwRm9yQXBwZW5kKFVyaSB1cmksIE91dHB1dFN0cmVhbSB3cmFwcGVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiB3cmFwRm9yV3JpdGUodXJpLCB3cmFwcGVkKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIGVuY29kZShVcmkgdXJpLCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICByZXR1cm4gZmlsZW5hbWUudG9Mb3dlckNhc2UoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgU3RyaW5nIGRlY29kZShVcmkgdXJpLCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICByZXR1cm4gZmlsZW5hbWUudG9VcHBlckNhc2UoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaS9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjNjYzMxOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkvQlVJTEQKQEAgLTAsMCArMSwzMSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gInNwaSIsCisgICAgc3JjcyA9IGdsb2IoWyIqLmphdmEiXSksCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICMgTk9URTogZGVwZW5kZW5jeSBvZiBnbXNjb3JlIGNsaWVudCBsaWIgPGludGVybmFsPgorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpL0JhY2tlbmQuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkvQmFja2VuZC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEyZGFlZjEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpL0JhY2tlbmQuamF2YQpAQCAtMCwwICsxLDE5MiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGk7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC51dGlsLlBhaXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uR2NQYXJhbTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5Mb2NrU2NvcGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworCisvKioKKyAqIEJhY2tlbmRzIGFyZSBpbnN0YW50aWF0ZWQgb25jZSBwZXIgcHJvdG9jb2wgZHVyaW5nIGluaXRpYWxpemF0aW9uLiBUaGV5IGVuY2Fwc3VsYXRlIHRoZSBtZXRob2RzCisgKiBuZWVkZWQgdG8gaW50ZXJhY3Qgd2l0aCBhIGNvbmNyZXRlIHN0b3JhZ2UgbWVjaGFuaXNtLgorICoKKyAqIDxwPkJhY2tlbmQgbWV0aG9kcyBhcmUgZXhwZWN0ZWQgdG8gaWdub3JlIHRoZSBVUkkgZnJhZ21lbnQsIGFzIHRoZSB0cmFuc2Zvcm0gZW5jb2RlZCBpbiBpdCBhcmUKKyAqIGludGVycHJldGVkIGJ5IHRoZSBoaWdoZXItbGV2ZWwgQVBJIChzZWUge0BsaW5rIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2V9KS4KKyAqLworcHVibGljIGludGVyZmFjZSBCYWNrZW5kIHsKKyAgLyoqCisgICAqIE5hbWUgZm9yIHRoaXMgYmFja2VuZC4gTXVzdCBiZSBBU0NJSSBhbHBoYW51bWVyaWMuIFVzZWQgYXMgdGhlIHNjaGVtZSBpbiB0aGUgVXJpLgorICAgKgorICAgKiBAcmV0dXJuIFRoZSBuYW1lLCB3aGljaCBhcHBlYXJzIGFzIHRoZSBzY2hlbWUgb2YgdGhlIHVyaS4KKyAgICovCisgIFN0cmluZyBuYW1lKCk7CisKKyAgLyoqCisgICAqIE9wZW4gdGhpcyBVcmkgZm9yIHJlYWRpbmcuCisgICAqCisgICAqIEBwYXJhbSB1cmkKKyAgICogQHJldHVybiBBIElucHV0U3RyZWFtIGZvciByZWFkaW5nIGZyb20uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIGRlZmF1bHQgSW5wdXRTdHJlYW0gb3BlbkZvclJlYWQoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbigib3BlbkZvclJlYWQgbm90IHN1cHBvcnRlZCBieSAiICsgbmFtZSgpKTsKKyAgfQorCisgIC8qKgorICAgKiBPcGVuIHRoaXMgVXJpIGZvciByZWFkaW5nIGJ5IG5hdGl2ZSBjb2RlIGluIHRoZSBmb3JtIG9mIGEgZmlsZSBkZXNjcmlwdG9yIFVSSS4KKyAgICoKKyAgICogQHJldHVybiBBbiBmZCBVUkkuIENhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgY2xvc2luZy4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgZGVmYXVsdCBQYWlyPFVyaSwgQ2xvc2VhYmxlPiBvcGVuRm9yTmF0aXZlUmVhZChVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJvcGVuRm9yTmF0aXZlUmVhZCBub3Qgc3VwcG9ydGVkIGJ5ICIgKyBuYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIE9wZW4gdGhpcyBVcmkgZm9yIHdyaXRpbmcsIG92ZXJ3cml0aW5nIGFueSBleGlzdGluZyBjb250ZW50LgorICAgKgorICAgKiA8cD5Bbnkgbm9uLWV4aXN0ZW50IGRpcmVjdG9yaWVzIHdpbGwgYmUgY3JlYXRlZCBhcyBwYXJ0IG9mIG9wZW5pbmcgdGhlIGZpbGUuCisgICAqCisgICAqIEBwYXJhbSB1cmkKKyAgICogQHJldHVybiBBIE91dHB1dFN0cmVhbSB0byB3cml0ZSB0by4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgZGVmYXVsdCBPdXRwdXRTdHJlYW0gb3BlbkZvcldyaXRlKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oIm9wZW5Gb3JXcml0ZSBub3Qgc3VwcG9ydGVkIGJ5ICIgKyBuYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIE9wZW4gdGhpcyBVcmkgZm9yIGFwcGVuZC4KKyAgICoKKyAgICogPHA+QW55IG5vbi1leGlzdGVudCBkaXJlY3RvcmllcyB3aWxsIGJlIGNyZWF0ZWQgYXMgcGFydCBvZiBvcGVuaW5nIHRoZSBmaWxlLgorICAgKgorICAgKiBAcGFyYW0gdXJpCisgICAqIEByZXR1cm4gQSBPdXRwdXRTdHJlYW0gdG8gd3JpdGUgdG8uCisgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24KKyAgICovCisgIGRlZmF1bHQgT3V0cHV0U3RyZWFtIG9wZW5Gb3JBcHBlbmQoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbigib3BlbkZvckFwcGVuZCBub3Qgc3VwcG9ydGVkIGJ5ICIgKyBuYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIERlbGV0ZSB0aGUgZmlsZSBpZGVudGlmaWVkIHdpdGggdXJpLgorICAgKgorICAgKiBAcGFyYW0gdXJpCisgICAqIEB0aHJvd3MgRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGlmIHRoZSBmaWxlIGRvZXMgbm90IGV4aXN0LCBvciBpcyBhIGRpcmVjdG9yeQorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBmaWxlIGNvdWxkIG5vdCBiZSBkZWxldGVkIGZvciBhbnkgb3RoZXIgcmVhc29uCisgICAqLworICBkZWZhdWx0IHZvaWQgZGVsZXRlRmlsZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJkZWxldGVGaWxlIG5vdCBzdXBwb3J0ZWQgYnkgIiArIG5hbWUoKSk7CisgIH0KKworICAvKioKKyAgICogRGVsZXRlcyB0aGUgZGlyZWN0b3J5IGRlbm90ZWQgYnkge0Bjb2RlIHVyaX0uIFRoZSBkaXJlY3RvcnkgbXVzdCBiZSBlbXB0eSBpbiBvcmRlciB0byBiZQorICAgKiBkZWxldGVkLgorICAgKgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIHRoZSBkaXJlY3RvcnkgY291bGQgbm90IGJlIGRlbGV0ZWQgZm9yIGFueSByZWFzb24KKyAgICovCisgIGRlZmF1bHQgdm9pZCBkZWxldGVEaXJlY3RvcnkoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbigiZGVsZXRlRGlyZWN0b3J5IG5vdCBzdXBwb3J0ZWQgYnkgIiArIG5hbWUoKSk7CisgIH0KKworICAvKioKKyAgICogUmVuYW1lIHRoZSBmaWxlIG9yIGRpcmVjdG9yeSBpZGVudGlmaWVkIHdpdGgge0Bjb2RlIGZyb219IHRvIHtAY29kZSB0b30uCisgICAqCisgICAqIDxwPkFueSBub24tZXhpc3RlbnQgZGlyZWN0b3JpZXMgd2lsbCBiZSBjcmVhdGVkIGFzIHBhcnQgb2YgdGhlIHJlbmFtZS4KKyAgICoKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgZmlsZSBjb3VsZCBub3QgYmUgcmVuYW1lZCBmb3IgYW55IHJlYXNvbgorICAgKi8KKyAgZGVmYXVsdCB2b2lkIHJlbmFtZShVcmkgZnJvbSwgVXJpIHRvKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJyZW5hbWUgbm90IHN1cHBvcnRlZCBieSAiICsgbmFtZSgpKTsKKyAgfQorCisgIC8qKgorICAgKiBUZWxscyB3aGV0aGVyIHRoaXMgZmlsZSBvciBkaXJlY3RvcnkgZXhpc3RzLgorICAgKgorICAgKiBAcGFyYW0gdXJpCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBpdCBleGlzdHMuCisgICAqLworICBkZWZhdWx0IGJvb2xlYW4gZXhpc3RzKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oImV4aXN0cyBub3Qgc3VwcG9ydGVkIGJ5ICIgKyBuYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIFRlbGxzIHdoZXRoZXIgdGhpcyB1cmkgcmVmZXJzIHRvIGEgZGlyZWN0b3J5LgorICAgKgorICAgKiBAcGFyYW0gdXJpCisgICAqIEByZXR1cm4gVHJ1ZSBpZiBpdCBpcyBhIGRpcmVjdG9yeS4KKyAgICovCisgIGRlZmF1bHQgYm9vbGVhbiBpc0RpcmVjdG9yeShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJpc0RpcmVjdG9yeSBub3Qgc3VwcG9ydGVkIGJ5ICIgKyBuYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBuZXcgZGlyZWN0b3J5LiBBbnkgbm9uLWV4aXN0ZW50IHBhcmVudCBkaXJlY3RvcmllcyB3aWxsIGFsc28gYmUgY3JlYXRlZC4KKyAgICoKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiB0aGUgZGlyZWN0b3J5IGNvdWxkIG5vdCBiZSBjcmVhdGVkIGZvciBhbnkgcmVhc29uCisgICAqLworICBkZWZhdWx0IHZvaWQgY3JlYXRlRGlyZWN0b3J5KFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oImNyZWF0ZURpcmVjdG9yeSBub3Qgc3VwcG9ydGVkIGJ5ICIgKyBuYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIEdldHMgdGhlIGZpbGUgc2l6ZS4gSWYgdGhlIHVyaSByZWZlcnMgdG8gYSBkaXJlY3Rvcnkgb3Igbm9uLWV4aXN0ZW50LCByZXR1cm5zIDAuCisgICAqCisgICAqIEBwYXJhbSB1cmkKKyAgICogQHJldHVybiBUaGUgc2l6ZSBpbiBieXRlcyBvZiB0aGUgZmlsZS4KKyAgICovCisgIGRlZmF1bHQgbG9uZyBmaWxlU2l6ZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJmaWxlU2l6ZSBub3Qgc3VwcG9ydGVkIGJ5ICIgKyBuYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIExpc3RzIHRoZSBjaGlsZHJlbiBvZiB0aGlzIHBhcmVudCBkaXJlY3RvcnkuIElmIHRoZSBVcmkgcmVmZXJzIHRvIGEgbm9uLWRpcmVjdG9yeSwgYW4gZXhjZXB0aW9uCisgICAqIGlzIHRocm93bi4KKyAgICoKKyAgICogQHBhcmFtIHBhcmVudFVyaSBUaGUgcGFyZW50IGRpcmVjdG9yeSB0byBxdWVyeSBmb3IgY2hpbGRyZW4uCisgICAqIEByZXR1cm4gTGlzdCBvZiBmdWxseSBxdWFsaWZpZWQgVVJJcy4KKyAgICovCisgIGRlZmF1bHQgSXRlcmFibGU8VXJpPiBjaGlsZHJlbihVcmkgcGFyZW50VXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJjaGlsZHJlbiBub3Qgc3VwcG9ydGVkIGJ5ICIgKyBuYW1lKCkpOworICB9CisKKyAgLyoqIFJldHJpZXZlcyB0aGUge0BsaW5rIEdjUGFyYW19IGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gVVJJLiAqLworICBkZWZhdWx0IEdjUGFyYW0gZ2V0R2NQYXJhbShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJnZXRHY1BhcmFtIG5vdCBzdXBwb3J0ZWQgYnkgIiArIG5hbWUoKSk7CisgIH0KKworICAvKiogU2V0cyB0aGUge0BsaW5rIEdjUGFyYW19IGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gVVJJLiAqLworICBkZWZhdWx0IHZvaWQgc2V0R2NQYXJhbShVcmkgdXJpLCBHY1BhcmFtIHBhcmFtKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJzZXRHY1BhcmFtIG5vdCBzdXBwb3J0ZWQgYnkgIiArIG5hbWUoKSk7CisgIH0KKworICAvKiogQ29udmVydHMgdGhlIFVSSSB0byBhIEZpbGUgaWYgcG9zc2libGUuIExpa2UgYWxsIEJhY2tlbmQgbWV0aG9kcywgaWdub3JlcyBmcmFnbWVudC4gKi8KKyAgZGVmYXVsdCBGaWxlIHRvRmlsZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uKCJDYW5ub3QgY29udmVydCB1cmkgdG8gZmlsZSAiICsgbmFtZSgpICsgIiAiICsgdXJpKTsKKyAgfQorCisgIC8qKiBSZXRyaWV2ZXMgdGhlIHtAbGluayBMb2NrU2NvcGV9IHJlc3BvbnNpYmxlIGZvciBsb2NraW5nIGZpbGVzIGluIHRoaXMgQmFja2VuZC4gKi8KKyAgZGVmYXVsdCBMb2NrU2NvcGUgbG9ja1Njb3BlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbigibG9ja1Njb3BlIG5vdCBzdXBwb3J0ZWQgYnkgIiArIG5hbWUoKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkvRm9yd2FyZGluZ0JhY2tlbmQuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkvRm9yd2FyZGluZ0JhY2tlbmQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NmNmZDQ3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaS9Gb3J3YXJkaW5nQmFja2VuZC5qYXZhCkBAIC0wLDAgKzEsMTMzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaTsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5Mb2NrU2NvcGU7CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKgorICogQSBiYWNrZW5kIHdoaWNoIGZvcndhcmRzIGFsbCBpdHMgY2FsbHMgdG8gYW5vdGhlciBiYWNrZW5kLiBTdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZSBvbmUgb3IgbW9yZQorICogbWV0aG9kcyB0byB0byBtb2RpZnkgdGhlIGJlaGF2aW9yIG9mIHRoZSB3cmFwcGVkIGJhY2tlbmQuCisgKi8KK3B1YmxpYyBhYnN0cmFjdCBjbGFzcyBGb3J3YXJkaW5nQmFja2VuZCBpbXBsZW1lbnRzIEJhY2tlbmQgeworCisgIC8qKgorICAgKiBHZXRzIHRoZSBiYWNrZW5kIHRvIHdoaWNoIHRoaXMgYmFja2VuZCBmb3J3YXJkcyBjYWxscy4KKyAgICoKKyAgICogQHJldHVybiBUaGUgZGVsZWdhdGUuCisgICAqLworICBwcm90ZWN0ZWQgYWJzdHJhY3QgQmFja2VuZCBkZWxlZ2F0ZSgpOworCisgIC8qKgorICAgKiBSZXdyaXRlcyB0aGUgVXJpIHRvIHVzZSB0aGUgZGVsZWdhdGUncyBzY2hlbWUuIElmIHN1YmNsYXNzIGNhbGxzIHN1cGVyLm1ldGhvZCgpLCB0aGlzIGlzCisgICAqIGludm9rZWQgb24gdGhlIFVyaSBiZWZvcmUgY2FsbGluZyBtZXRob2QoKSBvbiBkZWxlZ2F0ZS4KKyAgICoKKyAgICogPHA+VGhpcyBtZXRob2QgaXMgYSBnb29kIHBsYWNlIHRvIGRvIHZhbGlkYXRpb24uIElmIHRoZSBVcmkgaXMgaW52YWxpZCwgaW1wbGVtZW50YXRpb24gc2hvdWxkCisgICAqIHRocm93IE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi4KKyAgICoKKyAgICogQHBhcmFtIHVyaSBUaGUgdXJpIHRoYXQgd2lsbCBoYXZlIGl0cyBzY2hlbWUgcmV3cml0dGVuLgorICAgKiBAcmV0dXJuIFRoZSB1cmkgd2l0aCB0aGUgc2NoZW1lIG9mIHRoZSBkZWxlZ2F0ZS4KKyAgICovCisgIHByb3RlY3RlZCBVcmkgcmV3cml0ZVVyaShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiB1cmkuYnVpbGRVcG9uKCkuc2NoZW1lKGRlbGVnYXRlKCkubmFtZSgpKS5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIFJldmVyc2VzIHRoZSByZXdyaXRlIHBlcmZvcm1lZCBieSByZXdyaXRlVXJpLiBUaGlzIGlzIHVzZWQgZm9yIGRpcmVjdG9yeSBsaXN0aW5nIG9wZXJhdGlvbnMuCisgICAqCisgICAqIEBwYXJhbSB1cmkgVGhlIHVyaSB0aGF0IGhhZCBpdHMgc2NoZW1lIHJld3JpdHRlbi4KKyAgICogQHJldHVybiBUaGUgdXJpIHdpdGggdGhlIHNjaGVtZSBmcm9tIHRoaXMgYmFja2VuZC4KKyAgICovCisgIHByb3RlY3RlZCBVcmkgcmV2ZXJzZVJld3JpdGVVcmkoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gdXJpLmJ1aWxkVXBvbigpLnNjaGVtZShuYW1lKCkpLmJ1aWxkKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIG9wZW5Gb3JSZWFkKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGRlbGVnYXRlKCkub3BlbkZvclJlYWQocmV3cml0ZVVyaSh1cmkpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgUGFpcjxVcmksIENsb3NlYWJsZT4gb3BlbkZvck5hdGl2ZVJlYWQoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZGVsZWdhdGUoKS5vcGVuRm9yTmF0aXZlUmVhZChyZXdyaXRlVXJpKHVyaSkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBPdXRwdXRTdHJlYW0gb3BlbkZvcldyaXRlKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGRlbGVnYXRlKCkub3BlbkZvcldyaXRlKHJld3JpdGVVcmkodXJpKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE91dHB1dFN0cmVhbSBvcGVuRm9yQXBwZW5kKFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGRlbGVnYXRlKCkub3BlbkZvckFwcGVuZChyZXdyaXRlVXJpKHVyaSkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGRlbGV0ZUZpbGUoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBkZWxlZ2F0ZSgpLmRlbGV0ZUZpbGUocmV3cml0ZVVyaSh1cmkpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBkZWxldGVEaXJlY3RvcnkoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBkZWxlZ2F0ZSgpLmRlbGV0ZURpcmVjdG9yeShyZXdyaXRlVXJpKHVyaSkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHJlbmFtZShVcmkgZnJvbSwgVXJpIHRvKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGRlbGVnYXRlKCkucmVuYW1lKHJld3JpdGVVcmkoZnJvbSksIHJld3JpdGVVcmkodG8pKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBleGlzdHMoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZGVsZWdhdGUoKS5leGlzdHMocmV3cml0ZVVyaSh1cmkpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBpc0RpcmVjdG9yeShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBkZWxlZ2F0ZSgpLmlzRGlyZWN0b3J5KHJld3JpdGVVcmkodXJpKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgY3JlYXRlRGlyZWN0b3J5KFVyaSB1cmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgZGVsZWdhdGUoKS5jcmVhdGVEaXJlY3RvcnkocmV3cml0ZVVyaSh1cmkpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgbG9uZyBmaWxlU2l6ZShVcmkgdXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBkZWxlZ2F0ZSgpLmZpbGVTaXplKHJld3JpdGVVcmkodXJpKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIEl0ZXJhYmxlPFVyaT4gY2hpbGRyZW4oVXJpIHBhcmVudFVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMaXN0PFVyaT4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxVcmk+KCk7CisgICAgZm9yIChVcmkgY2hpbGQgOiBkZWxlZ2F0ZSgpLmNoaWxkcmVuKHJld3JpdGVVcmkocGFyZW50VXJpKSkpIHsKKyAgICAgIHJlc3VsdC5hZGQocmV2ZXJzZVJld3JpdGVVcmkoY2hpbGQpKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTG9ja1Njb3BlIGxvY2tTY29wZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIGRlbGVnYXRlKCkubG9ja1Njb3BlKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkvTW9uaXRvci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaS9Nb25pdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjRiZDYyMwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkvTW9uaXRvci5qYXZhCkBAIC0wLDAgKzEsNzIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKgorICogQSBNb25pdG9yIG9ic2VydmVzIHRoZSBzdHJlYW0uIEl0IGNhbiBiZSB1c2VkIGZvciBwYXNzaXZlbHkgdHJhY2tpbmcgYWN0aXZpdHkgc3VjaCBhcyBudW1iZXIgb2YKKyAqIGJ5dGVzIHJlYWQgYW5kIHdyaXR0ZW4uIE1vbml0b3JzIGFyZSBub3QgaW52b2tlZCBmb3Igbm9uLXN0cmVhbS1iYXNlZCBvcGVyYXRpb25zLgorICoKKyAqIDxwPk1vbml0b3JzIGFyZSBleHBlY3RlZCB0byBwYXNzaXZlbHkgb2JzZXJ2ZSBhbmQgbm90IG11dGF0ZSB0aGUgc3RyZWFtLiBIb3dldmVyLCBmb3IgZWZmaWNpZW5jeSwKKyAqIHRoZSByYXcgYnl0ZVtdIGlzIHBhc3NlZCB0byB0aGUgaW1wbGVtZW50YXRpb24gc28gdGhpcyBpcyBub3QgZW5mb3JjZWQuIElmIHRoZSBhcnJheSBpcyBtdXRhdGVkLAorICogdGhlIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4gTW9yZW92ZXIsIG1vbml0b3JzIHJ1biBhcyBiZXN0LWVmZm9ydDogaWYgdGhleSBlbmNvdW50ZXIgYSBwcm9ibGVtLAorICogdGhleSBhcmUgZXhwZWN0ZWQgdG8gZ2V0IG91dCBvZiB0aGUgd2F5IGFuZCBub3QgYmxvY2sgdGhlIG1vbml0b3JlZCBzdHJlYW0gdHJhbnNhY3Rpb24uIFRoaXMgaXMKKyAqIHdoeSB0aGV5IGRvIE5PVCBoYXZlIElPRXhjZXB0aW9uIGluIHRoZWlyIG1ldGhvZCBzaWduYXR1cmVzLgorICoKKyAqIDxwPk1vbml0b3JzIGFyZSBpbnZva2VkIGFmdGVyIGFsbCB0cmFuc2Zvcm1zIGFyZSBhcHBsaWVkIGZvciB3cml0ZSwgYW5kIGJlZm9yZSBvbiByZWFkLiBGb3IKKyAqIGV4YW1wbGUsIGlmIHRoZXJlIGlzIGEgY29tcHJlc3Npb24gdHJhbnNmb3JtLCB0aGlzIG1vbml0b3Igd2lsbCBzZWUgdGhlIGNvbXByZXNzZWQgYnl0ZXMuCisgKgorICogPHA+VGhlIG9yaWdpbmFsIFVyaSBwYXNzZWQgdG8gdGhlIEZpbGVTdG9yYWdlIEFQSSwgaW5jbHVkaW5nIHRyYW5zZm9ybXMsIGlzIHBhc3NlZCB0byB0aGlzIEFQSS4KKyAqLworcHVibGljIGludGVyZmFjZSBNb25pdG9yIHsKKworICAvKiogQ3JlYXRlcyBhIG5ldyBpbnB1dCBtb25pdG9yIGZvciB0aGlzIFVyaSwgb3IgbnVsbCBpZiB0aGlzIElPIGRvZXNuJ3QgbmVlZCB0byBiZSBtb25pdG9yZWQuICovCisgIEBOdWxsYWJsZQorICBJbnB1dE1vbml0b3IgbW9uaXRvclJlYWQoVXJpIHVyaSk7CisKKyAgLyoqIENyZWF0ZXMgYSBuZXcgb3V0cHV0IG1vbml0b3IgZm9yIHRoaXMgVXJpLCBvciBudWxsIGlmIHRoaXMgSU8gZG9lc24ndCBuZWVkIHRvIGJlIG1vbml0b3JlZC4gKi8KKyAgQE51bGxhYmxlCisgIE91dHB1dE1vbml0b3IgbW9uaXRvcldyaXRlKFVyaSB1cmkpOworCisgIC8qKiBDcmVhdGVzIGEgbmV3IG91dHB1dCBtb25pdG9yIGZvciB0aGlzIFVyaSwgb3IgbnVsbCBpZiB0aGlzIElPIGRvZXNuJ3QgbmVlZCB0byBiZSBtb25pdG9yZWQuICovCisgIEBOdWxsYWJsZQorICBPdXRwdXRNb25pdG9yIG1vbml0b3JBcHBlbmQoVXJpIHVyaSk7CisKKyAgLyoqIE1vbml0b3JzIGRhdGEgcmVhZC4gKi8KKyAgaW50ZXJmYWNlIElucHV0TW9uaXRvciBleHRlbmRzIENsb3NlYWJsZSB7CisgICAgLyoqIENhbGxlZCB3aXRoIGJ5dGVzIGFzIHRoZXkgYXJlIHJlYWQgZnJvbSB0aGUgc3RyZWFtLiAqLworICAgIHZvaWQgYnl0ZXNSZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKTsKKworICAgIEBPdmVycmlkZQorICAgIGRlZmF1bHQgdm9pZCBjbG9zZSgpIHsKKyAgICAgIC8vIElnbm9yZS4KKyAgICB9CisgIH0KKworICAvKiogTW9uaXRvcnMgZGF0YSB3cml0dGVuLiAqLworICBpbnRlcmZhY2UgT3V0cHV0TW9uaXRvciBleHRlbmRzIENsb3NlYWJsZSB7CisgICAgLyoqIENhbGxlZCB3aXRoIGJ5dGVzIGFzIHRoZXkgYXJlIHdyaXR0ZW4gdG8gdGhlIHN0cmVhbS4gKi8KKyAgICB2b2lkIGJ5dGVzV3JpdHRlbihieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbik7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBkZWZhdWx0IHZvaWQgY2xvc2UoKSB7CisgICAgICAvLyBJZ25vcmUuCisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpL1RyYW5zZm9ybS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaS9UcmFuc2Zvcm0uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNzVjNTA2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaS9UcmFuc2Zvcm0uamF2YQpAQCAtMCwwICsxLDExMSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGk7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKKy8qKgorICogQSBUcmFuc2Zvcm0gbW9kaWZpZXMgdGhlIHN0cmVhbSB0byBwcm92aWRlIGVuY3J5cHRpb24sIGNvbXByZXNzaW9uLCBhbmQgb3RoZXIgc3VjaCBmZWF0dXJlcy4gV2hlbgorICogcmVnaXN0ZXJlZCwgdGhleSBjYW4gYmUgaW52b2tlZCBieSB1c2luZyBhIGZyYWdtZW50IGxpa2UgI3RyYW5zZm9ybT08bmFtZT4uIFRoZXkgY2FuIGFsc28gYmUKKyAqIGV4cGxpY2l0bHkgaW52b2tlZCBieSBhIEJhY2tlbmRzLgorICoKKyAqIDxwPlRyYW5zZm9ybXMgY2FuIGJlIHBhcmFtZXRlcml6ZWQgb24gdGhlIFVyaSB1c2luZyB0aGUgZnJhZ21lbnQgc3VicGFyYW1ldGVycy4gRm9yIGV4YW1wbGUsCisgKiAjdHJhbnNmb3JtPWNvbXByZXNzKGFsZ29yaXRobT1HWmlwKSB3b3VsZCBtYWtlIHRoZSBrZXkvdmFsdWUgcGFpciAiYWxnb3JpdGhtIi8iR1ppcCIgYXZhaWxhYmxlIHRvCisgKiB0aGUgdHJhbnNmb3JtLiBUYWtlbiB0b2dldGhlciwgdGhlIG5hbWUgYW5kIHN1YnBhcmFtZXRlcnMgYXJlIHRoZSB0cmFuc2Zvcm0gc3BlYy4KKyAqCisgKiA8cD5UcmFuc2Zvcm1zIGNhbiBtb2RpZnkgYm90aCB0aGUgYnl0ZSBzdHJlYW0gYW5kIHRoZSBuYW1lcyBvZiByZXNvdXJjZXMuIEZvciBleGFtcGxlLCBhbgorICogZW5jcnlwdGlvbiBUcmFuc2Zvcm0gY2FuIGVuY3J5cHQgZmlsZSBuYW1lcyBieSBpbXBsZW1lbnRpbmcgdGhlIHtAbGluayAjZW5jb2RlfSBhbmQge0BsaW5rCisgKiAjZGVjb2RlfSBtZXRob2RzLgorICovCitwdWJsaWMgaW50ZXJmYWNlIFRyYW5zZm9ybSB7CisKKyAgLyoqCisgICAqIFRoZSBuYW1lIGFzIGl0IHdvdWxkIGFwcGVhciBpbiB0aGUgZnJhZ21lbnQuIE11c3QgYmUgQVNDSUkgYW5kIFthLXpBLVowLTktXS4KKyAgICoKKyAgICogQHJldHVybiBUaGUgbmFtZS4KKyAgICovCisgIFN0cmluZyBuYW1lKCk7CisKKyAgLyoqCisgICAqIFdyYXAgdGhlIHJlcXVlc3RlZCBzdHJlYW0gd2l0aCBhbm90aGVyIHRoYXQgcGVyZm9ybXMgdGhlIGRlc2lyZWQgZGVjb2RpbmcgdHJhbnNmb3JtLgorICAgKgorICAgKiBAcGFyYW0gdXJpIFRoZSB3aG9sZSBVUkkgd2l0aCBmcmFnbWVudCBmb3IgdGhpcyB0cmFuc2FjdGlvbi4KKyAgICogQHBhcmFtIHdyYXBwZWQgVGhlIHdyYXBwZWQgc3RyZWFtLgorICAgKiBAcmV0dXJuIHRoZSB3cmFwcGVkIHN0cmVhbS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgZGVmYXVsdCBJbnB1dFN0cmVhbSB3cmFwRm9yUmVhZChVcmkgdXJpLCBJbnB1dFN0cmVhbSB3cmFwcGVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSAoSW5wdXRTdHJlYW0gdyA9IHdyYXBwZWQpIHt9CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oIndyYXBGb3JSZWFkIG5vdCBzdXBwb3J0ZWQgYnkgIiArIG5hbWUoKSk7CisgIH0KKworICAvKioKKyAgICogV3JhcCB0aGUgcmVxdWVzdGVkIHN0cmVhbSB3aXRoIGFub3RoZXIgdGhhdCBwZXJmb3JtcyB0aGUgZGVzaXJlZCBlbmNvZGluZyB0cmFuc2Zvcm0gZm9yIHdyaXRlCisgICAqIG9wZXJhdGlvbnMuCisgICAqCisgICAqIEBwYXJhbSB1cmkgVGhlIHdob2xlIFVSSSB3aXRoIGZyYWdtZW50IGZvciB0aGlzIHRyYW5zYWN0aW9uLgorICAgKiBAcGFyYW0gd3JhcHBlZCBUaGUgd3JhcHBlZCBzdHJlYW0uCisgICAqIEByZXR1cm4gdGhlIHdyYXBwZWQgc3RyZWFtLgorICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCisgICAqLworICBkZWZhdWx0IE91dHB1dFN0cmVhbSB3cmFwRm9yV3JpdGUoVXJpIHVyaSwgT3V0cHV0U3RyZWFtIHdyYXBwZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gdyA9IHdyYXBwZWQpIHt9CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24oIndyYXBGb3JXcml0ZSBub3Qgc3VwcG9ydGVkIGJ5ICIgKyBuYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIFdyYXAgdGhlIHJlcXVlc3RlZCBzdHJlYW0gd2l0aCBhbm90aGVyIHRoYXQgcGVyZm9ybXMgdGhlIGRlc2lyZWQgZW5jb2RpbmcgdHJhbnNmb3JtIGZvciBhcHBlbmQKKyAgICogb3BlcmF0aW9ucy4gVGhlIGZyYWdtZW50IHBhcmFtIGlzIGFuZCBjYW4gYmUgbW9kaWZpZWQgdW50aWwgdGhlIHN0cmVhbSBpcyBjbG9zZWQuCisgICAqCisgICAqIEBwYXJhbSB1cmkgVGhlIHdob2xlIFVSSSB3aXRoIGZyYWdtZW50IGZvciB0aGlzIHRyYW5zYWN0aW9uLgorICAgKiBAcGFyYW0gd3JhcHBlZCBUaGUgc3RyZWFtLgorICAgKiBAcmV0dXJuIHRoZSB3cmFwcGVkIHN0cmVhbS4KKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbgorICAgKi8KKyAgZGVmYXVsdCBPdXRwdXRTdHJlYW0gd3JhcEZvckFwcGVuZChVcmkgdXJpLCBPdXRwdXRTdHJlYW0gd3JhcHBlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICB0cnkgKE91dHB1dFN0cmVhbSB3ID0gd3JhcHBlZCkge30KKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbigid3JhcEZvckFwcGVuZCBub3Qgc3VwcG9ydGVkIGJ5ICIgKyBuYW1lKCkpOworICB9CisKKyAgLyoqCisgICAqIFJld3JpdGUgdGhlIGZpbGUgbmFtZS4gVGhpcyBpcyBjYWxsZWQgYnkgYWxsIGZpbGUtYmFzZWQgbWV0aG9kcyBvZiBGaWxlU3RvcmFnZSB3aGVuIHRoaXMKKyAgICogdHJhbnNmb3JtIGlzIHNwZWNpZmllZCB3aXRoIGEgZnJhZ21lbnQgcGFyYW0uIElmIHRoZXJlIGFyZSBtdWx0aXBsZSB0cmFuc2Zvcm1zLCB0aGVpciB7QGxpbmsKKyAgICogI2VuY29kZX0gbWV0aG9kcyBhcmUgaW52b2tlZCBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmUgc3BlY2lmaWVkLgorICAgKgorICAgKiBAcGFyYW0gdXJpIFRoZSB3aG9sZSBVUkkgd2l0aCBmcmFnbWVudCBmb3IgdGhpcyB0cmFuc2FjdGlvbi4KKyAgICogQHBhcmFtIGZpbGVuYW1lIFRoZSBvcmlnaW5hbCBmaWxlbmFtZS4KKyAgICogQHJldHVybiBUaGUgZW5jb2RlZCBmaWxlbmFtZS4KKyAgICovCisgIGRlZmF1bHQgU3RyaW5nIGVuY29kZShVcmkgdXJpLCBTdHJpbmcgZmlsZW5hbWUpIHsKKyAgICByZXR1cm4gZmlsZW5hbWU7CisgIH0KKworICAvKioKKyAgICogUmV2ZXJzZSB0aGUgcmV3cml0aW5nIG9mIHRoZSBmaWxlbmFtZSBkb25lIGJ5IHtAbGluayAjZW5jb2RlfS4gQ2FsbGVkIG9uIGFsbCBkaXJlY3Rvcnkgc2Nhbm5pbmcKKyAgICogbWV0aG9kcyBpbiBGaWxlU3RvcmFnZSBpbiB0aGUgcmV2ZXJzZSBvcmRlciBpbiB3aGljaCB7QGxpbmsgI2VuY29kZX0gaXMgY2FsbGVkLgorICAgKgorICAgKiBAcGFyYW0gcGFyYW0gVGhlIGZyYWdtZW50IHBhcmFtIHZhbHVlIGZvciB0aGlzIHRyYW5zZm9ybS4KKyAgICogQHBhcmFtIGZpbGVuYW1lIFRoZSBlbmNvZGVkIGZpbGVuYW1lLgorICAgKiBAcmV0dXJuIFRoZSBkZWNvZGVkIGZpbGVuYW1lLgorICAgKi8KKyAgZGVmYXVsdCBTdHJpbmcgZGVjb2RlKFVyaSB1cmksIFN0cmluZyBmaWxlbmFtZSkgeworICAgIHJldHVybiBmaWxlbmFtZTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45Zjk1MjVkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvQlVJTEQKQEAgLTAsMCArMSw4MSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKKyMgTW9zdCBjbGllbnRzIHNob3VsZCBkZXBlbmQgb24gdGhpcyB0YXJnZXQuIEl0IGVuc3VyZXMgdGhhdCB0aGUgInN0YW5kYXJkIiB0cmFuc2Zvcm1zCisjIGFyZSBhdmFpbGFibGUuIENhcmUgd2lsbCBiZSB0YWtlbiB0byBrZWVwIHRoZSBzaXplIHNtYWxsLiBIb3dldmVyLCBpZiBhIGNsaWVudCB3YW50cworIyBldmVuIG1vcmUgZ3JhbnVsYXIgY29udHJvbCBvZiBkZXBlbmRlbmNpZXMsIGl0IGNhbiBkZXBlbmQgb24gYSBuYXJyb3dlciBidWlsZCB0YXJnZXRzIGJlbG93LgorYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAidHJhbnNmb3JtcyIsCisgICAgZXhwb3J0cyA9IFsKKyAgICAgICAgIjpidWZmZXIiLAorICAgICAgICAiOmNvbXByZXNzIiwKKyAgICAgICAgIjppbnRlZ3JpdHkiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImludGVncml0eSIsCisgICAgc3JjcyA9IFsiSW50ZWdyaXR5VHJhbnNmb3JtLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uOmZyYWdtZW50IiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiYnVmZmVyIiwKKyAgICBzcmNzID0gWyJCdWZmZXJUcmFuc2Zvcm0uamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb246ZnJhZ21lbnQiLCAgIyBUT0RPKGIvMTMyODE4NzQ3KSBSZW1vdmUKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiY29tcHJlc3MiLAorICAgIHNyY3MgPSBbIkNvbXByZXNzVHJhbnNmb3JtLmphdmEiXSwKKyAgICBkZXBzID0gWyIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkiXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAicHJvdG8iLAorICAgIHNyY3MgPSBbIlRyYW5zZm9ybVByb3Rvcy5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpjaGFyc2V0cyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6bGl0ZV90cmFuc2Zvcm1fZnJhZ21lbnRzIiwKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAicHJvdG9fZnJhZ21lbnRzIiwKKyAgICBzcmNzID0gWyJUcmFuc2Zvcm1Qcm90b0ZyYWdtZW50cy5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpwcm90byIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6bGl0ZV90cmFuc2Zvcm1fZnJhZ21lbnRzIiwKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL0J1ZmZlclRyYW5zZm9ybS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvQnVmZmVyVHJhbnNmb3JtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2U4MDU3NQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL0J1ZmZlclRyYW5zZm9ybS5qYXZhCkBAIC0wLDAgKzEsNjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3JtczsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5GcmFnbWVudDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5UcmFuc2Zvcm07CitpbXBvcnQgamF2YS5pby5CdWZmZXJlZE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CisKKy8qKgorICogQnVmZmVyVHJhbnNmb3JtIHRha2VzIHdyaXRlcyBhbmQgaG9sZHMgb24gdG8gaXQgdW50aWwgZW5vdWdoIGhhcyBiZWVuIHdyaXR0ZW4gdG8ganVzdGlmeSBmbHVzaGluZworICogdG8gdGhlIGRpc2suIFJlYWRzIGFyZSBub3QgYWZmZWN0ZWQgYnkgdGhpcyB0cmFuc2Zvcm0uCisgKgorICogPHA+QSBmbHVzaCBvZiB0aGUgYnVmZmVyIGNhbiBiZSBwZXJmb3JtZWQgdXNpbmcge0BsaW5rIE91dHB1dFN0cmVhbSNmbHVzaCgpfS4KKyAqCisgKiA8cD5JdCBpcyBjb25maWd1cmVkIHVzaW5nIHRyYW5zZm9ybSBmcmFnbWVudCBpbnQgcGFyYW0ge0Bjb2RlIHNpemV9LiBGb3IgZXhhbXBsZToge0Bjb2RlCisgKiBmaWxlOi8vL3RtcC9maWxlI3RyYW5zZm9ybT1idWZmZXIoc2l6ZT0xMDI0KX0uCisgKi8KK3B1YmxpYyBjbGFzcyBCdWZmZXJUcmFuc2Zvcm0gaW1wbGVtZW50cyBUcmFuc2Zvcm0geworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0JVRkZFUl9TSVpFID0gODE5MjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFJBTlNGT1JNX05BTUUgPSAiYnVmZmVyIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNVQlBBUkFNX1NJWkUgPSAic2l6ZSI7CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgbmFtZSgpIHsKKyAgICByZXR1cm4gVFJBTlNGT1JNX05BTUU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIHdyYXBGb3JSZWFkKFVyaSB1cmksIElucHV0U3RyZWFtIHdyYXBwZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHdyYXBwZWQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIE91dHB1dFN0cmVhbSB3cmFwRm9yQXBwZW5kKFVyaSB1cmksIE91dHB1dFN0cmVhbSB3cmFwcGVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiB3cmFwRm9yV3JpdGUodXJpLCB3cmFwcGVkKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3V0cHV0U3RyZWFtIHdyYXBGb3JXcml0ZShVcmkgdXJpLCBPdXRwdXRTdHJlYW0gd3JhcHBlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgYnVmZmVyU2l6ZVN0ciA9IEZyYWdtZW50LmdldFRyYW5zZm9ybVN1YlBhcmFtKHVyaSwgbmFtZSgpLCBTVUJQQVJBTV9TSVpFKTsKKyAgICBpbnQgYnVmZmVyU2l6ZSA9IERFRkFVTFRfQlVGRkVSX1NJWkU7CisgICAgaWYgKGJ1ZmZlclNpemVTdHIgIT0gbnVsbCkgeworICAgICAgYnVmZmVyU2l6ZSA9IEludGVnZXIucGFyc2VJbnQoYnVmZmVyU2l6ZVN0cik7CisgICAgfQorICAgIHJldHVybiBuZXcgQnVmZmVyZWRPdXRwdXRTdHJlYW0od3JhcHBlZCwgYnVmZmVyU2l6ZSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL0NvbXByZXNzVHJhbnNmb3JtLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy9Db21wcmVzc1RyYW5zZm9ybS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2OTdkZDQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy9Db21wcmVzc1RyYW5zZm9ybS5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3JtczsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5UcmFuc2Zvcm07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC56aXAuRGVmbGF0ZXJPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLnppcC5JbmZsYXRlcklucHV0U3RyZWFtOworCisvKiogQSB0cmFuc2Zvcm0gdGhhdCBjb21wcmVzc2VzL2RlY29tcHJlc3NlcyB3aXRoIGphdmEudXRpbC56aXAgSW5mbGF0ZXIvRGVmbGF0ZXIuICovCitwdWJsaWMgZmluYWwgY2xhc3MgQ29tcHJlc3NUcmFuc2Zvcm0gaW1wbGVtZW50cyBUcmFuc2Zvcm0geworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0ZPUk1fTkFNRSA9ICJjb21wcmVzcyI7CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBTdHJpbmcgbmFtZSgpIHsKKyAgICByZXR1cm4gVFJBTlNGT1JNX05BTUU7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIElucHV0U3RyZWFtIHdyYXBGb3JSZWFkKFVyaSB1cmksIElucHV0U3RyZWFtIHdyYXBwZWQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ldyBJbmZsYXRlcklucHV0U3RyZWFtKHdyYXBwZWQpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBPdXRwdXRTdHJlYW0gd3JhcEZvcldyaXRlKFVyaSB1cmksIE91dHB1dFN0cmVhbSB3cmFwcGVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBuZXcgRGVmbGF0ZXJPdXRwdXRTdHJlYW0od3JhcHBlZCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL0ludGVncml0eVRyYW5zZm9ybS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvSW50ZWdyaXR5VHJhbnNmb3JtLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODNhOTIwNQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL0ludGVncml0eVRyYW5zZm9ybS5qYXZhCkBAIC0wLDAgKzEsMjA4IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXM7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC50ZXh0LlRleHRVdGlsczsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuQmFzZTY0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkZyYWdtZW50OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlBhcmFtQ29tcHV0ZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnByaW1pdGl2ZXMuSW50czsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5EaWdlc3RJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5LkRpZ2VzdE91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS5zZWN1cml0eS5Ob1N1Y2hBbGdvcml0aG1FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworCisvKioKKyAqIEEgdHJhbnNmb3JtIHRoYXQgaW1wbGVtZW50cyBpbnRlZ3JpdHkgY2hlY2sgdXNpbmcgYSBjcnlwdG9ncmFwaGljIGhhc2ggKFNIQS0yNTYpLiBUaGlzIHRyYW5zZm9ybQorICogY2FuIHdvcmsgaW4gMyBtb2RlczoKKyAqCisgKiA8b2w+CisgKiAgIDxsaT5XaGlsZSByZWFkaW5nLCB2ZXJpZnkgdGhhdCBjb250ZW50IG1hdGNoZXMgaGFzaCBwcmVzZW50IGluIFVSSS4KKyAqICAgPGxpPkNvbXB1dGUgaGFzaCBmcm9tIGV4aXN0aW5nIGZpbGUgYW5kIHJldHVybiB3aXRoIHtAbGluaworICogICAgICAgQ29tcHV0ZWRVcmlJbnB1dFN0cmVhbSNjb25zdW1lU3RyZWFtQW5kR2V0Q29tcHV0ZWRVcml9CisgKiAgIDxsaT5Db21wdXRlIGhhc2ggd2hpbGUgd3JpdGluZywgYW5kIHJldHVybiB3aXRoIHtAbGluayBDb21wdXRlZFVyaU91dHB1dFN0cmVhbSNnZXRDb21wdXRlZFVyaX0KKyAqIDwvb2w+CisgKgorICogVGhlcmUgYXJlIHZ1bG5lcmFiaWxpdGllcyBwcmVzZW50IGluIHRoaXMgZGVzaWduOgorICoKKyAqIDx1bD4KKyAqICAgPGxpPldoaWxlIHJlYWRpbmcsIHRoZSB2ZXJpZmljYXRpb24gaGFwcGVucyBvbmx5IHdoZW4gdGhlIGVuZCBvZiB0aGUgc3RyZWFtIGlzIHJlYWNoZWQuIE5vCisgKiAgICAgICBhc3N1bXB0aW9ucyBjYW4gYmUgbWFkZSBhYm91dCBpbnRlZ3JpdHkgb2YgZGF0YSB1bnRpbCB0aGVuLgorICogICA8bGk+SWYgdGhlIGhhc2ggaXMgY29tcHV0ZWQgb24gYW4gZXhpc3RpbmcgZmlsZSBzdG9yZWQgb24gaW5zZWN1cmUgbWVkaXVtLCBpdCdzIHBvc3NpYmxlIGZvcgorICogICAgICAgdGhhdCBmaWxlIHRvIGhhdmUgYWxyZWFkeSBiZWVuIG1vZGlmaWVkLCBvciB0byBiZSBtb2RpZmllZCB3aGlsZSB0aGUgaGFzaCBpcyBiZWluZworICogICAgICAgY29tcHV0ZWQuCisgKiA8L3VsPgorICoKKyAqIDxwPkNsaWVudHMgYXJlIGV4cGVjdGVkIHRvIHVzZSB0aGUgY29tcHV0ZWQgVVJJIG1ldGhvZHMgdG8gcHJvZHVjZSBhIHZhbGlkIFVSSSB3aXRoIGhhc2ggZW1iZWRkZWQKKyAqIGluIGl0LiBUaGUgbmFtZSBvZiB0aGUgZGlnZXN0IHN1YnBhcmFtIChlZywgInNoYTI1NiIpIGlzIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGhhc2ggYW5kIGhhc2hpbmcKKyAqIGFsZ29yaXRobS4gRnV0dXJlIGltcGxlbWVudGF0aW9ucyBtYXkgdXNlIGRpZmZlcmVudCBhbGdvcml0aG1zIGFuZCBzdWJwYXJhbXMsIGJ1dCBhcmUgZXhwZWN0ZWQgdG8KKyAqIHJldGFpbiBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS4KKyAqCisgKiA8cD5Db21wdXRlZCBVUklzIHRoYXQgY29udGFpbiBoYXNoZXMgbXVzdCBiZSBzdG9yZWQgaW4gYSBzYWZlIHBsYWNlIHRvIGF2b2lkIHRhbXBlcmluZy4KKyAqCisgKiA8cD5Eb2VzIG5vdCBzdXBwb3J0IGFwcGVuZGluZyB0byBhbiBleGlzdGluZyBmaWxlLgorICoKKyAqIDxwPlNlZSA8aW50ZXJuYWw+IGZvciBmdXJ0aGVyIGRvY3VtZW50YXRpb24uCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBJbnRlZ3JpdHlUcmFuc2Zvcm0gaW1wbGVtZW50cyBUcmFuc2Zvcm0geworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUUkFOU0ZPUk1fTkFNRSA9ICJpbnRlZ3JpdHkiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1VCUEFSQU1fTkFNRSA9ICJzaGEyNTYiOworCisgIC8qKiBSZXR1cm5zIHRoZSBiYXNlNjQtZW5jb2RlZCBTSEEtMjU2IGRpZ2VzdCBlbmNvZGVkIGluIHtAY29kZSB1cml9LCBvciBudWxsIGlmIG5vdCBwcmVzZW50LiAqLworICBATnVsbGFibGUKKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0RGlnZXN0SWZQcmVzZW50KFVyaSB1cmkpIHsKKyAgICByZXR1cm4gRnJhZ21lbnQuZ2V0VHJhbnNmb3JtU3ViUGFyYW0odXJpLCBUUkFOU0ZPUk1fTkFNRSwgU1VCUEFSQU1fTkFNRSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgIHJldHVybiBUUkFOU0ZPUk1fTkFNRTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIE1lc3NhZ2VEaWdlc3QgbmV3RGlnZXN0ZXIoKSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiBNZXNzYWdlRGlnZXN0LmdldEluc3RhbmNlKCJTSEEtMjU2Iik7CisgICAgfSBjYXRjaCAoTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZSk7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBJbnB1dFN0cmVhbSB3cmFwRm9yUmVhZChVcmkgdXJpLCBJbnB1dFN0cmVhbSB3cmFwcGVkKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZyYWdtZW50LlBhcmFtVmFsdWUgcGFyYW0gPSBGcmFnbWVudC5nZXRUcmFuc2Zvcm1QYXJhbVZhbHVlKHVyaSwgbmFtZSgpKTsKKyAgICByZXR1cm4gbmV3IERpZ2VzdFZlcmlmeWluZ0lucHV0U3RyZWFtKHdyYXBwZWQsIHBhcmFtKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3V0cHV0U3RyZWFtIHdyYXBGb3JXcml0ZShVcmkgdXJpLCBPdXRwdXRTdHJlYW0gd3JhcHBlZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGcmFnbWVudC5QYXJhbVZhbHVlIHBhcmFtID0gRnJhZ21lbnQuZ2V0VHJhbnNmb3JtUGFyYW1WYWx1ZSh1cmksIG5hbWUoKSk7CisgICAgcmV0dXJuIG5ldyBEaWdlc3RDb21wdXRpbmdPdXRwdXRTdHJlYW0od3JhcHBlZCwgcGFyYW0pOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgRGlnZXN0Q29tcHV0aW5nT3V0cHV0U3RyZWFtIGV4dGVuZHMgRGlnZXN0T3V0cHV0U3RyZWFtCisgICAgICBpbXBsZW1lbnRzIFBhcmFtQ29tcHV0ZXIgeworICAgIEZyYWdtZW50LlBhcmFtVmFsdWUgcGFyYW07CisgICAgUGFyYW1Db21wdXRlci5DYWxsYmFjayBwYXJhbUNvbXB1dGVyQ2FsbGJhY2s7CisgICAgYm9vbGVhbiBkaWRDb21wdXRlRGlnZXN0ID0gZmFsc2U7CisKKyAgICBEaWdlc3RDb21wdXRpbmdPdXRwdXRTdHJlYW0oT3V0cHV0U3RyZWFtIHN0cmVhbSwgRnJhZ21lbnQuUGFyYW1WYWx1ZSBwYXJhbSkgeworICAgICAgc3VwZXIoc3RyZWFtLCBuZXdEaWdlc3RlcigpKTsKKyAgICAgIHRoaXMucGFyYW0gPSBwYXJhbTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBjbG9zZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgaWYgKCFkaWRDb21wdXRlRGlnZXN0KSB7CisgICAgICAgIGRpZENvbXB1dGVEaWdlc3QgPSB0cnVlOworICAgICAgICBpZiAocGFyYW1Db21wdXRlckNhbGxiYWNrICE9IG51bGwpIHsKKyAgICAgICAgICBwYXJhbUNvbXB1dGVyQ2FsbGJhY2sub25QYXJhbVZhbHVlQ29tcHV0ZWQoCisgICAgICAgICAgICAgIHBhcmFtLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAuYWRkU3ViUGFyYW0oCisgICAgICAgICAgICAgICAgICAgICAgU1VCUEFSQU1fTkFNRSwgQmFzZTY0LmVuY29kZVRvU3RyaW5nKGRpZ2VzdC5kaWdlc3QoKSwgQmFzZTY0Lk5PX1dSQVApKQorICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgc2V0Q2FsbGJhY2soUGFyYW1Db21wdXRlci5DYWxsYmFjayBjYWxsYmFjaykgeworICAgICAgdGhpcy5wYXJhbUNvbXB1dGVyQ2FsbGJhY2sgPSBjYWxsYmFjazsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBEaWdlc3RWZXJpZnlpbmdJbnB1dFN0cmVhbSBleHRlbmRzIERpZ2VzdElucHV0U3RyZWFtCisgICAgICBpbXBsZW1lbnRzIFBhcmFtQ29tcHV0ZXIgeworICAgIGJ5dGVbXSBza2lwQnVmZmVyID0gbmV3IGJ5dGVbNDA5Nl07CisgICAgYnl0ZVtdIGV4cGVjdGVkRGlnZXN0OworICAgIGJ5dGVbXSBjb21wdXRlZERpZ2VzdDsKKyAgICBGcmFnbWVudC5QYXJhbVZhbHVlIHBhcmFtOworICAgIFBhcmFtQ29tcHV0ZXIuQ2FsbGJhY2sgcGFyYW1Db21wdXRlckNhbGxiYWNrOworCisgICAgRGlnZXN0VmVyaWZ5aW5nSW5wdXRTdHJlYW0oSW5wdXRTdHJlYW0gc3RyZWFtLCBGcmFnbWVudC5QYXJhbVZhbHVlIHBhcmFtKSB7CisgICAgICBzdXBlcihzdHJlYW0sIG5ld0RpZ2VzdGVyKCkpOworICAgICAgdGhpcy5wYXJhbSA9IHBhcmFtOworICAgICAgU3RyaW5nIGRpZ2VzdCA9IHBhcmFtLmZpbmRTdWJQYXJhbVZhbHVlKFNVQlBBUkFNX05BTUUpOworICAgICAgaWYgKCFUZXh0VXRpbHMuaXNFbXB0eShkaWdlc3QpKSB7CisgICAgICAgIHRoaXMuZXhwZWN0ZWREaWdlc3QgPSBCYXNlNjQuZGVjb2RlKGRpZ2VzdCwgQmFzZTY0Lk5PX1dSQVApOworICAgICAgfQorICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGludCByZXN1bHQgPSBzdXBlci5yZWFkKGIsIG9mZiwgbGVuKTsKKyAgICAgIGlmIChyZXN1bHQgPT0gLTEpIHsKKyAgICAgICAgY2hlY2tEaWdlc3QoKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGludCByZXN1bHQgPSBzdXBlci5yZWFkKCk7CisgICAgICBpZiAocmVzdWx0ID09IC0xKSB7CisgICAgICAgIGNoZWNrRGlnZXN0KCk7CisgICAgICB9CisgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIENsb3NlIHVuZGVybHlpbmcgc3RyZWFtIGZpcnN0IHNpbmNlIGNoZWNrRGlnZXN0IGNhbiB0aHJvdyBleGNlcHRpb24uIElmIHRoZSB1bmRlcmx5aW5nCisgICAgICAvLyBjbG9zZSBmYWlscywgT1RPSCwgZGlnZXN0IHNob3VsZCBiZSBhc3N1bWVkIHRvIGJlIGludmFsaWQuCisgICAgICBzdXBlci5jbG9zZSgpOworICAgICAgY2hlY2tEaWdlc3QoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgbG9uZyBza2lwKGxvbmcgbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIC8vIENvbnN1bWUgbWluKGJ1ZmZlci5sZW5ndGgsIG4pIGJ5dGVzLCBwcm9jZXNzaW5nIHRoZSBieXRlcyB0aGUgZW5zdXJlIHRoZSBkaWdlc3QgaXMgdXBkYXRlZC4KKyAgICAgIGludCBsZW5ndGggPSBNYXRoLm1pbihza2lwQnVmZmVyLmxlbmd0aCwgSW50cy5jaGVja2VkQ2FzdChuKSk7CisgICAgICByZXR1cm4gcmVhZChza2lwQnVmZmVyLCAwLCBsZW5ndGgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHNldENhbGxiYWNrKFBhcmFtQ29tcHV0ZXIuQ2FsbGJhY2sgY2FsbGJhY2spIHsKKyAgICAgIHRoaXMucGFyYW1Db21wdXRlckNhbGxiYWNrID0gY2FsbGJhY2s7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIGNoZWNrRGlnZXN0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGlmIChjb21wdXRlZERpZ2VzdCAhPSBudWxsKSB7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIGNvbXB1dGVkRGlnZXN0ID0gZGlnZXN0LmRpZ2VzdCgpOworICAgICAgaWYgKHBhcmFtQ29tcHV0ZXJDYWxsYmFjayAhPSBudWxsKSB7CisgICAgICAgIHBhcmFtQ29tcHV0ZXJDYWxsYmFjay5vblBhcmFtVmFsdWVDb21wdXRlZCgKKyAgICAgICAgICAgIHBhcmFtLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgLmFkZFN1YlBhcmFtKFNVQlBBUkFNX05BTUUsIEJhc2U2NC5lbmNvZGVUb1N0cmluZyhjb21wdXRlZERpZ2VzdCwgQmFzZTY0Lk5PX1dSQVApKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICAgIH0KKyAgICAgIGlmIChleHBlY3RlZERpZ2VzdCAhPSBudWxsICYmICFBcnJheXMuZXF1YWxzKGNvbXB1dGVkRGlnZXN0LCBleHBlY3RlZERpZ2VzdCkpIHsKKyAgICAgICAgU3RyaW5nIGEgPSBCYXNlNjQuZW5jb2RlVG9TdHJpbmcoY29tcHV0ZWREaWdlc3QsIEJhc2U2NC5OT19XUkFQKTsKKyAgICAgICAgU3RyaW5nIGUgPSBCYXNlNjQuZW5jb2RlVG9TdHJpbmcoZXhwZWN0ZWREaWdlc3QsIEJhc2U2NC5OT19XUkFQKTsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJNaXNtYXRjaGVkIGRpZ2VzdDogIiArIGEgKyAiIGV4cGVjdGVkOiAiICsgZSk7CisgICAgICB9CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy9UcmFuc2Zvcm1Qcm90b0ZyYWdtZW50cy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvVHJhbnNmb3JtUHJvdG9GcmFnbWVudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjc5M2Y1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvVHJhbnNmb3JtUHJvdG9GcmFnbWVudHMuamF2YQpAQCAtMCwwICsxLDQ1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXM7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuTGl0ZVRyYW5zZm9ybUZyYWdtZW50czsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuVHJhbnNmb3JtUHJvdG87CisKKy8qKiBIZWxwZXIgZm9yIFVyaSBjbGFzc2VzIHRvIGhhbmRsZSB0cmFuc2Zvcm0gZnJhZ21lbnRzIHVzaW5nIHByb3RvIHNwZWNzLiAqLworcHVibGljIGZpbmFsIGNsYXNzIFRyYW5zZm9ybVByb3RvRnJhZ21lbnRzIHsKKworICAvKiogQWRkcyB0aGlzIHNwZWMgdG8gdGhlIFVSSSwgcmVwbGFjaW5nIGV4aXN0aW5nIHNwZWMgaWYgcHJlc2VudC4gKi8KKyAgcHVibGljIHN0YXRpYyBVcmkgYWRkT3JSZXBsYWNlVHJhbnNmb3JtKFVyaSB1cmksIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybSBzcGVjKSB7CisgICAgSW1tdXRhYmxlTGlzdC5CdWlsZGVyPFN0cmluZz4gcmVzdWx0ID0gSW1tdXRhYmxlTGlzdC5idWlsZGVyKCk7CisgICAgSW1tdXRhYmxlTGlzdDxTdHJpbmc+IG9sZFNwZWNzID0gTGl0ZVRyYW5zZm9ybUZyYWdtZW50cy5wYXJzZVRyYW5zZm9ybVNwZWNzKHVyaSk7CisgICAgU3RyaW5nIG5ld1NwZWMgPSBUcmFuc2Zvcm1Qcm90b3MudG9FbmNvZGVkU3BlYyhzcGVjKTsKKyAgICBTdHJpbmcgbmV3U3BlY05hbWUgPSBMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLnBhcnNlU3BlY05hbWUobmV3U3BlYyk7CisgICAgZm9yIChTdHJpbmcgb2xkU3BlYyA6IG9sZFNwZWNzKSB7CisgICAgICBTdHJpbmcgb2xkU3BlY05hbWUgPSBMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLnBhcnNlU3BlY05hbWUob2xkU3BlYyk7CisgICAgICBpZiAoIW9sZFNwZWNOYW1lLmVxdWFscyhuZXdTcGVjTmFtZSkpIHsKKyAgICAgICAgcmVzdWx0LmFkZChvbGRTcGVjKTsKKyAgICAgIH0KKyAgICB9CisgICAgcmVzdWx0LmFkZChuZXdTcGVjKTsKKyAgICByZXR1cm4gdXJpLmJ1aWxkVXBvbigpCisgICAgICAgIC5lbmNvZGVkRnJhZ21lbnQoTGl0ZVRyYW5zZm9ybUZyYWdtZW50cy5qb2luVHJhbnNmb3JtU3BlY3MocmVzdWx0LmJ1aWxkKCkpKQorICAgICAgICAuYnVpbGQoKTsKKyAgfQorCisgIHByaXZhdGUgVHJhbnNmb3JtUHJvdG9GcmFnbWVudHMoKSB7fQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvVHJhbnNmb3JtUHJvdG9zLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy9UcmFuc2Zvcm1Qcm90b3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ODFmZWMxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvVHJhbnNmb3JtUHJvdG9zLmphdmEKQEAgLTAsMCArMSwxNTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3JtczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbC5DaGFyc2V0cy5VVEZfODsKKworaW1wb3J0IGFuZHJvaWQudXRpbC5CYXNlNjQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWwuTGl0ZVRyYW5zZm9ybUZyYWdtZW50czsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLkpvaW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlByZWNvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLlRyYW5zZm9ybVByb3RvOworaW1wb3J0IGphdmEuaW8uVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5ldC5VUkxFbmNvZGVyOworCisvKiogVXRpbGl0eSB0byBjb252ZXJ0IFRyYW5zZm9ybSBwcm90byBpbnRvIFVSSSBmcmFnbWVudC4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBUcmFuc2Zvcm1Qcm90b3MgeworCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtIERFRkFVTFRfQ09NUFJFU1NfU1BFQyA9CisgICAgICBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm0ubmV3QnVpbGRlcigpCisgICAgICAgICAgLnNldENvbXByZXNzKFRyYW5zZm9ybVByb3RvLkNvbXByZXNzVHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgIC5idWlsZCgpOworCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtIERFRkFVTFRfRU5DUllQVF9TUEVDID0KKyAgICAgIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAuc2V0RW5jcnlwdChUcmFuc2Zvcm1Qcm90by5FbmNyeXB0VHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgIC5idWlsZCgpOworCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtIERFRkFVTFRfSU5URUdSSVRZX1NQRUMgPQorICAgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtLm5ld0J1aWxkZXIoKQorICAgICAgICAgIC5zZXRJbnRlZ3JpdHkoVHJhbnNmb3JtUHJvdG8uSW50ZWdyaXR5VHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgIC5idWlsZCgpOworCisgIHB1YmxpYyBzdGF0aWMgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtIGVuY3J5cHRUcmFuc2Zvcm1TcGVjV2l0aEtleShieXRlW10ga2V5KSB7CisgICAgcmV0dXJuIGVuY3J5cHRUcmFuc2Zvcm1TcGVjV2l0aEJhc2U2NEtleShCYXNlNjQuZW5jb2RlVG9TdHJpbmcoa2V5LCBCYXNlNjQuTk9fV1JBUCkpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm0gZW5jcnlwdFRyYW5zZm9ybVNwZWNXaXRoQmFzZTY0S2V5KFN0cmluZyBiYXNlNjRLZXkpIHsKKyAgICByZXR1cm4gVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0RW5jcnlwdChUcmFuc2Zvcm1Qcm90by5FbmNyeXB0VHJhbnNmb3JtLm5ld0J1aWxkZXIoKS5zZXRBZXNHY21LZXlCYXNlNjQoYmFzZTY0S2V5KSkKKyAgICAgICAgLmJ1aWxkKCk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybSBpbnRlZ3JpdHlUcmFuc2Zvcm1TcGVjV2l0aFNoYTI1NihTdHJpbmcgc2hhMjU2KSB7CisgICAgcmV0dXJuIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEludGVncml0eShUcmFuc2Zvcm1Qcm90by5JbnRlZ3JpdHlUcmFuc2Zvcm0ubmV3QnVpbGRlcigpLnNldFNoYTI1NihzaGEyNTYpKQorICAgICAgICAuYnVpbGQoKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtIHppcFRyYW5zZm9ybVNwZWNXaXRoVGFyZ2V0KFN0cmluZyB0YXJnZXQpIHsKKyAgICByZXR1cm4gVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0WmlwKFRyYW5zZm9ybVByb3RvLlppcFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkuc2V0VGFyZ2V0KHRhcmdldCkpCisgICAgICAgIC5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIFRyYW5zbGF0ZSBmcm9tIHByb3RvIHJlcHJlc2VudGF0aW9uIHRvIGFuIGVuY29kZWQgZnJhZ21lbnQsIHdoaWNoIGlzIHN1aXRhYmxlIGZvciBhcHBlbmRpbmcgdG8KKyAgICogYSBVUkkuCisgICAqCisgICAqIDxwPlRvIGJ1aWxkIGFuIHtAbGluayBhbmRyb2lkLm5ldC5Vcml9IHdpdGggc3VjaCBhIGZyYWdtZW50OiA8Y29kZT4KKyAgICogRnJhZ21lbnQgZnJhZ21lbnQgPSBUcmFuc2Zvcm1Qcm90b3MudG9FbmNvZGVkRnJhZ21lbnQodHJhbnNmb3JtUHJvdG8pOworICAgKiBVcmkgdXJpID0gb3JpZ1VyaS5idWlsZFVwb24oKS5lbmNvZGVkRnJhZ21lbnQoZnJhZ21lbnQudG9TdHJpbmcoKSkuYnVpbGQoKTsKKyAgICogPC9jb2RlPgorICAgKgorICAgKiBAcGFyYW0gdHJhbnNmb3Jtc1Byb3RvIFRoZSBwcm90byB0byB0cmFuc2xhdGUgdG8gYSBmcmFnbWVudC4KKyAgICogQHJldHVybiBUaGUgZW5jb2RlZCBmcmFnbWVudCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcHJvdG8uCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b0VuY29kZWRGcmFnbWVudChUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm1zIHRyYW5zZm9ybXNQcm90bykgeworICAgIEltbXV0YWJsZUxpc3QuQnVpbGRlcjxTdHJpbmc+IGVuY29kZWRTcGVjcyA9IEltbXV0YWJsZUxpc3QuYnVpbGRlcigpOworICAgIGZvciAoVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtIHRyYW5zZm9ybVByb3RvIDogdHJhbnNmb3Jtc1Byb3RvLmdldFRyYW5zZm9ybUxpc3QoKSkgeworICAgICAgZW5jb2RlZFNwZWNzLmFkZCh0b0VuY29kZWRTcGVjKHRyYW5zZm9ybVByb3RvKSk7CisgICAgfQorICAgIHJldHVybiBMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLmpvaW5UcmFuc2Zvcm1TcGVjcyhlbmNvZGVkU3BlY3MuYnVpbGQoKSk7CisgIH0KKworICAvKioKKyAgICogVHJhbnNsYXRlIHByb3RvIHJlcHJlc2VudGF0aW9uIHRvIGFuIGVuY29kZWQgdHJhbnNmb3JtIHNwZWMuCisgICAqCisgICAqIEBwYXJhbSB0cmFuc2Zvcm1Qcm90byBUaGUgcHJvdG8gdG8gdHJhbnNsYXRlIHRvIGEgc3BlYy4KKyAgICogQHJldHVybiBBbiBlbmNvZGVkIHNwZWMgc3VpdGFibGUgZm9yIGpvaW5pbmcgd2l0aCBvdGhlciBzcGVjcyB0byBmb3JtIGZyYWdtZW50LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9FbmNvZGVkU3BlYyhUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm0gdHJhbnNmb3JtUHJvdG8pIHsKKyAgICBTdHJpbmcgZW5jb2RlZFNwZWM7CisgICAgc3dpdGNoICh0cmFuc2Zvcm1Qcm90by5nZXRUcmFuc2Zvcm1DYXNlKCkpIHsKKyAgICAgIGNhc2UgQ09NUFJFU1M6CisgICAgICAgIGVuY29kZWRTcGVjID0gImNvbXByZXNzIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEVOQ1JZUFQ6CisgICAgICAgIFRyYW5zZm9ybVByb3RvLkVuY3J5cHRUcmFuc2Zvcm0gZW5jcnlwdCA9IHRyYW5zZm9ybVByb3RvLmdldEVuY3J5cHQoKTsKKyAgICAgICAgaWYgKGVuY3J5cHQuaGFzQWVzR2NtS2V5QmFzZTY0KCkpIHsKKyAgICAgICAgICBlbmNvZGVkU3BlYyA9ICJlbmNyeXB0KGFlc19nY21fa2V5PSIgKyB1cmxFbmNvZGUoZW5jcnlwdC5nZXRBZXNHY21LZXlCYXNlNjQoKSkgKyAiKSI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZW5jb2RlZFNwZWMgPSAiZW5jcnlwdCI7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIElOVEVHUklUWToKKyAgICAgICAgVHJhbnNmb3JtUHJvdG8uSW50ZWdyaXR5VHJhbnNmb3JtIGludGVncml0eSA9IHRyYW5zZm9ybVByb3RvLmdldEludGVncml0eSgpOworICAgICAgICBpZiAoaW50ZWdyaXR5Lmhhc1NoYTI1NigpKSB7CisgICAgICAgICAgZW5jb2RlZFNwZWMgPSAiaW50ZWdyaXR5KHNoYTI1Nj0iICsgdXJsRW5jb2RlKGludGVncml0eS5nZXRTaGEyNTYoKSkgKyAiKSI7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgZW5jb2RlZFNwZWMgPSAiaW50ZWdyaXR5IjsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgWklQOgorICAgICAgICBUcmFuc2Zvcm1Qcm90by5aaXBUcmFuc2Zvcm0gemlwID0gdHJhbnNmb3JtUHJvdG8uZ2V0WmlwKCk7CisgICAgICAgIFByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudCh6aXAuaGFzVGFyZ2V0KCkpOworICAgICAgICBlbmNvZGVkU3BlYyA9ICJ6aXAodGFyZ2V0PSIgKyB1cmxFbmNvZGUoemlwLmdldFRhcmdldCgpKSArICIpIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIENVU1RPTToKKyAgICAgICAgVHJhbnNmb3JtUHJvdG8uQ3VzdG9tVHJhbnNmb3JtIGN1c3RvbSA9IHRyYW5zZm9ybVByb3RvLmdldEN1c3RvbSgpOworICAgICAgICBTdHJpbmcgcGFyYW1zID0gIiI7CisgICAgICAgIGlmIChjdXN0b20uZ2V0U3VicGFyYW1Db3VudCgpID4gMCkgeworICAgICAgICAgIEltbXV0YWJsZUxpc3QuQnVpbGRlcjxTdHJpbmc+IHN1YnBhcmFtcyA9IEltbXV0YWJsZUxpc3QuYnVpbGRlcigpOworICAgICAgICAgIGZvciAoVHJhbnNmb3JtUHJvdG8uQ3VzdG9tVHJhbnNmb3JtLlN1YlBhcmFtIHN1YnBhcmFtIDogY3VzdG9tLmdldFN1YnBhcmFtTGlzdCgpKSB7CisgICAgICAgICAgICBQcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoc3VicGFyYW0uaGFzS2V5KCkpOworICAgICAgICAgICAgaWYgKHN1YnBhcmFtLmhhc1ZhbHVlKCkpIHsKKyAgICAgICAgICAgICAgc3VicGFyYW1zLmFkZChzdWJwYXJhbS5nZXRLZXkoKSArICI9IiArIHVybEVuY29kZShzdWJwYXJhbS5nZXRWYWx1ZSgpKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBzdWJwYXJhbXMuYWRkKHN1YnBhcmFtLmdldEtleSgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgcGFyYW1zID0gIigiICsgSm9pbmVyLm9uKCIsIikuam9pbihzdWJwYXJhbXMuYnVpbGQoKSkgKyAiKSI7CisgICAgICAgIH0KKyAgICAgICAgZW5jb2RlZFNwZWMgPSBjdXN0b20uZ2V0TmFtZSgpICsgcGFyYW1zOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk5vIHRyYW5zZm9ybSBzcGVjaWZpZWQiKTsKKyAgICB9CisgICAgcmV0dXJuIGVuY29kZWRTcGVjOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIHVybEVuY29kZShTdHJpbmcgc3RyKSB7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiBVUkxFbmNvZGVyLmVuY29kZShzdHIsIFVURl84LmRpc3BsYXlOYW1lKCkpOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihlKTsgLy8gRXhwZWN0cyBVVEY4IHRvIGJlIGF2YWlsYWJsZS4KKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZm9yZWdyb3VuZC9BbmRyb2lkTWFuaWZlc3QueG1sIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9mb3JlZ3JvdW5kL0FuZHJvaWRNYW5pZmVzdC54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWRjZDQxMAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZm9yZWdyb3VuZC9BbmRyb2lkTWFuaWZlc3QueG1sCkBAIC0wLDAgKzEsMjUgQEAKKzwhLS0KKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCistLT4KKzxtYW5pZmVzdAorICAgIHhtbG5zOmFuZHJvaWQ9Imh0dHA6Ly9zY2hlbWFzLmFuZHJvaWQuY29tL2Fway9yZXMvYW5kcm9pZCIKKyAgICBwYWNrYWdlPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5mb3JlZ3JvdW5kIj4KKworICA8dXNlcy1zZGsgYW5kcm9pZDptaW5TZGtWZXJzaW9uPSIxNiIvPgorCisgIDxhcHBsaWNhdGlvbiAvPgorPC9tYW5pZmVzdD4KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZm9yZWdyb3VuZC9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZm9yZWdyb3VuZC9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOThjNjIzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9mb3JlZ3JvdW5kL0JVSUxECkBAIC0wLDAgKzEsNDQgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsKKyAgICAgICAgIi8vdmlzaWJpbGl0eTpwdWJsaWMiLAorICAgIF0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCitmaWxlZ3JvdXAoCisgICAgbmFtZSA9ICJyZXNvdXJjZV9maWxlcyIsCisgICAgc3JjcyA9IGdsb2IoWworICAgICAgICAicmVzLyoqIiwKKyAgICBdKSwKKykKKworIyBUaGlzIGluY2x1ZGVzIGFsbCB0cmFuc2xhdGVkIHN0cmluZ3MgZm9yIE1ERCBOb3RpZmljYXRpb25zLiBBcHBzIGNhbiBjaG9vc2UgdG8gaW5jbHVkZSBzdWJzZXQgb2YgdGhlCisjIHN1cHBvcnRlZCBsb2NhbGUgcmVzb3VyY2VzIGluIHRoZWlyIGJpbmFyeSB1c2luZyB0aGUgYHJlc291cmNlX2NvbmZpZ3VyYXRpb25fZmlsdGVyc2Agb3B0aW9uIGluCisjIHRoZWlyIGFuZHJvaWRfYmluYXJ5IHJ1bGUuIEZvciBtb3JlIGluZm8sIHNlZTogPGludGVybmFsPgorYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiTm90aWZpY2F0aW9uVXRpbCIsCisgICAgc3JjcyA9IFsiTm90aWZpY2F0aW9uVXRpbC5qYXZhIl0sCisgICAgbWFuaWZlc3QgPSAiQW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgcmVzb3VyY2VfZmlsZXMgPSBnbG9iKFsicmVzLyoqIl0pLAorICAgIGRlcHMgPSBbCisgICAgICAgICJAYW5kcm9pZHhfYW5ub3RhdGlvbl9hbm5vdGF0aW9uIiwKKyAgICAgICAgIkBhbmRyb2lkeF9jb3JlX2NvcmUiLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZvcmVncm91bmQvTm90aWZpY2F0aW9uVXRpbC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9mb3JlZ3JvdW5kL05vdGlmaWNhdGlvblV0aWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YmE5YTkwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9mb3JlZ3JvdW5kL05vdGlmaWNhdGlvblV0aWwuamF2YQpAQCAtMCwwICsxLDE5OSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZm9yZWdyb3VuZDsKKworaW1wb3J0IGFuZHJvaWQuYW5ub3RhdGlvbi5TdXBwcmVzc0xpbnQ7CitpbXBvcnQgYW5kcm9pZC5hcHAuTm90aWZpY2F0aW9uQ2hhbm5lbDsKK2ltcG9ydCBhbmRyb2lkLmFwcC5QZW5kaW5nSW50ZW50OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5JbnRlbnQ7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZC5WRVJTSU9OOworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQuVkVSU0lPTl9DT0RFUzsKK2ltcG9ydCBhbmRyb2lkeC5hbm5vdGF0aW9uLlJlcXVpcmVzQXBpOworaW1wb3J0IGFuZHJvaWR4LmNvcmUuYXBwLk5vdGlmaWNhdGlvbkNvbXBhdDsKK2ltcG9ydCBhbmRyb2lkeC5jb3JlLmFwcC5Ob3RpZmljYXRpb25Db21wYXQuQmlnVGV4dFN0eWxlOworaW1wb3J0IGFuZHJvaWR4LmNvcmUuYXBwLk5vdGlmaWNhdGlvbk1hbmFnZXJDb21wYXQ7CitpbXBvcnQgYW5kcm9pZHguY29yZS5jb250ZW50LkNvbnRleHRDb21wYXQ7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5QcmVjb25kaXRpb25zOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKiBVdGlsaXRpZXMgZm9yIGNyZWF0aW5nIGFuZCBtYW5hZ2luZyBub3RpZmljYXRpb25zLiAqLworLy8gVE9ETyhiLzE0ODQwMTAxNik6IEFkZCBVSSB0ZXN0IGZvciBOb3RpZmljYXRpb25VdGlsLgorcHVibGljIGZpbmFsIGNsYXNzIE5vdGlmaWNhdGlvblV0aWwgeworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDQU5DRUxfQUNUSU9OX0VYVFJBID0gImNhbmNlbC1hY3Rpb24iOworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBLRVlfRVhUUkEgPSAia2V5IjsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RPUF9TRVJWSUNFX0VYVFJBID0gInN0b3Atc2VydmljZSI7CisKKyAgcHJpdmF0ZSBOb3RpZmljYXRpb25VdGlsKCkge30KKworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOT1RJRklDQVRJT05fQ0hBTk5FTF9JRCA9ICJkb3dubG9hZC1ub3RpZmljYXRpb24tY2hhbm5lbC1pZCI7CisKKyAgLyoqIENyZWF0ZSB0aGUgTm90aWZpY2F0aW9uQnVpbGRlciBmb3IgdGhlIEZvcmVncm91bmQgRG93bmxvYWQgU2VydmljZSAqLworICBwdWJsaWMgc3RhdGljIE5vdGlmaWNhdGlvbkNvbXBhdC5CdWlsZGVyIGNyZWF0ZUZvcmVncm91bmRTZXJ2aWNlTm90aWZpY2F0aW9uQnVpbGRlcigKKyAgICAgIENvbnRleHQgY29udGV4dCkgeworICAgIHJldHVybiBnZXROb3RpZmljYXRpb25CdWlsZGVyKGNvbnRleHQpCisgICAgICAgIC5zZXRDb250ZW50VGl0bGUoCisgICAgICAgICAgICAgICAgIkRvd25sb2FkaW5nIikKKyAgICAgICAgLnNldFNtYWxsSWNvbihhbmRyb2lkLlIuZHJhd2FibGUuc3RhdF9ub3RpZnlfc3luY19ub2FuaW0pOworICB9CisKKyAgLyoqIENyZWF0ZSBhIE5vdGlmaWNhdGlvbi5CdWlsZGVyLiAqLworICBwdWJsaWMgc3RhdGljIE5vdGlmaWNhdGlvbkNvbXBhdC5CdWlsZGVyIGNyZWF0ZU5vdGlmaWNhdGlvbkJ1aWxkZXIoCisgICAgICBDb250ZXh0IGNvbnRleHQsIGludCBzaXplLCBTdHJpbmcgY29udGVudFRpdGxlLCBTdHJpbmcgY29udGVudFRleHQpIHsKKyAgICByZXR1cm4gZ2V0Tm90aWZpY2F0aW9uQnVpbGRlcihjb250ZXh0KQorICAgICAgICAuc2V0Q29udGVudFRpdGxlKGNvbnRlbnRUaXRsZSkKKyAgICAgICAgLnNldENvbnRlbnRUZXh0KGNvbnRlbnRUZXh0KQorICAgICAgICAuc2V0U21hbGxJY29uKGFuZHJvaWQuUi5kcmF3YWJsZS5zdGF0X3N5c19kb3dubG9hZCkKKyAgICAgICAgLnNldE9uZ29pbmcodHJ1ZSkKKyAgICAgICAgLnNldFByb2dyZXNzKHNpemUsIDAsIGZhbHNlKQorICAgICAgICAuc2V0U3R5bGUobmV3IEJpZ1RleHRTdHlsZSgpLmJpZ1RleHQoY29udGVudFRleHQpKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIE5vdGlmaWNhdGlvbkNvbXBhdC5CdWlsZGVyIGdldE5vdGlmaWNhdGlvbkJ1aWxkZXIoQ29udGV4dCBjb250ZXh0KSB7CisgICAgcmV0dXJuIG5ldyBOb3RpZmljYXRpb25Db21wYXQuQnVpbGRlcihjb250ZXh0LCBOT1RJRklDQVRJT05fQ0hBTk5FTF9JRCkKKyAgICAgICAgLnNldENhdGVnb3J5KE5vdGlmaWNhdGlvbkNvbXBhdC5DQVRFR09SWV9TRVJWSUNFKQorICAgICAgICAuc2V0T25seUFsZXJ0T25jZSh0cnVlKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBOb3RpZmljYXRpb24gZm9yIGEga2V5LgorICAgKgorICAgKiBAcGFyYW0ga2V5IEtleSB0byBpZGVudGlmeSB0aGUgZG93bmxvYWQgdGhpcyBub3RpZmljYXRpb24gaXMgY3JlYXRlZCBmb3IuCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgY2FuY2VsTm90aWZpY2F0aW9uRm9yS2V5KENvbnRleHQgY29udGV4dCwgU3RyaW5nIGtleSkgeworICAgIE5vdGlmaWNhdGlvbk1hbmFnZXJDb21wYXQgbm90aWZpY2F0aW9uTWFuYWdlciA9IE5vdGlmaWNhdGlvbk1hbmFnZXJDb21wYXQuZnJvbShjb250ZXh0KTsKKyAgICBub3RpZmljYXRpb25NYW5hZ2VyLmNhbmNlbChub3RpZmljYXRpb25LZXlGb3JLZXkoa2V5KSk7CisgIH0KKworICAvKiogQ3JlYXRlIHRoZSBDYW5jZWwgTWVudSBBY3Rpb24gd2hpY2ggd2lsbCBiZSBhdHRhY2ggdG8gdGhlIGRvd25sb2FkIG5vdGlmaWNhdGlvbi4gKi8KKyAgLy8gRkxBR19JTU1VVEFCTEUgaXMgb25seSBmb3IgYXBpID49IDIzLCBob3dldmVyIGZyYW1ld29yayBzdGlsbCByZWNvbW1lbmRzIHRvIHVzZSB0aGlzOgorICAvLyA8aW50ZXJuYWw+CisgIEBTdXBwcmVzc0xpbnQoIklubGluZWRBcGkiKQorICBwdWJsaWMgc3RhdGljIHZvaWQgY3JlYXRlQ2FuY2VsQWN0aW9uKAorICAgICAgQ29udGV4dCBjb250ZXh0LAorICAgICAgQ2xhc3M8Pz4gZm9yZWdyb3VuZERvd25sb2FkU2VydmljZUNsYXNzLAorICAgICAgU3RyaW5nIGtleSwKKyAgICAgIE5vdGlmaWNhdGlvbkNvbXBhdC5CdWlsZGVyIG5vdGlmaWNhdGlvbiwKKyAgICAgIGludCBub3RpZmljYXRpb25LZXkpIHsKKyAgICBTYWZlckludGVudFV0aWxzIGludGVudFV0aWxzID0gbmV3IFNhZmVySW50ZW50VXRpbHMoKSB7fTsKKworICAgIEludGVudCBjYW5jZWxJbnRlbnQgPSBuZXcgSW50ZW50KGNvbnRleHQsIGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzcyk7CisgICAgY2FuY2VsSW50ZW50LnNldFBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBjYW5jZWxJbnRlbnQucHV0RXh0cmEoQ0FOQ0VMX0FDVElPTl9FWFRSQSwgbm90aWZpY2F0aW9uS2V5KTsKKyAgICBjYW5jZWxJbnRlbnQucHV0RXh0cmEoS0VZX0VYVFJBLCBrZXkpOworCisgICAgLy8gSXQgc2hvdWxkIGJlIHNhZmUgc2luY2Ugd2UgYXJlIHVzaW5nIFNhZmVyUGVuZGluZ0ludGVudCwgc2V0dGluZyBQYWNrYWdlIGFuZCBDb21wb25lbnQsIGFuZAorICAgIC8vIHVzZSBQZW5kaW5nSW50ZW50LkZMQUdfT05FX1NIT1QgfCBQZW5kaW5nSW50ZW50LkZMQUdfSU1NVVRBQkxFLgorICAgIFBlbmRpbmdJbnRlbnQgcGVuZGluZ0NhbmNlbEludGVudDsKKyAgICBpZiAoVkVSU0lPTi5TREtfSU5UID49IFZFUlNJT05fQ09ERVMuTykgeworICAgICAgcGVuZGluZ0NhbmNlbEludGVudCA9CisgICAgICAgICAgaW50ZW50VXRpbHMuZ2V0Rm9yZWdyb3VuZFNlcnZpY2UoCisgICAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbktleSwKKyAgICAgICAgICAgICAgY2FuY2VsSW50ZW50LAorICAgICAgICAgICAgICBQZW5kaW5nSW50ZW50LkZMQUdfT05FX1NIT1QgfCBQZW5kaW5nSW50ZW50LkZMQUdfSU1NVVRBQkxFKTsKKyAgICB9IGVsc2UgeworICAgICAgcGVuZGluZ0NhbmNlbEludGVudCA9CisgICAgICAgICAgaW50ZW50VXRpbHMuZ2V0U2VydmljZSgKKyAgICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgICAgbm90aWZpY2F0aW9uS2V5LAorICAgICAgICAgICAgICBjYW5jZWxJbnRlbnQsCisgICAgICAgICAgICAgIFBlbmRpbmdJbnRlbnQuRkxBR19PTkVfU0hPVCB8IFBlbmRpbmdJbnRlbnQuRkxBR19JTU1VVEFCTEUpOworICAgIH0KKyAgICBOb3RpZmljYXRpb25Db21wYXQuQWN0aW9uIGFjdGlvbiA9CisgICAgICAgIG5ldyBOb3RpZmljYXRpb25Db21wYXQuQWN0aW9uLkJ1aWxkZXIoCisgICAgICAgICAgICAgICAgYW5kcm9pZC5SLmRyYXdhYmxlLnN0YXRfc3lzX3dhcm5pbmcsCisgICAgICAgICAgICAgICAgIkNhbmNlbCIsCisgICAgICAgICAgICAgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocGVuZGluZ0NhbmNlbEludGVudCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBub3RpZmljYXRpb24uYWRkQWN0aW9uKGFjdGlvbik7CisgIH0KKworICAvKiogR2VuZXJhdGUgdGhlIE5vdGlmaWNhdGlvbiBLZXkgZm9yIHRoZSBLZXkgKi8KKyAgcHVibGljIHN0YXRpYyBpbnQgbm90aWZpY2F0aW9uS2V5Rm9yS2V5KFN0cmluZyBrZXkpIHsKKyAgICAvLyBDb25zaWRlciBpZiB3ZSBjb3VsZCBoYXZlIGNvbGxpc2lvbi4KKyAgICAvLyBIZWF2aWVyIGFsdGVybmF0aXZlIGlzIEhhc2hpbmcuZ29vZEZhc3RIYXNoKDMyKS5oYXNoVW5lbmNvZGVkQ2hhcnMoa2V5KS5hc0ludCgpOworICAgIHJldHVybiBrZXkuaGFzaENvZGUoKTsKKyAgfQorCisgIC8qKiBTZW5kIGludGVudCB0byBzdGFydCB0aGUgRG93bmxvYWRTZXJ2aWNlIGluIGZvcmVncm91bmQuICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBzdGFydEZvcmVncm91bmREb3dubG9hZFNlcnZpY2UoCisgICAgICBDb250ZXh0IGNvbnRleHQsIENsYXNzPD8+IGZvcmVncm91bmREb3dubG9hZFNlcnZpY2UsIFN0cmluZyBrZXkpIHsKKyAgICBJbnRlbnQgaW50ZW50ID0gbmV3IEludGVudChjb250ZXh0LCBmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlKTsKKyAgICBpbnRlbnQucHV0RXh0cmEoS0VZX0VYVFJBLCBrZXkpOworCisgICAgLy8gU3RhcnQgRm9yZWdyb3VuZERvd25sb2FkU2VydmljZSB0byBkb3dubG9hZCBpbiB0aGUgZm9yZWdyb3VuZC4KKyAgICBDb250ZXh0Q29tcGF0LnN0YXJ0Rm9yZWdyb3VuZFNlcnZpY2UoY29udGV4dCwgaW50ZW50KTsKKyAgfQorCisgIC8qKiBTZW5kaW5nIHRoZSBpbnRlbnQgdG8gc3RvcCB0aGUgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBzdG9wRm9yZWdyb3VuZERvd25sb2FkU2VydmljZSgKKyAgICAgIENvbnRleHQgY29udGV4dCwgQ2xhc3M8Pz4gZm9yZWdyb3VuZERvd25sb2FkU2VydmljZSkgeworICAgIEludGVudCBpbnRlbnQgPSBuZXcgSW50ZW50KGNvbnRleHQsIGZvcmVncm91bmREb3dubG9hZFNlcnZpY2UpOworICAgIGludGVudC5wdXRFeHRyYShTVE9QX1NFUlZJQ0VfRVhUUkEsIHRydWUpOworCisgICAgLy8gVGhpcyB3aWxsIHNlbmQgdGhlIGludGVudCB0byBzdG9wIHRoZSBzZXJ2aWNlLgorICAgIENvbnRleHRDb21wYXQuc3RhcnRGb3JlZ3JvdW5kU2VydmljZShjb250ZXh0LCBpbnRlbnQpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybiB0aGUgU3RyaW5nIG1lc3NhZ2UgdG8gZGlzcGxheSBpbiBOb3RpZmljYXRpb24gd2hlbiB0aGUgZG93bmxvYWQgaXMgcGF1c2VkIHRvIHdhaXQgZm9yCisgICAqIG5ldHdvcmsgY29ubmVjdGlvbi4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldERvd25sb2FkUGF1c2VkTWVzc2FnZShDb250ZXh0IGNvbnRleHQpIHsKKyAgICByZXR1cm4gIldhaXRpbmcgZm9yIG5ldHdvcmsgY29ubmVjdGlvbiI7CisgIH0KKworICAvKiogUmV0dXJuIHRoZSBTdHJpbmcgbWVzc2FnZSB0byBkaXNwbGF5IGluIE5vdGlmaWNhdGlvbiB3aGVuIHRoZSBkb3dubG9hZCBpcyBmYWlsZWQuICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldERvd25sb2FkRmFpbGVkTWVzc2FnZShDb250ZXh0IGNvbnRleHQpIHsKKyAgICByZXR1cm4gIkRvd25sb2FkIGZhaWxlZCI7CisgIH0KKworICAvKiogUmV0dXJuIHRoZSBTdHJpbmcgbWVzc2FnZSB0byBkaXNwbGF5IGluIE5vdGlmaWNhdGlvbiB3aGVuIHRoZSBkb3dubG9hZCBpcyBzdWNjZXNzLiAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXREb3dubG9hZFN1Y2Nlc3NNZXNzYWdlKENvbnRleHQgY29udGV4dCkgeworICAgIHJldHVybiAiRG93bmxvYWRlZCI7CisgIH0KKworICAvKiogQ3JlYXRlIHRoZSBOb3RpZmljYXRpb24gQ2hhbm5lbCBmb3IgRG93bmxvYWRpbmcuICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBjcmVhdGVOb3RpZmljYXRpb25DaGFubmVsKENvbnRleHQgY29udGV4dCkgeworICAgIGlmIChWRVJTSU9OLlNES19JTlQgPj0gVkVSU0lPTl9DT0RFUy5PKSB7CisgICAgICBOb3RpZmljYXRpb25DaGFubmVsIG5vdGlmaWNhdGlvbkNoYW5uZWwgPQorICAgICAgICAgIG5ldyBOb3RpZmljYXRpb25DaGFubmVsKAorICAgICAgICAgICAgICBOT1RJRklDQVRJT05fQ0hBTk5FTF9JRCwKKyAgICAgICAgICAgICAgICAgICJEYXRhIERvd25sb2FkIE5vdGlmaWNhdGlvbiBDaGFubmVsIiwKKyAgICAgICAgICAgICAgYW5kcm9pZC5hcHAuTm90aWZpY2F0aW9uTWFuYWdlci5JTVBPUlRBTkNFX0RFRkFVTFQpOworCisgICAgICBhbmRyb2lkLmFwcC5Ob3RpZmljYXRpb25NYW5hZ2VyIG1hbmFnZXIgPQorICAgICAgICAgIGNvbnRleHQuZ2V0U3lzdGVtU2VydmljZShhbmRyb2lkLmFwcC5Ob3RpZmljYXRpb25NYW5hZ2VyLmNsYXNzKTsKKyAgICAgIG1hbmFnZXIuY3JlYXRlTm90aWZpY2F0aW9uQ2hhbm5lbChub3RpZmljYXRpb25DaGFubmVsKTsKKyAgICB9CisgIH0KKworICAvKiogVXRpbGl0aWVzIGZvciBzYWZlbHkgYWNjZXNzaW5nIFBlbmRpbmdJbnRlbnQgQVBJcy4gKi8KKyAgcHJpdmF0ZSBpbnRlcmZhY2UgU2FmZXJJbnRlbnRVdGlscyB7CisgICAgQE51bGxhYmxlCisgICAgQFJlcXVpcmVzQXBpKFZFUlNJT05fQ09ERVMuTykgLy8gdG8gbWF0Y2ggUGVuZGluZ0ludGVudC5nZXRGb3JlZ3JvdW5kU2VydmljZSgpCisgICAgZGVmYXVsdCBQZW5kaW5nSW50ZW50IGdldEZvcmVncm91bmRTZXJ2aWNlKAorICAgICAgICBDb250ZXh0IGNvbnRleHQsIGludCByZXF1ZXN0Q29kZSwgSW50ZW50IGludGVudCwgaW50IGZsYWdzKSB7CisgICAgICByZXR1cm4gUGVuZGluZ0ludGVudC5nZXRGb3JlZ3JvdW5kU2VydmljZShjb250ZXh0LCByZXF1ZXN0Q29kZSwgaW50ZW50LCBmbGFncyk7CisgICAgfQorCisgICAgQE51bGxhYmxlCisgICAgZGVmYXVsdCBQZW5kaW5nSW50ZW50IGdldFNlcnZpY2UoQ29udGV4dCBjb250ZXh0LCBpbnQgcmVxdWVzdENvZGUsIEludGVudCBpbnRlbnQsIGludCBmbGFncykgeworICAgICAgcmV0dXJuIFBlbmRpbmdJbnRlbnQuZ2V0U2VydmljZShjb250ZXh0LCByZXF1ZXN0Q29kZSwgaW50ZW50LCBmbGFncyk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZvcmVncm91bmQvcmVzL3ZhbHVlcy9zdHJpbmdzLnhtbCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZm9yZWdyb3VuZC9yZXMvdmFsdWVzL3N0cmluZ3MueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4OTZiMGMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZvcmVncm91bmQvcmVzL3ZhbHVlcy9zdHJpbmdzLnhtbApAQCAtMCwwICsxLDU0IEBACis8IS0tCisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLS0+Cis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI/PgorPHJlc291cmNlcz4KKyAgPCEtLSBOb3RpZmljYXRpb24gdGl0bGUgdGhhdCBpcyBzaG93biB3aGVuIE1ERCBpcworICAgIGRvd25sb2FkaW5nIGEgZmlsZS5bQ0hBUl9MSU1JVD04MF0gLS0+CisgIDxzdHJpbmcgbmFtZT0ibWRkX2ZvcmVncm91bmRfc2VydmljZV9ub3RpZmljYXRpb25fdGl0bGUiPgorICAgIERvd25sb2FkaW5nCisgIDwvc3RyaW5nPgorCisgIDwhLS0gTm90aWZpY2F0aW9uIGNoYW5uZWwgZ3JvdXAgdGhhdCBpcyBzaG93biB3aGVuIGxvbmcgcHJlc3NpbmcgYW55IG5vdGlmaWNhdGlvbi4KK1tDSEFSX0xJTUlUPTgwXSAtLT4KKyAgPHN0cmluZyBuYW1lPSJtZGRfZG93bmxvYWRfbm90aWZpY2F0aW9uX2NoYW5uZWxfbmFtZSI+CisgICAgRGF0YSBEb3dubG9hZCBOb3RpZmljYXRpb24gQ2hhbm5lbAorICA8L3N0cmluZz4KKworICA8IS0tIE5vdGlmaWNhdGlvbiB0aXRsZSB0aGF0IGlzIHNob3duIGZvciBldmVyeSBmaWxlIHRoYXQgaXMgY3VycmVudGx5CisgICAgZG93bmxvYWRpbmcgYnV0IGlzIHRlbXBvcmFyeSBwYXVzZWQgZHVlIHRvIG5ldHdvcmsgY29ubmVjdGlvbi4gW0NIQVJfTElNSVQ9ODBdIC0tPgorICA8c3RyaW5nIG5hbWU9Im1kZF9ub3RpZmljYXRpb25fZG93bmxvYWRfcGF1c2VkIj4KKyAgICBXYWl0aW5nIGZvciBuZXR3b3JrIGNvbm5lY3Rpb24KKyAgPC9zdHJpbmc+CisKKyAgPCEtLSBOb3RpZmljYXRpb24gdGl0bGUgdGhhdCBpcyBzaG93biBmb3IgZXZlcnkgZmlsZSB0aGF0IHdhcyBzdWNjZXNzZnVsbHkKKyAgICBkb3dubG9hZGVkLltDSEFSX0xJTUlUPTgwXSAtLT4KKyAgPHN0cmluZyBuYW1lPSJtZGRfbm90aWZpY2F0aW9uX2Rvd25sb2FkX3N1Y2Nlc3MiPgorICAgIERvd25sb2FkZWQKKyAgPC9zdHJpbmc+CisKKyAgPCEtLSBOb3RpZmljYXRpb24gdGl0bGUgdGhhdCBpcyBzaG93biBmb3IgZXZlcnkgZmlsZSB0aGF0IGZhaWxlZCB0byBkb3dubG9hZC4KKyAgICBbQ0hBUl9MSU1JVD04MF0gLS0+CisgIDxzdHJpbmcgbmFtZT0ibWRkX25vdGlmaWNhdGlvbl9kb3dubG9hZF9mYWlsZWQiPgorICAgIERvd25sb2FkIGZhaWxlZAorICA8L3N0cmluZz4KKworICA8IS0tIFRoZSBjYW5jZWwgYWN0aW9uIG1lbnUuW0NIQVJfTElNSVQ9ODBdIC0tPgorICA8c3RyaW5nIG5hbWU9Im1kZF9ub3RpZmljYXRpb25fYWN0aW9uX2NhbmNlbCI+CisgICAgQ2FuY2VsCisgIDwvc3RyaW5nPgorPC9yZXNvdXJjZXM+CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0FjdGl2YXRpb25SZXF1aXJlZEZvckdyb3VwRXhjZXB0aW9uLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0FjdGl2YXRpb25SZXF1aXJlZEZvckdyb3VwRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGYyMGY1YwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvQWN0aXZhdGlvblJlcXVpcmVkRm9yR3JvdXBFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDE5IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbDsKKworLyoqIFRocm93biB3aGVuIHRyeWluZyB0byBhZGQgYSBGaWxlIEdyb3VwIHRoYXQgcmVxdWlyZXMgZGV2aWNlIHNpZGUgYWN0aXZhdGlvbi4gKi8KK3B1YmxpYyBjbGFzcyBBY3RpdmF0aW9uUmVxdWlyZWRGb3JHcm91cEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7fQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9BcHBsaWNhdGlvbkNvbnRleHQuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvQXBwbGljYXRpb25Db250ZXh0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDI0YmI4NAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvQXBwbGljYXRpb25Db250ZXh0LmphdmEKQEAgLTAsMCArMSwyMiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWw7CisKK2ltcG9ydCBqYXZheC5pbmplY3QuUXVhbGlmaWVyOworCisvKiogUXVhbGlmaWVyIGZvciB0aGUgYXBwbGljYXRpb24gQ29udGV4dC4gKi8KK0BRdWFsaWZpZXIKK3B1YmxpYyBAaW50ZXJmYWNlIEFwcGxpY2F0aW9uQ29udGV4dCB7fQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjhmOTEzOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvQlVJTEQKQEAgLTAsMCArMSwyOTIgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyIiwKKyAgICBzcmNzID0gWyJNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOkFwcGxpY2F0aW9uQ29udGV4dCIsCisgICAgICAgICI6RGF0YUZpbGVHcm91cFZhbGlkYXRvciIsCisgICAgICAgICI6RXhwaXJhdGlvbkhhbmRsZXIiLAorICAgICAgICAiOkZpbGVHcm91cE1hbmFnZXIiLAorICAgICAgICAiOkZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICI6TWRkRXhjZXB0aW9ucyIsCisgICAgICAgICI6TWlncmF0aW9ucyIsCisgICAgICAgICI6U2hhcmVkRmlsZU1hbmFnZXIiLAorICAgICAgICAiOlNoYXJlZEZpbGVzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZpbGVTb3VyY2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpTaWxlbnRGZWVkYmFjayIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtczpwcm90byIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvYW5ub3RhdGlvbnM6U2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlcjpGaWxlVmFsaWRhdG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9leHBlcmltZW50YXRpb246RG93bmxvYWRTdGFnZU1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6RXZlbnRMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6RmlsZUdyb3VwU3RhdHNMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dnaW5nU3RhdGVTdG9yZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpOZXR3b3JrTG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOlN0b3JhZ2VMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpGaWxlR3JvdXBVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOlNoYXJlZFByZWZlcmVuY2VzVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZzpjb25jdXJyZW50IiwKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAYW5kcm9pZHhfYW5ub3RhdGlvbl9hbm5vdGF0aW9uIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2RhZ2dlciIsCisgICAgICAgICJAY29tX2dvb2dsZV9lcnJvcnByb25lX2Vycm9yX3Byb25lX2Fubm90YXRpb25zIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86YW55X3Byb3RvIiwKKyAgICAgICAgIkBqYXZheF9pbmplY3QiLAorICAgICAgICAiQG9yZ19jaGVja2VyZnJhbWV3b3JrX3F1YWwiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkRhdGFGaWxlR3JvdXBWYWxpZGF0b3IiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpNZGRDb25zdGFudHMiLAorICAgICAgICAiOk1pZ3JhdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOkZpbGVHcm91cFV0aWwiLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJNZGRFeGNlcHRpb25zIiwKKyAgICBzcmNzID0gWworICAgICAgICAiQWN0aXZhdGlvblJlcXVpcmVkRm9yR3JvdXBFeGNlcHRpb24uamF2YSIsCisgICAgICAgICJFeHBpcmVkRmlsZUdyb3VwRXhjZXB0aW9uLmphdmEiLAorICAgICAgICAiU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24uamF2YSIsCisgICAgICAgICJVbmluc3RhbGxlZEFwcEV4Y2VwdGlvbi5qYXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJNZGRDb25zdGFudHMiLAorICAgIHNyY3MgPSBbIk1kZENvbnN0YW50cy5qYXZhIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk1pZ3JhdGlvbnMiLAorICAgIHNyY3MgPSBbIk1pZ3JhdGlvbnMuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6U2lsZW50RmVlZGJhY2siLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiQXBwbGljYXRpb25Db250ZXh0IiwKKyAgICBzcmNzID0gWworICAgICAgICAiQXBwbGljYXRpb25Db250ZXh0LmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX2RhZ2dlciIsCisgICAgICAgICJAamF2YXhfaW5qZWN0IiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJGaWxlR3JvdXBNYW5hZ2VyIiwKKyAgICBzcmNzID0gWyJGaWxlR3JvdXBNYW5hZ2VyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOkFwcGxpY2F0aW9uQ29udGV4dCIsCisgICAgICAgICI6RmlsZUdyb3Vwc01ldGFkYXRhIiwKKyAgICAgICAgIjpNZGRDb25zdGFudHMiLAorICAgICAgICAiOk1kZEV4Y2VwdGlvbnMiLAorICAgICAgICAiOlNoYXJlZEZpbGVNYW5hZ2VyIiwKKyAgICAgICAgIjpTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpBY2NvdW50U291cmNlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpBZ2dyZWdhdGVFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGaWxlU291cmNlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6U2lsZW50RmVlZGJhY2siLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOlRpbWVTb3VyY2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2FjY291bnQ6QWNjb3VudFV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9hbm5vdGF0aW9uczpTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9leHBlcmltZW50YXRpb246RG93bmxvYWRTdGFnZU1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6RG93bmxvYWRTdGF0ZUxvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpFdmVudExvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6QW5kcm9pZFNoYXJpbmdVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOkRpcmVjdG9yeVV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6RmlsZUdyb3VwVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpTeW1saW5rVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZzpjb25jdXJyZW50IiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfYXV0b192YWx1ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAY29tX2dvb2dsZV9wcm90b2J1Zi8vOmFueV9wcm90byIsCisgICAgICAgICJAamF2YXhfaW5qZWN0IiwKKyAgICAgICAgIkBvcmdfY2hlY2tlcmZyYW1ld29ya19xdWFsIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJGaWxlR3JvdXBzTWV0YWRhdGEiLAorICAgIHNyY3MgPSBbIkZpbGVHcm91cHNNZXRhZGF0YS5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQG9yZ19jaGVja2VyZnJhbWV3b3JrX3F1YWwiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIlNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhIiwKKyAgICBzcmNzID0gWyJTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YS5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpBcHBsaWNhdGlvbkNvbnRleHQiLAorICAgICAgICAiOkZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6U2lsZW50RmVlZGJhY2siLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOlRpbWVTb3VyY2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9hbm5vdGF0aW9uczpTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ1V0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpGaWxlR3JvdXBVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOkZpbGVHcm91cHNNZXRhZGF0YVV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6UHJvdG9MaXRlVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpTaGFyZWRQcmVmZXJlbmNlc1V0aWwiLAorICAgICAgICAiQGFuZHJvaWR4X2Fubm90YXRpb25fYW5ub3RhdGlvbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9lcnJvcnByb25lX2Vycm9yX3Byb25lX2Fubm90YXRpb25zIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBqYXZheF9pbmplY3QiLAorICAgICAgICAiQG9yZ19jaGVja2VyZnJhbWV3b3JrX3F1YWwiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkV4cGlyYXRpb25IYW5kbGVyIiwKKyAgICBzcmNzID0gWyJFeHBpcmF0aW9uSGFuZGxlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpBcHBsaWNhdGlvbkNvbnRleHQiLAorICAgICAgICAiOkZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICI6U2hhcmVkRmlsZU1hbmFnZXIiLAorICAgICAgICAiOlNoYXJlZEZpbGVzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpTaWxlbnRGZWVkYmFjayIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6VGltZVNvdXJjZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Fubm90YXRpb25zOlNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6RXZlbnRMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOkRpcmVjdG9yeVV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6RmlsZUdyb3VwVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZzpjb25jdXJyZW50IiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGphdmF4X2luamVjdCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiU2hhcmVkRmlsZU1hbmFnZXIiLAorICAgIHNyY3MgPSBbIlNoYXJlZEZpbGVNYW5hZ2VyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOkFwcGxpY2F0aW9uQ29udGV4dCIsCisgICAgICAgICI6RmlsZUdyb3Vwc01ldGFkYXRhIiwKKyAgICAgICAgIjpNZGRDb25zdGFudHMiLAorICAgICAgICAiOk1kZEV4Y2VwdGlvbnMiLAorICAgICAgICAiOk1pZ3JhdGlvbnMiLAorICAgICAgICAiOlNoYXJlZEZpbGVzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGaWxlU291cmNlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6U2lsZW50RmVlZGJhY2siLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kZWx0YTpEZWx0YURlY29kZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9hbm5vdGF0aW9uczpTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyOkRlbHRhRmlsZURvd25sb2FkZXJDYWxsYmFja0ltcGwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXI6RG93bmxvYWRlckNhbGxiYWNrSW1wbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlcjpGaWxlTmFtZVV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXI6RmlsZVZhbGlkYXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlcjpNZGRGaWxlRG93bmxvYWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpFdmVudExvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6RGlyZWN0b3J5VXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpTaGFyZWRQcmVmZXJlbmNlc1V0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3I6RG93bmxvYWRQcm9ncmVzc01vbml0b3IiLAorICAgICAgICAiQGFuZHJvaWR4X2Fubm90YXRpb25fYW5ub3RhdGlvbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICJAY29tX2dvb2dsZV9kYWdnZXIiLAorICAgICAgICAiQGNvbV9nb29nbGVfZXJyb3Jwcm9uZV9lcnJvcl9wcm9uZV9hbm5vdGF0aW9ucyIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAamF2YXhfaW5qZWN0IiwKKyAgICAgICAgIkBvcmdfY2hlY2tlcmZyYW1ld29ya19xdWFsIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICBzcmNzID0gWyJTaGFyZWRGaWxlc01ldGFkYXRhLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOk1pZ3JhdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOlNpbGVudEZlZWRiYWNrIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6RmlsZUdyb3VwVXRpbCIsCisgICAgICAgICIvL3Byb3RvOnRyYW5zZm9ybV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIlNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YSIsCisgICAgc3JjcyA9IFsiU2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOkFwcGxpY2F0aW9uQ29udGV4dCIsCisgICAgICAgICI6TWRkQ29uc3RhbnRzIiwKKyAgICAgICAgIjpNaWdyYXRpb25zIiwKKyAgICAgICAgIjpTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6U2lsZW50RmVlZGJhY2siLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ1V0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpTaGFyZWRGaWxlc01ldGFkYXRhVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpTaGFyZWRQcmVmZXJlbmNlc1V0aWwiLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfZXJyb3Jwcm9uZV9lcnJvcl9wcm9uZV9hbm5vdGF0aW9ucyIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAamF2YXhfaW5qZWN0IiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9EYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0RhdGFGaWxlR3JvdXBWYWxpZGF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDQ5MTU3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9EYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmphdmEKQEAgLTAsMCArMSwyNTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLlRyYW5zZm9ybVByb3RvczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5GaWxlR3JvdXBVdGlsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLlRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybXM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlLkNoZWNrc3VtVHlwZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbC5BbGxvd2VkUmVhZGVyczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRlbHRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRlbHRhRmlsZS5EaWZmRGVjb2RlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VOZXR3b3JrUG9saWN5OworCisvKiogRGF0YUZpbGVHcm91cFZhbGlkYXRvciAtIHZhbGlkYXRlcyB0aGUgcGFzc2VkIGluIERhdGFGaWxlR3JvdXAgKi8KK3B1YmxpYyBjbGFzcyBEYXRhRmlsZUdyb3VwVmFsaWRhdG9yIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIkRhdGFGaWxlR3JvdXBWYWxpZGF0b3IiOworCisgIC8qKgorICAgKiBDaGVja3MgaWYgdGhlIGRhdGEgZmlsZSBncm91cCB0aGF0IHdlIHJlY2VpdmVkIGlzIGEgdmFsaWQgZ3JvdXAuIEEgZ3JvdXAgaXMgdmFsaWQgaWYgYWxsIHRoZQorICAgKiBkYXRhIHJlcXVpcmVkIHRvIGRvd25sb2FkIGl0IGlzIHByZXNlbnQuIElmIGFueSBmaWVsZCB0aGF0IGlzIG5vdCByZXF1aXJlZCBpcyBzZXQsIGl0IHdpbGwgYmUKKyAgICogaWdub3JlZC4KKyAgICoKKyAgICogPHA+VGhpcyBpcyBqdXN0IGEgc2FuaXR5IGNoZWNrLiBGb3IgZXhhbXBsZSwgaXQgZG9lc24ndCBjaGVjayBpZiB0aGUgZmlsZSBpcyBwcmVzZW50IGF0IHRoZQorICAgKiBnaXZlbiBsb2NhdGlvbi4KKyAgICoKKyAgICogQHBhcmFtIGRhdGFGaWxlR3JvdXAgVGhlIGRhdGEgZmlsZSBncm91cCBvbiB3aGljaCBzYW5pdHkgY2hlY2sgbmVlZHMgdG8gYmUgZG9uZS4KKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSBncm91cCBpcyB2YWxpZC4KKyAgICovCisgIC8vIFRPRE8oYi8xMjQwNzI3NTQpOiBDaGFuZ2UgdG8gcGFja2FnZSBwcml2YXRlIG9uY2UgYWxsIGNvZGUgaXMgcmVmYWN0b3JlZC4KKyAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVmFsaWRHcm91cCgKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwLCBDb250ZXh0IGNvbnRleHQsIEZsYWdzIGZsYWdzKSB7CisgICAgLy8gQ2hlY2sgaWYgdGhlIGdyb3VwIG5hbWUgaXMgZW1wdHkuCisgICAgaWYgKGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkuaXNFbXB0eSgpKSB7CisgICAgICBMb2dVdGlsLmUoIiVzIEdyb3VwIG5hbWUgbWlzc2luZyBpbiBhZGRlZCBncm91cCIsIFRBRyk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgaWYgKGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkuY29udGFpbnMoTWRkQ29uc3RhbnRzLlNQTElUX0NIQVIpKSB7CisgICAgICBMb2dVdGlsLmUoIiVzIEdyb3VwIG5hbWUgPSAlcyBjb250YWlucyAnfCciLCBUQUcsIGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIGlmIChkYXRhRmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpLmNvbnRhaW5zKE1kZENvbnN0YW50cy5TUExJVF9DSEFSKSkgeworICAgICAgTG9nVXRpbC5lKCIlcyBPd25lciBwYWNrYWdlID0gJXMgY29udGFpbnMgJ3wnIiwgVEFHLCBkYXRhRmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBDaGVjayBpZiBhbnkgZmlsZSBpcyBtaXNzaW5nIGFueSBvZiB0aGUgcmVxdWlyZWQgZmllbGRzLgorICAgIGZvciAoRGF0YUZpbGUgZGF0YUZpbGUgOiBkYXRhRmlsZUdyb3VwLmdldEZpbGVMaXN0KCkpIHsKKyAgICAgIGlmIChkYXRhRmlsZS5nZXRGaWxlSWQoKS5pc0VtcHR5KCkKKyAgICAgICAgICB8fCBkYXRhRmlsZS5nZXRGaWxlSWQoKS5jb250YWlucyhNZGRDb25zdGFudHMuU1BMSVRfQ0hBUikKKyAgICAgICAgICB8fCAhaXNWYWxpZERhdGFGaWxlKGRhdGFGaWxlKSkgeworICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAiJXMgRmlsZSBkZXRhaWxzIG1pc3NpbmcgaW4gYWRkZWQgZ3JvdXAgPSAlcywgZmlsZSBpZCA9ICVzIiwKKyAgICAgICAgICAgIFRBRywgZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSwgZGF0YUZpbGUuZ2V0RmlsZUlkKCkpOworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICBpZiAoIWhhc1ZhbGlkVHJhbnNmb3JtcyhkYXRhRmlsZUdyb3VwLCBkYXRhRmlsZSwgZmxhZ3MpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGlmICghaGFzVmFsaWREZWx0YUZpbGVzKGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCksIGRhdGFGaWxlKSkgeworICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICB9CisgICAgICAvLyBDaGVjayBpZiBzaWRlbG9hZGVkIGZpbGVzIGFyZSBwcmVzZW50IGFuZCBpZiBzaWRlbG9hZGluZyBpcyBlbmFibGVkCisgICAgICBpZiAoRmlsZUdyb3VwVXRpbC5pc1NpZGVsb2FkZWRGaWxlKGRhdGFGaWxlKSAmJiAhZmxhZ3MuZW5hYmxlU2lkZWxvYWRpbmcoKSkgeworICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAiJXMgRmlsZSBkZXRlY3RlZCBhcyBzaWRlbG9hZGVkLCBidXQgc2lkZWxvYWRpbmcgaXMgbm90IGVuYWJsZWQuIGdyb3VwID0gJXMsIGZpbGUgaWQgPSIKKyAgICAgICAgICAgICAgICArICIgJXMsIGZpbGUgdXJsID0gJXMiLAorICAgICAgICAgICAgVEFHLCBkYXRhRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZGF0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKworICAgIC8vIENoZWNrIGlmIGEgZmlsZSBpZCBpcyByZXBlYXRlZC4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGFGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCk7IGkrKykgeworICAgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgZGF0YUZpbGVHcm91cC5nZXRGaWxlQ291bnQoKTsgaisrKSB7CisgICAgICAgIGlmIChkYXRhRmlsZUdyb3VwLmdldEZpbGUoaSkuZ2V0RmlsZUlkKCkuZXF1YWxzKGRhdGFGaWxlR3JvdXAuZ2V0RmlsZShqKS5nZXRGaWxlSWQoKSkpIHsKKyAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICIlcyBSZXBlYXRlZCBmaWxlIGlkIGluIGFkZGVkIGdyb3VwID0gJXMsIGZpbGUgaWQgPSAlcyIsCisgICAgICAgICAgICAgIFRBRywgZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSwgZGF0YUZpbGVHcm91cC5nZXRGaWxlKGkpLmdldEZpbGVJZCgpKTsKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoZGF0YUZpbGVHcm91cAorICAgICAgICAgICAgLmdldERvd25sb2FkQ29uZGl0aW9ucygpCisgICAgICAgICAgICAuZ2V0RGV2aWNlTmV0d29ya1BvbGljeSgpCisgICAgICAgICAgICAuZXF1YWxzKERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfRklSU1RfT05fV0lGSV9USEVOX09OX0FOWV9ORVRXT1JLKQorICAgICAgICAmJiBkYXRhRmlsZUdyb3VwLmdldERvd25sb2FkQ29uZGl0aW9ucygpLmdldERvd25sb2FkRmlyc3RPbldpZmlQZXJpb2RTZWNzKCkgPD0gMCkgeworICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICIlcyBGb3IgRE9XTkxPQURfRklSU1RfT05fV0lGSV9USEVOX09OX0FOWV9ORVRXT1JLIHBvbGljeSwgIgorICAgICAgICAgICAgICArICJ0aGUgZG93bmxvYWRfZmlyc3Rfb25fd2lmaV9wZXJpb2Rfc2VjcyBtdXN0IGJlID4gMCIsCisgICAgICAgICAgVEFHKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICBpZiAoIU1pZ3JhdGlvbnMuaXNNaWdyYXRlZFRvTmV3RmlsZUtleShjb250ZXh0KQorICAgICAgICAmJiBkYXRhRmlsZUdyb3VwLmdldEFsbG93ZWRSZWFkZXJzRW51bSgpLmVxdWFscyhBbGxvd2VkUmVhZGVycy5BTExfQVBQUykpIHsKKyAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAiJXMgRm9yIEFsbG93ZWRSZWFkZXJzIEFMTF9BUFBTIHBvbGljeSwgdGhlIGRldmljZSBzaG91bGQgYmUgbWlncmF0ZWQgdG8gbmV3IGtleSIsIFRBRyk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGhhc1ZhbGlkVHJhbnNmb3JtcygKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwLCBEYXRhRmlsZSBkYXRhRmlsZSwgRmxhZ3MgZmxhZ3MpIHsKKyAgICAvLyBWZXJpZnkgZm9yIERvd25sb2FkIHRyYW5zZm9ybXMKKyAgICBpZiAoZGF0YUZpbGUuaGFzRG93bmxvYWRUcmFuc2Zvcm1zKCkpIHsKKyAgICAgIGlmICghaXNWYWxpZFRyYW5zZm9ybXMoZGF0YUZpbGUuZ2V0RG93bmxvYWRUcmFuc2Zvcm1zKCkpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGlmICghaGFzVmFsaWRaaXBEb3dubG9hZFRyYW5zZm9ybShkYXRhRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpLCBkYXRhRmlsZSwgZmxhZ3MpKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGlmIChkYXRhRmlsZS5nZXRDaGVja3N1bVR5cGUoKSAhPSBDaGVja3N1bVR5cGUuTk9ORQorICAgICAgICAgICYmICFkYXRhRmlsZS5oYXNEb3dubG9hZGVkRmlsZUNoZWNrc3VtKCkpIHsKKyAgICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICAgIkRvd25sb2FkIGNoZWNrc3VtIG11c3QgYmUgcHJvdmlkZWQuIEdyb3VwID0gJXMsIGZpbGUgaWQgPSAlcyIsCisgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gVmVyaWZ5IGZvciBSZWFkIHRyYW5zZm9ybXMKKyAgICBpZiAoZGF0YUZpbGUuaGFzUmVhZFRyYW5zZm9ybXMoKSAmJiAhaXNWYWxpZFRyYW5zZm9ybXMoZGF0YUZpbGUuZ2V0UmVhZFRyYW5zZm9ybXMoKSkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGhhc1ZhbGlkWmlwRG93bmxvYWRUcmFuc2Zvcm0oCisgICAgICBTdHJpbmcgZ3JvdXBOYW1lLCBEYXRhRmlsZSBkYXRhRmlsZSwgRmxhZ3MgZmxhZ3MpIHsKKyAgICBpZiAoRmlsZUdyb3VwVXRpbC5oYXNaaXBEb3dubG9hZFRyYW5zZm9ybShkYXRhRmlsZSkpIHsKKyAgICAgIGlmICghZmxhZ3MuZW5hYmxlWmlwRm9sZGVyKCkpIHsKKyAgICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICAgIkZlYXR1cmUgZW5hYmxlWmlwRm9sZGVyIGlzIG5vdCBlbmFibGVkLiBHcm91cCA9ICVzLCBmaWxlIGlkID0gJXMiLAorICAgICAgICAgICAgZ3JvdXBOYW1lLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSk7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGlmIChkYXRhRmlsZS5nZXREb3dubG9hZFRyYW5zZm9ybXMoKS5nZXRUcmFuc2Zvcm1Db3VudCgpID4gMSkgeworICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAiRG93bmxvYWQgemlwIGZvbGRlciB0cmFuc2Zvcm0gY2Fubm90IG5vdCBiZSBhcHBsaWVkIHdpdGggb3RoZXIgdHJhbnNmb3Jtcy4gR3JvdXAgPSIKKyAgICAgICAgICAgICAgICArICIgJXMsIGZpbGUgaWQgPSAlcyIsCisgICAgICAgICAgICBncm91cE5hbWUsIGRhdGFGaWxlLmdldEZpbGVJZCgpKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgaWYgKCEiKiIuZXF1YWxzKGRhdGFGaWxlLmdldERvd25sb2FkVHJhbnNmb3JtcygpLmdldFRyYW5zZm9ybSgwKS5nZXRaaXAoKS5nZXRUYXJnZXQoKSkpIHsKKyAgICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICAgIkRvd25sb2FkIHppcCBmb2xkZXIgdHJhbnNmb3JtIGNhbiBvbmx5IGhhdmUgKiBhcyB0YXJnZXQuIEdyb3VwID0gJXMsIGZpbGUgaWQgPSAlcyIsCisgICAgICAgICAgICBncm91cE5hbWUsIGRhdGFGaWxlLmdldEZpbGVJZCgpKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNWYWxpZFRyYW5zZm9ybXMoVHJhbnNmb3JtcyB0cmFuc2Zvcm1zKSB7CisgICAgdHJ5IHsKKyAgICAgIFRyYW5zZm9ybVByb3Rvcy50b0VuY29kZWRGcmFnbWVudCh0cmFuc2Zvcm1zKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24pIHsKKyAgICAgIExvZ1V0aWwuZShpbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24sICJJbnZhbGlkIHRyYW5zZm9ybSBzcGVjaWZpY2F0aW9uIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBoYXNWYWxpZERlbHRhRmlsZXMoU3RyaW5nIGdyb3VwTmFtZSwgRGF0YUZpbGUgZGF0YUZpbGUpIHsKKyAgICBmb3IgKERlbHRhRmlsZSBkZWx0YUZpbGUgOiBkYXRhRmlsZS5nZXREZWx0YUZpbGVMaXN0KCkpIHsKKyAgICAgIGlmICghaXNWYWxpZERlbHRhRmlsZShkZWx0YUZpbGUpKSB7CisgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICIlcyBEZWx0YSBGaWxlIG9mIERhdGFmaWxlIGRldGFpbHMgbWlzc2luZyBpbiBhZGRlZCBncm91cCA9ICVzLCBmaWxlIGlkID0gJXMiCisgICAgICAgICAgICAgICAgKyAiLCBkZWx0YSBmaWxlIFVybFRvRG93bmxvYWQgPSAlcy4iLAorICAgICAgICAgICAgVEFHLCBncm91cE5hbWUsIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBkZWx0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpKTsKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNWYWxpZERhdGFGaWxlKERhdGFGaWxlIGRhdGFGaWxlKSB7CisgICAgLy8gV2hlbiBhIGRhdGEgZmlsZSBoYXMgemlwIHRyYW5zZm9ybSwgZG93bmxvYWRlZCBmaWxlIGNoZWNrc3VtIGlzIHVzZWQgZm9yIGlkZW50aWZ5aW5nIHRoZSBkYXRhCisgICAgLy8gZmlsZTsgb3RoZXJ3aXNlLCBjaGVja3N1bSBpcyB1c2VkLgorICAgIGJvb2xlYW4gaGFzTm9uRW1wdHlDaGVja3N1bTsKKyAgICBpZiAoRmlsZUdyb3VwVXRpbC5oYXNaaXBEb3dubG9hZFRyYW5zZm9ybShkYXRhRmlsZSkpIHsKKyAgICAgIGhhc05vbkVtcHR5Q2hlY2tzdW0gPQorICAgICAgICAgIGRhdGFGaWxlLmhhc0Rvd25sb2FkZWRGaWxlQ2hlY2tzdW0oKSAmJiAhZGF0YUZpbGUuZ2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bSgpLmlzRW1wdHkoKTsKKyAgICB9IGVsc2UgeworICAgICAgaGFzTm9uRW1wdHlDaGVja3N1bSA9IGRhdGFGaWxlLmhhc0NoZWNrc3VtKCkgJiYgIWRhdGFGaWxlLmdldENoZWNrc3VtKCkuaXNFbXB0eSgpOworICAgIH0KKworICAgIGJvb2xlYW4gdmFsaWRDaGVja3N1bTsKKyAgICBzd2l0Y2ggKGRhdGFGaWxlLmdldENoZWNrc3VtVHlwZSgpKSB7CisgICAgICAgIC8vIERlZmF1bHQgc3RhbmRzIGZvciBTSEExLgorICAgICAgY2FzZSBERUZBVUxUOgorICAgICAgICB2YWxpZENoZWNrc3VtID0gaGFzTm9uRW1wdHlDaGVja3N1bTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIE5PTkU6CisgICAgICAgIHZhbGlkQ2hlY2tzdW0gPSAhaGFzTm9uRW1wdHlDaGVja3N1bTsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICB2YWxpZENoZWNrc3VtID0gZmFsc2U7CisgICAgfQorCisgICAgLy8gRmlsZSBjaGVja3N1bSBpcyBub3QgbmVlZGVkIGZvciB6aXAgZm9sZGVyIGRvd25sb2FkIHRyYW5zZm9ybXMuCisgICAgdmFsaWRDaGVja3N1bSB8PSBGaWxlR3JvdXBVdGlsLmhhc1ppcERvd25sb2FkVHJhbnNmb3JtKGRhdGFGaWxlKSAmJiAhaGFzTm9uRW1wdHlDaGVja3N1bTsKKworICAgIGJvb2xlYW4gdmFsaWRBbmRyb2lkU2hhcmluZ0NvbmZpZyA9CisgICAgICAgIGRhdGFGaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW1UeXBlKCkgPT0gRGF0YUZpbGUuQW5kcm9pZFNoYXJpbmdDaGVja3N1bVR5cGUuU0hBMl8yNTYKKyAgICAgICAgICAgID8gIWRhdGFGaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKS5pc0VtcHR5KCkKKyAgICAgICAgICAgIDogdHJ1ZTsKKworICAgIHJldHVybiAhZGF0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpLmlzRW1wdHkoKQorICAgICAgICAmJiAhZGF0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpLmNvbnRhaW5zKE1kZENvbnN0YW50cy5TUExJVF9DSEFSKQorICAgICAgICAmJiBkYXRhRmlsZS5nZXRCeXRlU2l6ZSgpID49IDAKKyAgICAgICAgJiYgdmFsaWRDaGVja3N1bQorICAgICAgICAmJiB2YWxpZEFuZHJvaWRTaGFyaW5nQ29uZmlnCisgICAgICAgICYmICFGaWxlR3JvdXBVdGlsLmdldEZpbGVDaGVja3N1bShkYXRhRmlsZSkuY29udGFpbnMoTWRkQ29uc3RhbnRzLlNQTElUX0NIQVIpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc1ZhbGlkRGVsdGFGaWxlKERlbHRhRmlsZSBkZWx0YUZpbGUpIHsKKyAgICByZXR1cm4gIWRlbHRhRmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkuaXNFbXB0eSgpCisgICAgICAgICYmICFkZWx0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpLmNvbnRhaW5zKE1kZENvbnN0YW50cy5TUExJVF9DSEFSKQorICAgICAgICAmJiBkZWx0YUZpbGUuaGFzQnl0ZVNpemUoKQorICAgICAgICAmJiBkZWx0YUZpbGUuZ2V0Qnl0ZVNpemUoKSA+PSAwCisgICAgICAgICYmICFkZWx0YUZpbGUuZ2V0Q2hlY2tzdW0oKS5pc0VtcHR5KCkKKyAgICAgICAgJiYgIWRlbHRhRmlsZS5nZXRDaGVja3N1bSgpLmNvbnRhaW5zKE1kZENvbnN0YW50cy5TUExJVF9DSEFSKQorICAgICAgICAmJiBkZWx0YUZpbGUuaGFzRGlmZkRlY29kZXIoKQorICAgICAgICAmJiAhZGVsdGFGaWxlLmdldERpZmZEZWNvZGVyKCkuZXF1YWxzKERpZmZEZWNvZGVyLlVOU1BFQ0lGSUVEKQorICAgICAgICAmJiBkZWx0YUZpbGUuaGFzQmFzZUZpbGUoKQorICAgICAgICAmJiAhZGVsdGFGaWxlLmdldEJhc2VGaWxlKCkuZ2V0Q2hlY2tzdW0oKS5pc0VtcHR5KCkKKyAgICAgICAgJiYgIWRlbHRhRmlsZS5nZXRCYXNlRmlsZSgpLmdldENoZWNrc3VtKCkuY29udGFpbnMoTWRkQ29uc3RhbnRzLlNQTElUX0NIQVIpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0V4cGlyYXRpb25IYW5kbGVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0V4cGlyYXRpb25IYW5kbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjVlZmUyMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvRXhwaXJhdGlvbkhhbmRsZXIuamF2YQpAQCAtMCwwICsxLDQ2MCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWw7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZTsKK2ltcG9ydCBzdGF0aWMgamF2YS5sYW5nLk1hdGgubWluOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGFuZHJvaWR4LmFubm90YXRpb24uVmlzaWJsZUZvclRlc3Rpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuU2lsZW50RmVlZGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGltZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5hbm5vdGF0aW9ucy5JbnN0YW5jZUlkOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5hbm5vdGF0aW9ucy5TZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuRXZlbnRMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuRGlyZWN0b3J5VXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLkZpbGVHcm91cFV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5Qcm9wYWdhdGVkRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwSW50ZXJuYWw7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLk5ld0ZpbGVLZXk7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0ludGVnZXI7CitpbXBvcnQgamF2YXguaW5qZWN0LkluamVjdDsKKworLyoqCisgKiBBIGNsYXNzIHRoYXQgaGFuZGxlcyBvZiB0aGUgbG9naWMgZm9yIGZpbGUgZ3JvdXAgZXhwaXJhdGlvbiBhbmQgZmlsZSBleHBpcmF0aW9uLiBFeHBpcmF0aW9uIGlzCisgKiBkZXRlcm1pbmVkIGJ5IHR3byBzb3VyY2VzOiAxKSB3aGVuIHRoZSBhY3RpdmVfZXhwaXJhdGlvbl9kYXRlIChzZXQgc2VydmVyLXNpZGUgYnkgdGhlIGNsaWVudCkgaGFzCisgKiBwYXNzZWQgMikgd2hlbiBzdGFsZV9saWZldGltZV9zZWNzIGhhcyBwYXNzZWQgc2luY2UgdGhlIGdyb3VwIGJlY2FtZSBzdGFsZS4KKyAqLworcHVibGljIGNsYXNzIEV4cGlyYXRpb25IYW5kbGVyIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIkV4cGlyYXRpb25IYW5kbGVyIjsKKworICBAVmlzaWJsZUZvclRlc3RpbmcKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfRVhQSVJBVElPTl9IQU5ETEVSID0gImdtc19pY2luZ19tZGRfZXhwaXJhdGlvbl9oYW5kbGVyIjsKKworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dDsKKyAgcHJpdmF0ZSBmaW5hbCBGaWxlR3JvdXBzTWV0YWRhdGEgZmlsZUdyb3Vwc01ldGFkYXRhOworICBwcml2YXRlIGZpbmFsIFNoYXJlZEZpbGVNYW5hZ2VyIHNoYXJlZEZpbGVNYW5hZ2VyOworICBwcml2YXRlIGZpbmFsIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YTsKKyAgcHJpdmF0ZSBmaW5hbCBFdmVudExvZ2dlciBldmVudExvZ2dlcjsKKyAgcHJpdmF0ZSBmaW5hbCBUaW1lU291cmNlIHRpbWVTb3VyY2U7CisgIHByaXZhdGUgZmluYWwgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQ7CisgIHByaXZhdGUgZmluYWwgU2lsZW50RmVlZGJhY2sgc2lsZW50RmVlZGJhY2s7CisgIHByaXZhdGUgZmluYWwgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKyAgcHJpdmF0ZSBmaW5hbCBGbGFncyBmbGFnczsKKworICBASW5qZWN0CisgIHB1YmxpYyBFeHBpcmF0aW9uSGFuZGxlcigKKyAgICAgIEBBcHBsaWNhdGlvbkNvbnRleHQgQ29udGV4dCBjb250ZXh0LAorICAgICAgRmlsZUdyb3Vwc01ldGFkYXRhIGZpbGVHcm91cHNNZXRhZGF0YSwKKyAgICAgIFNoYXJlZEZpbGVNYW5hZ2VyIHNoYXJlZEZpbGVNYW5hZ2VyLAorICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YSBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXIsCisgICAgICBUaW1lU291cmNlIHRpbWVTb3VyY2UsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLAorICAgICAgQEluc3RhbmNlSWQgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkLAorICAgICAgU2lsZW50RmVlZGJhY2sgc2lsZW50RmVlZGJhY2ssCisgICAgICBAU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciBFeGVjdXRvciBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLAorICAgICAgRmxhZ3MgZmxhZ3MpIHsKKyAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OworICAgIHRoaXMuZmlsZUdyb3Vwc01ldGFkYXRhID0gZmlsZUdyb3Vwc01ldGFkYXRhOworICAgIHRoaXMuc2hhcmVkRmlsZU1hbmFnZXIgPSBzaGFyZWRGaWxlTWFuYWdlcjsKKyAgICB0aGlzLnNoYXJlZEZpbGVzTWV0YWRhdGEgPSBzaGFyZWRGaWxlc01ldGFkYXRhOworICAgIHRoaXMuZXZlbnRMb2dnZXIgPSBldmVudExvZ2dlcjsKKyAgICB0aGlzLnRpbWVTb3VyY2UgPSB0aW1lU291cmNlOworICAgIHRoaXMuZmlsZVN0b3JhZ2UgPSBmaWxlU3RvcmFnZTsKKyAgICB0aGlzLmluc3RhbmNlSWQgPSBpbnN0YW5jZUlkOworICAgIHRoaXMuc2lsZW50RmVlZGJhY2sgPSBzaWxlbnRGZWVkYmFjazsKKyAgICB0aGlzLnNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgPSBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKKyAgfQorCisgIC8vIFRPRE8oYi8xMjQwNzI3NTQpOiBDaGFuZ2UgdG8gcGFja2FnZSBwcml2YXRlIG9uY2UgYWxsIGNvZGUgaXMgcmVmYWN0b3JlZC4KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gdXBkYXRlRXhwaXJhdGlvbigpIHsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIHJlbW92ZUV4cGlyZWRTdGFsZUdyb3VwcygpLAorICAgICAgICB2b2lkQXJnMCAtPgorICAgICAgICAgICAgUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgcmVtb3ZlRXhwaXJlZEZyZXNoR3JvdXBzKCksCisgICAgICAgICAgICAgICAgdm9pZEFyZzEgLT4gcmVtb3ZlVW5hY2NvdW50ZWRGaWxlcygpLAorICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpLAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIC8qKiBSZXR1cm5zIGEgZnV0dXJlIHRoYXQgY2hlY2tzIGFsbCBGaWxlIEdyb3VwcyBhbmQgcmVtb3ZlIGV4cGlyZWQgb25lcyBmcm9tIEZpbGVHcm91cE1hbmFnZXIgKi8KKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlbW92ZUV4cGlyZWRGcmVzaEdyb3VwcygpIHsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpLAorICAgICAgICBncm91cHMgLT4geworICAgICAgICAgIExpc3Q8R3JvdXBLZXk+IGV4cGlyZWRHcm91cEtleXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgICBmb3IgKFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gcGFpciA6IGdyb3VwcykgeworICAgICAgICAgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPSBwYWlyLmZpcnN0OworICAgICAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPSBwYWlyLnNlY29uZDsKKyAgICAgICAgICAgIExvbmcgZ3JvdXBFeHBpcmF0aW9uRGF0ZU1pbGxpcyA9IEZpbGVHcm91cFV0aWwuZ2V0RXhwaXJhdGlvbkRhdGVNaWxsaXMoZGF0YUZpbGVHcm91cCk7CisgICAgICAgICAgICBMb2dVdGlsLmQoCisgICAgICAgICAgICAgICAgIiVzOiBDaGVja2luZyBncm91cCAlcyB3aXRoIGV4cGlyYXRpb24gZGF0ZSAlcyIsCisgICAgICAgICAgICAgICAgVEFHLCBkYXRhRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpLCBncm91cEV4cGlyYXRpb25EYXRlTWlsbGlzKTsKKyAgICAgICAgICAgIGlmIChGaWxlR3JvdXBVdGlsLmlzRXhwaXJlZChncm91cEV4cGlyYXRpb25EYXRlTWlsbGlzLCB0aW1lU291cmNlKSkgeworICAgICAgICAgICAgICBldmVudExvZ2dlci5sb2dFdmVudFNhbXBsZWQoCisgICAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZUdyb3VwVmVyc2lvbk51bWJlcigpLAorICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRCdWlsZElkKCksCisgICAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLmdldFZhcmlhbnRJZCgpKTsKKyAgICAgICAgICAgICAgTG9nVXRpbC5kKAorICAgICAgICAgICAgICAgICAgIiVzOiBFeHBpcmVkIGdyb3VwICVzIHdpdGggZXhwaXJhdGlvbiBkYXRlICVzIiwKKyAgICAgICAgICAgICAgICAgIFRBRywgZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSwgZ3JvdXBFeHBpcmF0aW9uRGF0ZU1pbGxpcyk7CisgICAgICAgICAgICAgIGV4cGlyZWRHcm91cEtleXMuYWRkKGdyb3VwS2V5KTsKKworICAgICAgICAgICAgICAvLyBSZW1vdmUgSXNvbGF0ZWQgc3RydWN0dXJlIGlmIG5lY2Vzc2FyeS4KKyAgICAgICAgICAgICAgaWYgKEZpbGVHcm91cFV0aWwuaXNJc29sYXRlZFN0cnVjdHVyZUFsbG93ZWQoZGF0YUZpbGVHcm91cCkpIHsKKyAgICAgICAgICAgICAgICBGaWxlR3JvdXBVdGlsLnJlbW92ZUlzb2xhdGVkRmlsZVN0cnVjdHVyZSgKKyAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgaW5zdGFuY2VJZCwgZGF0YUZpbGVHcm91cCwgZmlsZVN0b3JhZ2UpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorCisgICAgICAgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKGV4cGlyZWRHcm91cEtleXMpLAorICAgICAgICAgICAgICByZW1vdmVTdWNjZXNzIC0+IHsKKyAgICAgICAgICAgICAgICBpZiAoIXJlbW92ZVN1Y2Nlc3MpIHsKKyAgICAgICAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZSgiJXM6IEZhaWxlZCB0byByZW1vdmUgZXhwaXJlZCBncm91cHMhIiwgVEFHKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICB9LAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIC8qKiBDaGVjayBhbmQgdXBkYXRlIGFsbCBzdGFsZSBGaWxlIEdyb3VwczsgcmVtb3ZlIHN0YWxlZCBvbmVzICovCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiByZW1vdmVFeHBpcmVkU3RhbGVHcm91cHMoKSB7CisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKSwKKyAgICAgICAgc3RhbGVHcm91cHMgLT4geworICAgICAgICAgIExpc3Q8RGF0YUZpbGVHcm91cEludGVybmFsPiBub25FeHBpcmVkU3RhbGVHcm91cHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgICBmb3IgKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBzdGFsZUdyb3VwIDogc3RhbGVHcm91cHMpIHsKKyAgICAgICAgICAgIGxvbmcgZ3JvdXBTdGFsZUV4cGlyYXRpb25EYXRlTWlsbGlzID0KKyAgICAgICAgICAgICAgICBGaWxlR3JvdXBVdGlsLmdldFN0YWxlRXhwaXJhdGlvbkRhdGVNaWxsaXMoc3RhbGVHcm91cCk7CisgICAgICAgICAgICBsb25nIGdyb3VwRXhwaXJhdGlvbkRhdGVNaWxsaXMgPSBGaWxlR3JvdXBVdGlsLmdldEV4cGlyYXRpb25EYXRlTWlsbGlzKHN0YWxlR3JvdXApOworICAgICAgICAgICAgbG9uZyBhY3R1YWxFeHBpcmF0aW9uRGF0ZU1pbGxpcyA9CisgICAgICAgICAgICAgICAgbWluKGdyb3VwU3RhbGVFeHBpcmF0aW9uRGF0ZU1pbGxpcywgZ3JvdXBFeHBpcmF0aW9uRGF0ZU1pbGxpcyk7CisKKyAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgZ3JvdXAgZnJvbSB0aGlzIGxpc3QgaWYgaXRzIGV4cGlyZWQuCisgICAgICAgICAgICBpZiAoRmlsZUdyb3VwVXRpbC5pc0V4cGlyZWQoYWN0dWFsRXhwaXJhdGlvbkRhdGVNaWxsaXMsIHRpbWVTb3VyY2UpKSB7CisgICAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgKKyAgICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgICBzdGFsZUdyb3VwLmdldEdyb3VwTmFtZSgpLAorICAgICAgICAgICAgICAgICAgc3RhbGVHcm91cC5nZXRGaWxlR3JvdXBWZXJzaW9uTnVtYmVyKCksCisgICAgICAgICAgICAgICAgICBzdGFsZUdyb3VwLmdldEJ1aWxkSWQoKSwKKyAgICAgICAgICAgICAgICAgIHN0YWxlR3JvdXAuZ2V0VmFyaWFudElkKCkpOworCisgICAgICAgICAgICAgIC8vIFJlbW92ZSBJc29sYXRlZCBzdHJ1Y3R1cmUgaWYgbmVjZXNzYXJ5LgorICAgICAgICAgICAgICBpZiAoRmlsZUdyb3VwVXRpbC5pc0lzb2xhdGVkU3RydWN0dXJlQWxsb3dlZChzdGFsZUdyb3VwKSkgeworICAgICAgICAgICAgICAgIEZpbGVHcm91cFV0aWwucmVtb3ZlSXNvbGF0ZWRGaWxlU3RydWN0dXJlKAorICAgICAgICAgICAgICAgICAgICBjb250ZXh0LCBpbnN0YW5jZUlkLCBzdGFsZUdyb3VwLCBmaWxlU3RvcmFnZSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIG5vbkV4cGlyZWRTdGFsZUdyb3Vwcy5hZGQoc3RhbGVHcm91cCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorCisgICAgICAgICAgLy8gRW1wdHkgdGhlIGxpc3Qgb2Ygc3RhbGUgZ3JvdXBzIGluIHRoZSBGR0dDIGFuZCB3cml0ZSBvbmx5IHRoZSBub24tZXhwaXJlZCBzdGFsZSBncm91cHMuCisgICAgICAgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlQWxsU3RhbGVHcm91cHMoKSwKKyAgICAgICAgICAgICAgdm9pZEFyZyAtPgorICAgICAgICAgICAgICAgICAgUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLndyaXRlU3RhbGVHcm91cHMobm9uRXhwaXJlZFN0YWxlR3JvdXBzKSwKKyAgICAgICAgICAgICAgICAgICAgICB3cml0ZVN1Y2Nlc3MgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF3cml0ZVN1Y2Nlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoIiVzOiBGYWlsZWQgdG8gd3JpdGUgYmFjayBzdGFsZSBncm91cHMhIiwgVEFHKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKSwKKyAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlbW92ZVVuYWNjb3VudGVkRmlsZXMoKSB7CisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBnZXRGaWxlS2V5c1JlZmVyZW5jZWRCeUFueUdyb3VwKCksCisgICAgICAgIC8vIFJlbW92ZSBhbGwgc2hhcmVkIGZpbGUgbWV0YWRhdGEgdGhhdCBhcmUgbm90IHJlZmVyZW5jZWQgYnkgYW55IGdyb3VwLgorICAgICAgICBmaWxlS2V5c1JlZmVyZW5jZWRCeUFueUdyb3VwIC0+CisgICAgICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLmdldEFsbEZpbGVLZXlzKCksCisgICAgICAgICAgICAgICAgYWxsRmlsZUtleXMgLT4geworICAgICAgICAgICAgICAgICAgTGlzdDxVcmk+IGZpbGVzUmVxdWlyZWRCeU1kZCA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICAgICAgICAgICAgTGlzdDxVcmk+IGFuZHJvaWRTaGFyZWRGaWxlc1RvQmVSZWxlYXNlZCA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICAgICAgICAgICAgLy8gVXNlIEF0b21pY0ludGVnZXIgYmVjYXVzZSB2YXJpYWJsZXMgY2FwdHVyZWQgYnkgbGFtYmRhcyBtdXN0IGJlIGVmZmVjdGl2ZWx5CisgICAgICAgICAgICAgICAgICAvLyBmaW5hbC4KKyAgICAgICAgICAgICAgICAgIEF0b21pY0ludGVnZXIgcmVtb3ZlZE1ldGFkYXRhQ291bnQgPSBuZXcgQXRvbWljSW50ZWdlcigwKTsKKyAgICAgICAgICAgICAgICAgIExpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4gZnV0dXJlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICAgICAgICAgICAgZm9yIChOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgOiBhbGxGaWxlS2V5cykgeworICAgICAgICAgICAgICAgICAgICBpZiAoIWZpbGVLZXlzUmVmZXJlbmNlZEJ5QW55R3JvdXAuY29udGFpbnMobmV3RmlsZUtleSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlbW92ZUVudHJ5RnV0dXJlID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNoYXJlZEZpbGUgIT0gbnVsbCAmJiBzaGFyZWRGaWxlLmdldEFuZHJvaWRTaGFyZWQoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZHJvaWRTaGFyZWRGaWxlc1RvQmVSZWxlYXNlZC5hZGQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIHNoYXJlZEZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyLnJlbW92ZUZpbGVFbnRyeShuZXdGaWxlS2V5KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3VjY2VzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZWRNZXRhZGF0YUNvdW50LmdldEFuZEluY3JlbWVudCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogVW5zdWJzY3JpYmUgZnJvbSBmaWxlICVzIGZhaWxlZCEiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUQUcsIG5ld0ZpbGVLZXkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICAgICAgICAgICAgICAgIGZ1dHVyZXMuYWRkKHJlbW92ZUVudHJ5RnV0dXJlKTsKKyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICBmdXR1cmVzLmFkZCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkobmV3RmlsZUtleSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmkgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXJpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc1JlcXVpcmVkQnlNZGQuYWRkKHVyaSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgIC8vIElmIGlzb2xhdGVkIHN0cnVjdHVyZSB2ZXJpZmljYXRpb24gaXMgZW5hYmxlZCwgaW5jbHVkZSBhbGwgaW5kaXZpZHVhbCBpc29sYXRlZAorICAgICAgICAgICAgICAgICAgLy8gZmlsZSB1cmlzIHJlZmVyZW5jZWQgYnkgZnJlc2ggZ3JvdXBzLiBUaGlzIGVuc3VyZXMgYW55IHVuYWNjb3VudGVkIGlzb2xhdGVkCisgICAgICAgICAgICAgICAgICAvLyBmaWxlIHVyaXMgYXJlIHJlbW92ZWQgKGkuZS4gdmVyaWZpY2F0aW9uIGlzIHBlcmZvcm1lZCkuCisgICAgICAgICAgICAgICAgICBpZiAoZmxhZ3MuZW5hYmxlSXNvbGF0ZWRTdHJ1Y3R1cmVWZXJpZmljYXRpb24oKSkgeworICAgICAgICAgICAgICAgICAgICBmdXR1cmVzLmFkZCgKKyAgICAgICAgICAgICAgICAgICAgICAgIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRJc29sYXRlZEZpbGVVcmlzUmVmZXJlbmNlZEJ5RnJlc2hHcm91cHMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2VkSXNvbGF0ZWRGaWxlVXJpcyAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc1JlcXVpcmVkQnlNZGQuYWRkQWxsKHJlZmVyZW5jZWRJc29sYXRlZEZpbGVVcmlzKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikpOworICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gSXNvbGF0ZWQgc3RydWN0dXJlIHZlcmlmaWNhdGlvbiBpcyBkaXNhYmxlZCwgaW5jbHVkZSB0aGUgYmFzZSBzeW1saW5rCisgICAgICAgICAgICAgICAgICAgIC8vIGRpcmVjdG9yeSBhcyByZXF1aXJlZCBzbyBhbGwgaXNvbGF0ZWQgZmlsZSB1cmlzIHVuZGVyIHRoaXMgZGlyZWN0b3J5IGFyZQorICAgICAgICAgICAgICAgICAgICAvLyBfbm90XyByZW1vdmVkIChpLmUuIHZlcmlmaWNhdGlvbiBpcyBub3QgcGVyZm9ybWVkKS4KKyAgICAgICAgICAgICAgICAgICAgZmlsZXNSZXF1aXJlZEJ5TWRkLmFkZCgKKyAgICAgICAgICAgICAgICAgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0QmFzZURvd25sb2FkU3ltbGlua0RpcmVjdG9yeShjb250ZXh0LCBpbnN0YW5jZUlkKSk7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMud2hlbkFsbENvbXBsZXRlKGZ1dHVyZXMpCisgICAgICAgICAgICAgICAgICAgICAgLmNhbGwoCisgICAgICAgICAgICAgICAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVtb3ZlZE1ldGFkYXRhQ291bnQuZ2V0KCkgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudExvZ2dlci5sb2dNZGREYXRhRG93bmxvYWRGaWxlRXhwaXJhdGlvbkV2ZW50KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIHJlbW92ZWRNZXRhZGF0YUNvdW50LmdldCgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXJpIHBhcmVudERpcmVjdG9yeSA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0QmFzZURvd25sb2FkRGlyZWN0b3J5KGNvbnRleHQsIGluc3RhbmNlSWQpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCByZWxlYXNlZEZpbGVzID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsZWFzZVVuYWNjb3VudGVkQW5kcm9pZFNoYXJlZEZpbGVzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kcm9pZFNoYXJlZEZpbGVzVG9CZVJlbGVhc2VkKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogVG90YWwgJWQgdW5hY2NvdW50ZWQgZmlsZSByZWxlYXNlZC4gIiwgVEFHLCByZWxlYXNlZEZpbGVzKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB1bmFjY291bnRlZEZpbGVDb3VudCA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZVVuYWNjb3VudGVkRmlsZXNSZWN1cnNpdmVseSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudERpcmVjdG9yeSwgZmlsZXNSZXF1aXJlZEJ5TWRkKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogVG90YWwgJWQgdW5hY2NvdW50ZWQgZmlsZSBkZWxldGVkLiAiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUQUcsIHVuYWNjb3VudGVkRmlsZUNvdW50KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodW5hY2NvdW50ZWRGaWxlQ291bnQgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudExvZ2dlci5sb2dNZGREYXRhRG93bmxvYWRGaWxlRXhwaXJhdGlvbkV2ZW50KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIHVuYWNjb3VudGVkRmlsZUNvdW50KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlbGVhc2VkRmlsZXMgPiAwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudExvZ2dlci5sb2dNZGREYXRhRG93bmxvYWRGaWxlRXhwaXJhdGlvbkV2ZW50KDAsIHJlbGVhc2VkRmlsZXMpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8U2V0PE5ld0ZpbGVLZXk+PiBnZXRGaWxlS2V5c1JlZmVyZW5jZWRCeUFueUdyb3VwKCkgeworICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCksCisgICAgICAgIGFsbEdyb3Vwc0J5S2V5IC0+IHsKKyAgICAgICAgICBTZXQ8TmV3RmlsZUtleT4gZmlsZUtleXNSZWZlcmVuY2VkQnlBbnlHcm91cCA9IG5ldyBIYXNoU2V0PD4oKTsKKyAgICAgICAgICBMaXN0PERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZGF0YUZpbGVHcm91cHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgICBmb3IgKFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZGF0YUZpbGVHcm91cFBhaXIgOiBhbGxHcm91cHNCeUtleSkgeworICAgICAgICAgICAgZGF0YUZpbGVHcm91cHMuYWRkKGRhdGFGaWxlR3JvdXBQYWlyLnNlY29uZCk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm0oCisgICAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxTdGFsZUdyb3VwcygpLAorICAgICAgICAgICAgICBzdGFsZUdyb3VwcyAtPiB7CisgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cHMuYWRkQWxsKHN0YWxlR3JvdXBzKTsKKyAgICAgICAgICAgICAgICBmb3IgKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwIDogZGF0YUZpbGVHcm91cHMpIHsKKyAgICAgICAgICAgICAgICAgIGZvciAoRGF0YUZpbGUgZGF0YUZpbGUgOiBkYXRhRmlsZUdyb3VwLmdldEZpbGVMaXN0KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgZmlsZUtleXNSZWZlcmVuY2VkQnlBbnlHcm91cC5hZGQoCisgICAgICAgICAgICAgICAgICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZUZvckN1cnJlbnRWZXJzaW9uKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRBbGxvd2VkUmVhZGVyc0VudW0oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWxlbnRGZWVkYmFjaykpOworICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gZmlsZUtleXNSZWZlcmVuY2VkQnlBbnlHcm91cDsKKyAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIEdldCBhbGwgaXNvbGF0ZWQgZmlsZSB1cmlzIHRoYXQgYXJlIHJlZmVyZW5jZWQgYnkgYW55IGZyZXNoIGdyb3Vwcy4KKyAgICoKKyAgICogPHA+RnJlc2ggZ3JvdXBzIGFyZSBhY3RpdmUvcGVuZGluZyBncm91cHMuIElzb2xhdGVkIGZpbGUgdXJpcyBhcmUgZXhwZWN0ZWQgd2hlbiAxKSB0aGUgT1MKKyAgICogdmVyc2lvbiBzdXBwb3J0cyBzeW1saW5rcyAoYXQgbGVhc3QgTG9sbGlwb3AgKDIxKSk7IGFuZCAyKSBUaGUgZmlsZSBncm91cCBlbmFibGVzIGZpbGUKKyAgICogaXNvbGF0aW9uLgorICAgKgorICAgKiBAcmV0dXJuIExpc3RlbmFibGVGdXR1cmUgdGhhdCByZXNvbHZlcyB3aXRoIExpc3Qgb2YgaXNvbGF0ZWQgdXJpcyB0aGF0IGFyZSByZWZlcmVuY2VkIGJ5CisgICAqICAgICBhY3RpdmUvcGVuZGluZyBncm91cHMKKyAgICovCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxMaXN0PFVyaT4+IGdldElzb2xhdGVkRmlsZVVyaXNSZWZlcmVuY2VkQnlGcmVzaEdyb3VwcygpIHsKKyAgICBMaXN0PFVyaT4gcmVmZXJlbmNlZElzb2xhdGVkRmlsZVVyaXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtKAorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSwKKyAgICAgICAgZ3JvdXBLZXlBbmRHcm91cExpc3QgLT4geworICAgICAgICAgIGZvciAoUGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPiBncm91cEtleUFuZEdyb3VwIDogZ3JvdXBLZXlBbmRHcm91cExpc3QpIHsKKyAgICAgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmcmVzaEdyb3VwID0gZ3JvdXBLZXlBbmRHcm91cC5zZWNvbmQ7CisgICAgICAgICAgICAvLyBTa2lwIGFueSBncm91cHMgdGhhdCBkb24ndCBzdXBwb3J0IGlzb2xhdGVkIHN0cnVjdHVyZXMKKyAgICAgICAgICAgIGlmICghRmlsZUdyb3VwVXRpbC5pc0lzb2xhdGVkU3RydWN0dXJlQWxsb3dlZChmcmVzaEdyb3VwKSkgeworICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLy8gQWRkIHRoZSBleHBlY3RlZCBpc29sYXRlZCBmaWxlIHVyaXMgZm9yIGVhY2ggZmlsZQorICAgICAgICAgICAgZm9yIChEYXRhRmlsZSBmaWxlIDogZnJlc2hHcm91cC5nZXRGaWxlTGlzdCgpKSB7CisgICAgICAgICAgICAgIFVyaSBpc29sYXRlZEZpbGVVcmkgPQorICAgICAgICAgICAgICAgICAgRmlsZUdyb3VwVXRpbC5nZXRJc29sYXRlZEZpbGVVcmkoY29udGV4dCwgaW5zdGFuY2VJZCwgZmlsZSwgZnJlc2hHcm91cCk7CisgICAgICAgICAgICAgIHJlZmVyZW5jZWRJc29sYXRlZEZpbGVVcmlzLmFkZChpc29sYXRlZEZpbGVVcmkpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKworICAgICAgICAgIHJldHVybiByZWZlcmVuY2VkSXNvbGF0ZWRGaWxlVXJpczsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIGludCByZWxlYXNlVW5hY2NvdW50ZWRBbmRyb2lkU2hhcmVkRmlsZXMoTGlzdDxVcmk+IGFuZHJvaWRTaGFyZWRGaWxlc1RvQmVSZWxlYXNlZCkgeworICAgIGludCByZWxlYXNlZEZpbGVzID0gMDsKKyAgICBmb3IgKFVyaSBzaGFyZWRGaWxlIDogYW5kcm9pZFNoYXJlZEZpbGVzVG9CZVJlbGVhc2VkKSB7CisgICAgICB0cnkgeworICAgICAgICBmaWxlU3RvcmFnZS5kZWxldGVGaWxlKHNoYXJlZEZpbGUpOworICAgICAgICByZWxlYXNlZEZpbGVzICs9IDE7CisgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICBMb2dVdGlsLmUoZSwgIiVzOiBGYWlsZWQgdG8gcmVsZWFzZSB1bmFjY291bnRlZCBmaWxlISIsIFRBRyk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiByZWxlYXNlZEZpbGVzOworICB9CisKKyAgLy8gVE9ETyhiLzExOTYyMjUwNCkgRml4IG51bGxuZXNzIHZpb2xhdGlvbjogaW5jb21wYXRpYmxlIHR5cGVzIGluIGFyZ3VtZW50LgorICBAU3VwcHJlc3NXYXJuaW5ncygibnVsbG5lc3M6YXJndW1lbnQiKQorICBwcml2YXRlIGludCBkZWxldGVVbmFjY291bnRlZEZpbGVzUmVjdXJzaXZlbHkoVXJpIGRpcmVjdG9yeSwgTGlzdDxVcmk+IGZpbGVzUmVxdWlyZWRCeU1kZCkgeworICAgIGludCB1bmFjY291bnRlZEZpbGVDb3VudCA9IDA7CisgICAgdHJ5IHsKKyAgICAgIGlmICghZmlsZVN0b3JhZ2UuZXhpc3RzKGRpcmVjdG9yeSkpIHsKKyAgICAgICAgcmV0dXJuIHVuYWNjb3VudGVkRmlsZUNvdW50OworICAgICAgfQorCisgICAgICBmb3IgKFVyaSB1cmkgOiBmaWxlU3RvcmFnZS5jaGlsZHJlbihkaXJlY3RvcnkpKSB7CisgICAgICAgIHRyeSB7CisgICAgICAgICAgaWYgKGlzQ29udGFpbmVkSW5VcmlMaXN0KHVyaSwgZmlsZXNSZXF1aXJlZEJ5TWRkKSkgeworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChmaWxlU3RvcmFnZS5pc0RpcmVjdG9yeSh1cmkpKSB7CisgICAgICAgICAgICB1bmFjY291bnRlZEZpbGVDb3VudCArPSBkZWxldGVVbmFjY291bnRlZEZpbGVzUmVjdXJzaXZlbHkodXJpLCBmaWxlc1JlcXVpcmVkQnlNZGQpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMb2dVdGlsLmQoIiVzOiBEZWxldGVkIHVuYWNjb3VudGVkIGZpbGUgd2l0aCB1cmkgJXMhIiwgVEFHLCB1cmkuZ2V0UGF0aCgpKTsKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLmRlbGV0ZUZpbGUodXJpKTsKKyAgICAgICAgICAgIHVuYWNjb3VudGVkRmlsZUNvdW50Kys7CisgICAgICAgICAgfQorCisgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICBldmVudExvZ2dlci5sb2dFdmVudFNhbXBsZWQoMCk7CisgICAgICAgICAgTG9nVXRpbC5lKGUsICIlczogRmFpbGVkIHRvIGRlbGV0ZSB1bmFjY291bnRlZCBmaWxlISIsIFRBRyk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAgIExvZ1V0aWwuZShlLCAiJXM6IEZhaWxlZCB0byBkZWxldGUgdW5hY2NvdW50ZWQgZmlsZSEiLCBUQUcpOworICAgIH0KKyAgICByZXR1cm4gdW5hY2NvdW50ZWRGaWxlQ291bnQ7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB0cnVlIGlmIGdpdmVuIHVyaSBpcyB3aXRoaW4gdGhlIGdpdmVuIHVyaSBsaXN0IG9yIGlzIGEgY2hpbGQgb2YgYW55IHVyaSBpbiB0aGUgbGlzdC4KKyAgICoKKyAgICogPHA+VXNlZCBieSBNREQncyB1bmFjY291bnRlZCBmaWxlIGxvZ2ljIHRvIGZpbHRlciBvdXQgZmlsZXMgdGhhdCBzaG91bGRuJ3QgYmUgZGVsZXRlZC4gVGhpcyBpcworICAgKiB1c2VkIGluIHR3byBjYXNlczoKKyAgICoKKyAgICogPHVsPgorICAgKiAgIDxsaT5maWxlcyByZWZlcnJlZCBieSBhbnkgYWN0aXZlIE1ERCBmaWxlcy4gVGhpcyBpbmNsdWRlcyBpbnRlcm5hbCBNREQgZmlsZXMsIHN1Y2ggYXMgZGVsdGEKKyAgICogICAgICAgZmlsZXMgb2YgYSBmdWxsIGFjdGl2ZSBmaWxlLCB3aGljaCBhcmUgc3RvcmVkIHVzaW5nIHRoZSBhY3RpdmUgZmlsZSBuYW1lIGFuZCBhIGNoZWNrc3VtCisgICAqICAgICAgIHN1ZmZpeC4KKyAgICogICA8bGk+c3ltbGlua3MgY3JlYXRlZCBmb3IgYW4gaXNvbGF0ZWQgZmlsZSBzdHJ1Y3R1cmUuIFRoZXNlIHN5bWxpbmtzIHdpbGwgcmVmZXJlbmNlIGFjdGl2ZQorICAgKiAgICAgICBmaWxlcyBhbmQgdGhlaXIgbGlmZWN5Y2xlIGlzIG1hbmFnZWQgb24gdGhlIGZpbGUgZ3JvdXAgbGV2ZWwsIHJhdGhlciB0aGFuIGFzIGluZGl2aWR1YWwKKyAgICogICAgICAgZmlsZXMuCisgICAqIDwvdWw+CisgICAqLworICBwcml2YXRlIGJvb2xlYW4gaXNDb250YWluZWRJblVyaUxpc3QoVXJpIHVyaSwgTGlzdDxVcmk+IHVyaUxpc3QpIHsKKyAgICBmb3IgKFVyaSBhY3RpdmVVcmkgOiB1cmlMaXN0KSB7CisgICAgICBpZiAodXJpLnRvU3RyaW5nKCkuc3RhcnRzV2l0aChhY3RpdmVVcmkudG9TdHJpbmcoKSkpIHsKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9FeHBpcmVkRmlsZUdyb3VwRXhjZXB0aW9uLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0V4cGlyZWRGaWxlR3JvdXBFeGNlcHRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZDdlY2ZmCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9FeHBpcmVkRmlsZUdyb3VwRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwxOSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWw7CisKKy8qKiBUaHJvd24gd2hlbiB0cnlpbmcgdG8gYWRkIGEgRmlsZSBHcm91cCB0aGF0IGhhcyBhbHJlYWR5IGV4cGlyZWQuICovCitwdWJsaWMgY2xhc3MgRXhwaXJlZEZpbGVHcm91cEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7fQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9GaWxlR3JvdXBNYW5hZ2VyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0ZpbGVHcm91cE1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZWM2ZWNhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9GaWxlR3JvdXBNYW5hZ2VyLmphdmEKQEAgLTAsMCArMSwyOTQ0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlRyYWNlUHJvcGFnYXRpb24ucHJvcGFnYXRlQXN5bmNGdW5jdGlvbjsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24uYmFzZS5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmU7CitpbXBvcnQgc3RhdGljIGphdmEubGFuZy5NYXRoLm1heDsKKworaW1wb3J0IGFuZHJvaWQuYWNjb3VudHMuQWNjb3VudDsKK2ltcG9ydCBhbmRyb2lkLmFubm90YXRpb24uVGFyZ2V0QXBpOworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5wbS5QYWNrYWdlTWFuYWdlci5OYW1lTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQuVkVSU0lPTjsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkLlZFUlNJT05fQ09ERVM7CitpbXBvcnQgYW5kcm9pZC50ZXh0LlRleHRVdGlsczsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBhbmRyb2lkeC5hbm5vdGF0aW9uLlJlcXVpcmVzQXBpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkFjY291bnRTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuQWdncmVnYXRlRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uLkRvd25sb2FkUmVzdWx0Q29kZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GaWxlU291cmNlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkZsYWdzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlNpbGVudEZlZWRiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlRpbWVTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuYWNjb3VudC5BY2NvdW50VXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5hbm5vdGF0aW9ucy5JbnN0YW5jZUlkOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5hbm5vdGF0aW9ucy5TZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmV4cGVyaW1lbnRhdGlvbi5Eb3dubG9hZFN0YWdlTWFuYWdlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkRvd25sb2FkU3RhdGVMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5FdmVudExvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5BbmRyb2lkU2hhcmluZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5BbmRyb2lkU2hhcmluZ1V0aWwuQW5kcm9pZFNoYXJpbmdFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5EaXJlY3RvcnlVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuRmlsZUdyb3VwVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLlN5bWxpbmtVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRyYWNpbmcuUHJvcGFnYXRlZEZsdWVudEZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlByb3BhZ2F0ZWRGdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuYXV0by52YWx1ZS5BdXRvVmFsdWU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5GdW5jdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuUHJlY29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkNvbXBhcmlzb25DaGFpbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVNYXA7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVTZXQ7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5NYXBzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Bc3luY0Z1bmN0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVDYWxsYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmVycm9ycHJvbmUuYW5ub3RhdGlvbnMuQ2hlY2tSZXR1cm5WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZS5BbmRyb2lkU2hhcmluZ1R5cGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwQm9va2tlZXBpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwSW50ZXJuYWw7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Eb3dubG9hZENvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Eb3dubG9hZENvbmRpdGlvbnMuQWN0aXZhdGluZ0NvbmRpdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VOZXR3b3JrUG9saWN5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRmlsZVN0YXR1czsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkdyb3VwS2V5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uR3JvdXBLZXlQcm9wZXJ0aWVzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uTmV3RmlsZUtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLlNoYXJlZEZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5Bbnk7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljUmVmZXJlbmNlOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CitpbXBvcnQgamF2YXguaW5qZWN0LkluamVjdDsKK2ltcG9ydCBvcmcuY2hlY2tlcmZyYW1ld29yay5jaGVja2VyLm51bGxuZXNzLmNvbXBhdHF1YWwuTnVsbGFibGVUeXBlOworCisvKioKKyAqIEtlZXBzIHRyYWNrIG9mIHBlbmRpbmcgZ3JvdXBzIHRvIGRvd25sb2FkIGFuZCBzdG9yZXMgdGhlIGRvd25sb2FkZWQgZ3JvdXBzIGZvciByZXRyaWV2YWwuIEl0J3MKKyAqIG5vdCB0aHJlYWQgc2FmZS4gQ3VycmVudGx5IGl0IHdvcmtzIGJ5IGJlaW5nIGNhbGxlZCBmcm9tIGEgc2luZ2xlIHRocmVhZCBleGVjdXRvci4KKyAqCisgKiA8cD5BbHNvIHByb3ZpZGVzIG1ldGhvZHMgdG8gcmVnaXN0ZXIgYW5kIHZlcmlmeSBkb3dubG9hZCBjb21wbGV0ZSBmb3IgYWxsIHBlbmRpbmcgZG93bmxvYWRzLgorICovCitAQ2hlY2tSZXR1cm5WYWx1ZQorcHVibGljIGNsYXNzIEZpbGVHcm91cE1hbmFnZXIgeworCisgIC8qKiBUaGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgZ3JvdXAuICovCisgIHB1YmxpYyBlbnVtIEdyb3VwRG93bmxvYWRTdGF0dXMgeworICAgIC8qKiBBdCBsZWFzdCBvbmUgZmlsZSBoYXMgbm90IGRvd25sb2FkZWQgZnVsbHksIGJ1dCBubyBmaWxlIGRvd25sb2FkIGhhcyBmYWlsZWQuICovCisgICAgUEVORElORywKKworICAgIC8qKiBBbGwgZmlsZXMgaGF2ZSBzdWNjZXNzZnVsbHkgZG93bmxvYWRlZCBhbmQgc2hvdWxkIG5vdyBiZSBmdWxseSBhdmFpbGFibGUuICovCisgICAgRE9XTkxPQURFRCwKKworICAgIC8qKiBUaGUgZG93bmxvYWQgb2YgYXQgbGVhc3Qgb25lIGZpbGUgZmFpbGVkLiAqLworICAgIEZBSUxFRCwKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiRmlsZUdyb3VwTWFuYWdlciI7CisKKyAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisgIHByaXZhdGUgZmluYWwgRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXI7CisgIHByaXZhdGUgZmluYWwgU2lsZW50RmVlZGJhY2sgc2lsZW50RmVlZGJhY2s7CisgIHByaXZhdGUgZmluYWwgRmlsZUdyb3Vwc01ldGFkYXRhIGZpbGVHcm91cHNNZXRhZGF0YTsKKyAgcHJpdmF0ZSBmaW5hbCBTaGFyZWRGaWxlTWFuYWdlciBzaGFyZWRGaWxlTWFuYWdlcjsKKyAgcHJpdmF0ZSBmaW5hbCBUaW1lU291cmNlIHRpbWVTb3VyY2U7CisgIHByaXZhdGUgZmluYWwgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxBY2NvdW50U291cmNlPiBhY2NvdW50U291cmNlT3B0aW9uYWw7CisgIHByaXZhdGUgZmluYWwgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQ7CisgIHByaXZhdGUgZmluYWwgRG93bmxvYWRTdGFnZU1hbmFnZXIgZG93bmxvYWRTdGFnZU1hbmFnZXI7CisgIHByaXZhdGUgZmluYWwgRmxhZ3MgZmxhZ3M7CisKKyAgQEluamVjdAorICBwdWJsaWMgRmlsZUdyb3VwTWFuYWdlcigKKyAgICAgIEBBcHBsaWNhdGlvbkNvbnRleHQgQ29udGV4dCBjb250ZXh0LAorICAgICAgRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXIsCisgICAgICBTaWxlbnRGZWVkYmFjayBzaWxlbnRGZWVkYmFjaywKKyAgICAgIEZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGEsCisgICAgICBTaGFyZWRGaWxlTWFuYWdlciBzaGFyZWRGaWxlTWFuYWdlciwKKyAgICAgIFRpbWVTb3VyY2UgdGltZVNvdXJjZSwKKyAgICAgIE9wdGlvbmFsPEFjY291bnRTb3VyY2U+IGFjY291bnRTb3VyY2VPcHRpb25hbCwKKyAgICAgIEBTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IsCisgICAgICBASW5zdGFuY2VJZCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLAorICAgICAgRG93bmxvYWRTdGFnZU1hbmFnZXIgZG93bmxvYWRTdGFnZU1hbmFnZXIsCisgICAgICBGbGFncyBmbGFncykgeworICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CisgICAgdGhpcy5ldmVudExvZ2dlciA9IGV2ZW50TG9nZ2VyOworICAgIHRoaXMuc2lsZW50RmVlZGJhY2sgPSBzaWxlbnRGZWVkYmFjazsKKyAgICB0aGlzLmZpbGVHcm91cHNNZXRhZGF0YSA9IGZpbGVHcm91cHNNZXRhZGF0YTsKKyAgICB0aGlzLnNoYXJlZEZpbGVNYW5hZ2VyID0gc2hhcmVkRmlsZU1hbmFnZXI7CisgICAgdGhpcy50aW1lU291cmNlID0gdGltZVNvdXJjZTsKKyAgICB0aGlzLmFjY291bnRTb3VyY2VPcHRpb25hbCA9IGFjY291bnRTb3VyY2VPcHRpb25hbDsKKyAgICB0aGlzLnNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgPSBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworICAgIHRoaXMuaW5zdGFuY2VJZCA9IGluc3RhbmNlSWQ7CisgICAgdGhpcy5maWxlU3RvcmFnZSA9IGZpbGVTdG9yYWdlOworICAgIHRoaXMuZG93bmxvYWRTdGFnZU1hbmFnZXIgPSBkb3dubG9hZFN0YWdlTWFuYWdlcjsKKyAgICB0aGlzLmZsYWdzID0gZmxhZ3M7CisgIH0KKworICAvKioKKyAgICogQWRkcyB0aGUgZ2l2ZW4gZGF0YSBmaWxlIGdyb3VwIGZvciBkb3dubG9hZC4KKyAgICoKKyAgICogPHA+Q2FsbGluZyB0aGlzIG1ldGhvZCB3aXRoIHRoZSBleGFjdCBzYW1lIGZpbGUgZ3JvdXAgbXVsdGlwbGUgdGltZXMgaXMgYSBubyBvcC4KKyAgICoKKyAgICogQHBhcmFtIGdyb3VwS2V5IFRoZSBrZXkgZm9yIHRoZSBncm91cC4KKyAgICogQHBhcmFtIHJlY2VpdmVkR3JvdXAgVGhlIEZpbGUgZ3JvdXAgdGhhdCBuZWVkcyB0byBiZSBkb3dubG9hZGVkLgorICAgKiBAcmV0dXJuIEEgZnV0dXJlIHRoYXQgcmVzb2x2ZXMgdG8gdHJ1ZSBpZiB0aGUgcmVjZWl2ZWQgZ3JvdXAgd2FzIG5ldy91cGdyYWRlIGFuZCB3YXMKKyAgICogICAgIHN1Y2Nlc3NmdWxseSBhZGRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgKi8KKyAgLy8gVE9ETyhiLzEyNDA3Mjc1NCk6IENoYW5nZSB0byBwYWNrYWdlIHByaXZhdGUgb25jZSBhbGwgY29kZSBpcyByZWZhY3RvcmVkLgorICBAU3VwcHJlc3NXYXJuaW5ncygibnVsbG5lc3MiKQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiBhZGRHcm91cEZvckRvd25sb2FkKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbCByZWNlaXZlZEdyb3VwKQorICAgICAgdGhyb3dzIEV4cGlyZWRGaWxlR3JvdXBFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBVbmluc3RhbGxlZEFwcEV4Y2VwdGlvbiwKKyAgICAgICAgICBBY3RpdmF0aW9uUmVxdWlyZWRGb3JHcm91cEV4Y2VwdGlvbiB7CisgICAgaWYgKEZpbGVHcm91cFV0aWwuaXNBY3RpdmVHcm91cEV4cGlyZWQocmVjZWl2ZWRHcm91cCwgdGltZVNvdXJjZSkpIHsKKyAgICAgIExvZ1V0aWwuZSgiJXM6IFRyeWluZyB0byBhZGQgZXhwaXJlZCBncm91cCAlcy4iLCBUQUcsIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpKTsKKyAgICAgIGxvZ0V2ZW50V2l0aERhdGFGaWxlR3JvdXAoMCwgZXZlbnRMb2dnZXIsIHJlY2VpdmVkR3JvdXApOworICAgICAgdGhyb3cgbmV3IEV4cGlyZWRGaWxlR3JvdXBFeGNlcHRpb24oKTsKKyAgICB9CisgICAgaWYgKCFpc0FwcEluc3RhbGxlZChncm91cEtleS5nZXRPd25lclBhY2thZ2UoKSkpIHsKKyAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAiJXM6IFRyeWluZyB0byBhZGQgZ3JvdXAgJXMgZm9yIHVuaW5zdGFsbGVkIGFwcCAlcy4iLAorICAgICAgICAgIFRBRywgZ3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCksIGdyb3VwS2V5LmdldE93bmVyUGFja2FnZSgpKTsKKyAgICAgIGxvZ0V2ZW50V2l0aERhdGFGaWxlR3JvdXAoMCwgZXZlbnRMb2dnZXIsIHJlY2VpdmVkR3JvdXApOworICAgICAgdGhyb3cgbmV3IFVuaW5zdGFsbGVkQXBwRXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiByZXN1bHRGdXR1cmUgPSBpbW1lZGlhdGVGdXR1cmUobnVsbCk7CisgICAgaWYgKGZsYWdzLmVuYWJsZURlbGF5ZWREb3dubG9hZCgpCisgICAgICAgICYmIHJlY2VpdmVkR3JvdXAuZ2V0RG93bmxvYWRDb25kaXRpb25zKCkuZ2V0QWN0aXZhdGluZ0NvbmRpdGlvbigpCisgICAgICAgICAgICA9PSBBY3RpdmF0aW5nQ29uZGl0aW9uLkRFVklDRV9BQ1RJVkFURUQpIHsKKworICAgICAgcmVzdWx0RnV0dXJlID0KKyAgICAgICAgICB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkR3JvdXBLZXlQcm9wZXJ0aWVzKGdyb3VwS2V5KSwKKyAgICAgICAgICAgICAgZ3JvdXBLZXlQcm9wZXJ0aWVzIC0+IHsKKyAgICAgICAgICAgICAgICAvLyBJdCBzaG91bGRuJ3QgbWFrZSBhIGRpZmZlcmVuY2UgaWYgd2UgZm91bmQgYW4gZXhpc3RpbmcgdmFsdWUgb3Igbm90LgorICAgICAgICAgICAgICAgIGlmIChncm91cEtleVByb3BlcnRpZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgZ3JvdXBLZXlQcm9wZXJ0aWVzID0gR3JvdXBLZXlQcm9wZXJ0aWVzLmdldERlZmF1bHRJbnN0YW5jZSgpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmICghZ3JvdXBLZXlQcm9wZXJ0aWVzLmdldEFjdGl2YXRlZE9uRGV2aWNlKCkpIHsKKyAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZCgKKyAgICAgICAgICAgICAgICAgICAgICAiJXM6IFRyeWluZyB0byBhZGQgZ3JvdXAgJXMgdGhhdCByZXF1aXJlcyBhY3RpdmF0aW9uICVzLiIsCisgICAgICAgICAgICAgICAgICAgICAgVEFHLCBncm91cEtleS5nZXRHcm91cE5hbWUoKSwgZ3JvdXBLZXkuZ2V0T3duZXJQYWNrYWdlKCkpOworCisgICAgICAgICAgICAgICAgICBsb2dFdmVudFdpdGhEYXRhRmlsZUdyb3VwKDAsIGV2ZW50TG9nZ2VyLCByZWNlaXZlZEdyb3VwKTsKKworICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFjdGl2YXRpb25SZXF1aXJlZEZvckdyb3VwRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUobnVsbCk7CisgICAgICAgICAgICAgIH0pOworICAgIH0KKworICAgIHJldHVybiBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlLmZyb20ocmVzdWx0RnV0dXJlKQorICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICB2b2lkQXJnIC0+IGlzQWRkZWRHcm91cER1cGxpY2F0ZShncm91cEtleSwgcmVjZWl2ZWRHcm91cCksIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIGlzRHVwbGljYXRlIC0+IHsKKyAgICAgICAgICAgICAgaWYgKGlzRHVwbGljYXRlKSB7CisgICAgICAgICAgICAgICAgTG9nVXRpbC5kKAorICAgICAgICAgICAgICAgICAgICAiJXM6IFJlY2VpdmVkIGR1cGxpY2F0ZSBjb25maWcgZm9yIGdyb3VwOiAlcyIsIFRBRywgZ3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUoZmFsc2UpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICBtYXliZVNldEdyb3VwTmV3RmlsZXNSZWNlaXZlZFRpbWVzdGFtcChncm91cEtleSwgcmVjZWl2ZWRHcm91cCksCisgICAgICAgICAgICAgICAgICByZWNlaXZlZEdyb3VwQ29weSAtPiB7CisgICAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZCgKKyAgICAgICAgICAgICAgICAgICAgICAgICIlczogUmVjZWl2ZWQgbmV3IGNvbmZpZyBmb3IgZ3JvdXA6ICVzIiwgVEFHLCBncm91cEtleS5nZXRHcm91cE5hbWUoKSk7CisKKyAgICAgICAgICAgICAgICAgICAgbG9nRXZlbnRXaXRoRGF0YUZpbGVHcm91cCgwLCBldmVudExvZ2dlciwgcmVjZWl2ZWRHcm91cENvcHkpOworCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmVHcm91cChyZWNlaXZlZEdyb3VwQ29weSksCisgICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmVkIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzdWJzY3JpYmVkKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJTdWJzY3JpYmluZyB0byBncm91cCBmYWlsZWQiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE8oYi8xNjAxNjQwMzIpOiBpZiB0aGUgRmlsZSBHcm91cCBoYXMgbmV3IFN5bmNJZCwgY2xlYXIgdGhlIG9sZAorICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzeW5jLgorICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPKGIvMTYwMTY0MDMyKTogdHJpZ2dlclN5bmMgaW4gZGFpbHkgbWFpbnRlbmFuY2UgZm9yIG5vdAorICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21wbGV0ZWQgZ3JvdXBzLgorICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXcml0ZSB0byBNZXRhZGF0YSB0aGVuIHNjaGVkdWxlIHRhc2sgdmlhIFNQRS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlVXBkYXRlZEdyb3VwVG9NZXRhZGF0YShncm91cEtleSwgcmVjZWl2ZWRHcm91cENvcHkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWRBcmcpIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZSh0cnVlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgIH0sCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiB3cml0ZVVwZGF0ZWRHcm91cFRvTWV0YWRhdGEoCisgICAgICBHcm91cEtleSBncm91cEtleSwgTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwSW50ZXJuYWwgcmVjZWl2ZWRHcm91cENvcHkpIHsKKyAgICAvLyBXcml0ZSB0aGUgcmVjZWl2ZWQgZ3JvdXAgYXMgYSBwZW5kaW5nIGdyb3VwLiBJZiB0aGVyZSB3YXMgYQorICAgIC8vIHBlbmRpbmcgZ3JvdXAgYWxyZWFkeSBwcmVzZW50LCBpdCB3aWxsIGJlIG92ZXJ3cml0dGVuIGFuZCBhbnkKKyAgICAvLyBmaWxlcyB3aWxsIGJlIGdhcmJhZ2UgY29sbGVjdGVkIGxhdGVyLgorICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleSA9IGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPEBOdWxsYWJsZVR5cGUgRGF0YUZpbGVHcm91cEludGVybmFsPiB0b0JlT3ZlcndyaXR0ZW5QZW5kaW5nR3JvdXBGdXR1cmUgPQorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChwZW5kaW5nR3JvdXBLZXkpOworCisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmUuZnJvbSh0b0JlT3ZlcndyaXR0ZW5QZW5kaW5nR3JvdXBGdXR1cmUpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIG51bGxWb2lkIC0+IGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZShwZW5kaW5nR3JvdXBLZXksIHJlY2VpdmVkR3JvdXBDb3B5KSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIHdyaXRlU3VjY2VzcyAtPiB7CisgICAgICAgICAgICAgIGlmICghd3JpdGVTdWNjZXNzKSB7CisgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgICAgIG5ldyBJT0V4Y2VwdGlvbigiRmFpbGVkIHRvIGNvbW1pdCBuZXcgZ3JvdXAgbWV0YWRhdGEgdG8gZGlzay4iKSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgIH0sCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICBudWxsVm9pZCAtPiBkb3dubG9hZFN0YWdlTWFuYWdlci51cGRhdGVFeHBlcmltZW50SWRzKHJlY2VpdmVkR3JvdXBDb3B5LmdldEdyb3VwTmFtZSgpKSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIG51bGxWb2lkIC0+IHsKKyAgICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBtYWtlIHN1cmUgdG8gY2xlYXIgdGhlIGV4cGVyaW1lbnQgaWRzIGZvciB0aGlzIGdyb3VwIGhlcmUsIHNpbmNlIGl0IHdpbGwKKyAgICAgICAgICAgICAgLy8gYmUgb3ZlcndyaXR0ZW4gYWZ0ZXJ3YXJkcy4KKyAgICAgICAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHRvQmVPdmVyd3JpdHRlblBlbmRpbmdHcm91cCA9CisgICAgICAgICAgICAgICAgICBGdXR1cmVzLmdldERvbmUodG9CZU92ZXJ3cml0dGVuUGVuZGluZ0dyb3VwRnV0dXJlKTsKKyAgICAgICAgICAgICAgaWYgKHRvQmVPdmVyd3JpdHRlblBlbmRpbmdHcm91cCAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGRvd25sb2FkU3RhZ2VNYW5hZ2VyLmNsZWFyRXhwZXJpbWVudElkc0ZvckJ1aWxkc0lmTm9uZUFjdGl2ZSgKKyAgICAgICAgICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZih0b0JlT3ZlcndyaXR0ZW5QZW5kaW5nR3JvdXApKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKioKKyAgICogUmVtb3ZlcyBkYXRhIGZpbGUgZ3JvdXAgd2l0aCB0aGUgZ2l2ZW4gZ3JvdXAga2V5LCBhbmQgY2FuY2VscyBhbnkgb25nb2luZyBkb3dubG9hZCBvZiB0aGUgZmlsZQorICAgKiBncm91cC4KKyAgICoKKyAgICogQHBhcmFtIGdyb3VwS2V5IFRoZSBrZXkgb2YgdGhlIGRhdGEgZmlsZSBncm91cCB0byBiZSByZW1vdmVkLgorICAgKiBAcGFyYW0gcGVuZGluZ09ubHkgSWYgdHJ1ZSwgb25seSByZW1vdmUgdGhlIHBlbmRpbmcgdmVyc2lvbiBvZiB0aGlzIGZpbGVncm91cC4KKyAgICogQHJldHVybiBMaXN0ZW5hYmxlRnV0dXJlIHRoYXQgbWF5IHRocm93IGFuIElPRXhjZXB0aW9uIGlmIHNvbWUgZXJyb3IgaXMgZW5jb3VudGVyZWQgd2hlbgorICAgKiAgICAgcmVtb3ZpbmcgZnJvbSBtZXRhZGF0YSBvciBhIFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uIGlmIHNvbWUgb2YgdGhlIHNoYXJlZCBmaWxlIG1ldGFkYXRhCisgICAqICAgICBpcyBtaXNzaW5nLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiByZW1vdmVGaWxlR3JvdXAoR3JvdXBLZXkgZ3JvdXBLZXksIGJvb2xlYW4gcGVuZGluZ09ubHkpCisgICAgICB0aHJvd3MgU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKKyAgICAvLyBSZW1vdmUgdGhlIHBlbmRpbmcgdmVyc2lvbiBmcm9tIG1ldGFkYXRhLgorICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleSA9IGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQocGVuZGluZ0dyb3VwS2V5KSwKKyAgICAgICAgcGVuZGluZ0ZpbGVHcm91cCAtPiB7CisgICAgICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiByZW1vdmVQZW5kaW5nR3JvdXBGdXR1cmUgPSBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgaWYgKHBlbmRpbmdGaWxlR3JvdXAgIT0gbnVsbCkgeworICAgICAgICAgICAgLy8gQ2xlYXIgU3luYyBSZWFzb24gYmVmb3JlIHJlbW92aW5nIHRoZSBmaWxlIGdyb3VwLgorICAgICAgICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjbGVhclN5bmNSZWFzb25GdXR1cmUgPSBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICByZW1vdmVQZW5kaW5nR3JvdXBGdXR1cmUgPQorICAgICAgICAgICAgICAgIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgY2xlYXJTeW5jUmVhc29uRnV0dXJlLAorICAgICAgICAgICAgICAgICAgICB2b2lkQXJnIC0+CisgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlbW92ZShwZW5kaW5nR3JvdXBLZXkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVN1Y2Nlc3MgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZW1vdmVTdWNjZXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogRmFpbGVkIHRvIHJlbW92ZSBwZW5kaW5nIHZlcnNpb24gZm9yIGdyb3VwOiAnJXMnOyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgYWNjb3VudDogJyVzJyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUQUcsIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpLCBncm91cEtleS5nZXRBY2NvdW50KCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudExvZ2dlci5sb2dFdmVudFNhbXBsZWQoMCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSU9FeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byByZW1vdmUgcGVuZGluZyBncm91cDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG93bmxvYWRTdGFnZU1hbmFnZXIuY2xlYXJFeHBlcmltZW50SWRzRm9yQnVpbGRzSWZOb25lQWN0aXZlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YocGVuZGluZ0ZpbGVHcm91cCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgcmVtb3ZlUGVuZGluZ0dyb3VwRnV0dXJlLAorICAgICAgICAgICAgICB2b2lkQXJnMCAtPiB7CisgICAgICAgICAgICAgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5ID0gZ3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZCh0cnVlKS5idWlsZCgpOworICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGRvd25sb2FkZWRHcm91cEtleSksCisgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkZWRGaWxlR3JvdXAgLT4geworICAgICAgICAgICAgICAgICAgICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVtb3ZlRG93bmxvYWRlZEdyb3VwRnV0dXJlID0gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICAgICAgICAgIGlmIChkb3dubG9hZGVkRmlsZUdyb3VwICE9IG51bGwgJiYgIXBlbmRpbmdPbmx5KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGRvd25sb2FkZWQgdmVyc2lvbiBmcm9tIG1ldGFkYXRhLgorICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRG93bmxvYWRlZEdyb3VwRnV0dXJlID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5yZW1vdmUoZG93bmxvYWRlZEdyb3VwS2V5KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlU3VjY2VzcyAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZW1vdmVTdWNjZXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBGYWlsZWQgdG8gcmVtb3ZlIHRoZSBkb3dubG9hZGVkIHZlcnNpb24gZm9yIGdyb3VwOiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICclcyc7IGFjY291bnQ6ICclcyciLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRBRywgZ3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCksIGdyb3VwS2V5LmdldEFjY291bnQoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudExvZ2dlci5sb2dFdmVudFNhbXBsZWQoMCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJT0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byByZW1vdmUgZG93bmxvYWRlZCBncm91cDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBncm91cEtleS5nZXRHcm91cE5hbWUoKSkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIGRvd25sb2FkZWQgdmVyc2lvbiB0byBzdGFsZS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEuYWRkU3RhbGVHcm91cChkb3dubG9hZGVkRmlsZUdyb3VwKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3VjY2VzcyAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhZGRTdWNjZXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBGYWlsZWQgdG8gYWRkIHRvIHN0YWxlIGZvciBncm91cDogJyVzJzsiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBhY2NvdW50OiAnJXMnIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUQUcsIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpLCBncm91cEtleS5nZXRBY2NvdW50KCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSU9FeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gYWRkIGRvd25sb2FkZWQgZ3JvdXAgdG8gc3RhbGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZ3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvd25sb2FkU3RhZ2VNYW5hZ2VyLnVwZGF0ZUV4cGVyaW1lbnRJZHMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkZWRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRG93bmxvYWRlZEdyb3VwRnV0dXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkQXJnMSAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2FuY2VsIGFueSBvbmdvaW5nIGRvd25sb2FkIG9mIHRoZSBkYXRhIGZpbGVzIGluIHRoZSBmaWxlIGdyb3VwLCBpZgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBkYXRhIGZpbGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyBub3QgcmVmZXJlbmNlZCBieSBhbnkgZnJlc2ggZ3JvdXAuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBlbmRpbmdGaWxlR3JvdXAgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRGaWxlS2V5c1JlZmVyZW5jZWRCeUZyZXNoR3JvdXBzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmZXJlbmNlZEZpbGVLZXlzIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4gY2FuY2VsRG93bmxvYWRzRnV0dXJlcyA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKERhdGFGaWxlIGRhdGFGaWxlIDogcGVuZGluZ0ZpbGVHcm91cC5nZXRGaWxlTGlzdCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNraXAgc2lkZWxvYWRlZCBmaWxlcyAtLSB0aGV5IHdpbGwgbm90IGhhdmUgYSBwZW5kaW5nCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvd25sb2FkIGJ5IGRlZmluaXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEZpbGVHcm91cFV0aWwuaXNTaWRlbG9hZGVkRmlsZShkYXRhRmlsZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZSwgcGVuZGluZ0ZpbGVHcm91cC5nZXRBbGxvd2VkUmVhZGVyc0VudW0oKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENhbmNlbCB0aGUgb25nb2luZyBkb3dubG9hZCwgaWYgdGhlIGZpbGUgaXMgbm90IHJlZmVyZW5jZWQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnkgYW55IGZyZXNoIGZpbGUgZ3JvdXAuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcmVmZXJlbmNlZEZpbGVLZXlzLmNvbnRhaW5zKG5ld0ZpbGVLZXkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FuY2VsRG93bmxvYWRzRnV0dXJlcy5hZGQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyLmNhbmNlbERvd25sb2FkKG5ld0ZpbGVLZXkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLndoZW5BbGxDb21wbGV0ZShjYW5jZWxEb3dubG9hZHNGdXR1cmVzKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYWxsKCgpIC0+IG51bGwsIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICAgIH0pOworICAgICAgICB9KTsKKyAgfQorCisgIC8qKgorICAgKiBSZW1vdmVzIGRhdGEgZmlsZSBncm91cHMgd2l0aCBnaXZlbiBncm91cCBrZXlzIGFuZCBjYW5jZWxzIGFueSBvbmdvaW5nIGRvd25sb2FkcyBvZiB0aGUgZmlsZQorICAgKiBncm91cHMuCisgICAqCisgICAqIDxwPlRoZSBmb2xsb3dpbmcgc3RlcHMgYXJlIHBlcmZvcm1lZCBmb3IgZWFjaCBmaWxlIGdyb3VwIHRvIHJlbW92ZS4gSWYgYW55IHN0ZXAgZmFpbHMsIHRoZQorICAgKiBvcGVyYXRpb24gc3RvcHMgYW5kIGZhaWx1cmVzIGFyZSByZXR1cm5lZC4KKyAgICoKKyAgICogPG9sPgorICAgKiAgIDxsaT5DbGVhciBTUEUgU3luYyBSZWFzb25zIChpZiBhcHBsaWNhYmxlKSBhbmQgcmVtb3ZlIHBlbmRpbmcgZmlsZSBncm91cCBtZXRhZGF0YQorICAgKiAgIDxsaT5SZW1vdmUgZG93bmxvYWRlZCBmaWxlIGdyb3VwIG1ldGFkYXRhCisgICAqICAgPGxpPk1vdmUgYW55IHJlbW92ZWQgZmlsZSBncm91cHMgZnJvbSBkb3dubG9hZGVkIHRvIHN0YWxlCisgICAqICAgPGxpPlJlbW92ZSBhbnkgcGVuZGluZyBkb3dubG9hZHMgZm9yIGZpbGVzIG5vIGxvbmdlciByZWZlcmVuY2VkCisgICAqIDwvb2w+CisgICAqCisgICAqIEBwYXJhbSBncm91cEtleXMgS2V5cyBvZiB0aGUgRmlsZSBHcm91cHMgdG8gcmVtb3ZlCisgICAqIEByZXR1cm4gTGlzdGVuYWJsZUZ1dHVyZSB0aGF0IHJlc29sdmVzIHdoZW4gZmlsZSBncm91cHMgaGF2ZSBiZWVuIHJlbW92ZWQsIG9yIGZhaWxzIGlmIHVuYWJsZQorICAgKiAgICAgdG8gcmVtb3ZlIGZpbGUgZ3JvdXBzIGZyb20gbWV0YWRhdGEuCisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlbW92ZUZpbGVHcm91cHMoTGlzdDxHcm91cEtleT4gZ3JvdXBLZXlzKSB7CisgICAgLy8gVHJhY2sgUGVuZGluZyBhbmQgRG93bmxvYWRlZCBHcm91cCBLZXlzIHRvIHJlbW92ZQorICAgIE1hcDxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPiBwZW5kaW5nR3JvdXBzVG9SZW1vdmUgPQorICAgICAgICBNYXBzLm5ld0hhc2hNYXBXaXRoRXhwZWN0ZWRTaXplKGdyb3VwS2V5cy5zaXplKCkpOworICAgIE1hcDxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPiBkb3dubG9hZGVkR3JvdXBzVG9SZW1vdmUgPQorICAgICAgICBNYXBzLm5ld0hhc2hNYXBXaXRoRXhwZWN0ZWRTaXplKGdyb3VwS2V5cy5zaXplKCkpOworCisgICAgLy8gVHJhY2sgUGVuZGluZyBGaWxlIEtleXMgdGhhdCBzaG91bGQgYmUgY2FuY2VsZWQKKyAgICBTZXQ8TmV3RmlsZUtleT4gcGVuZGluZ0ZpbGVLZXlzVG9DYW5jZWwgPSBuZXcgSGFzaFNldDw+KCk7CisKKyAgICAvLyBUcmFjayBEb3dubG9hZGVkIEZpbGUgR3JvdXBzIHRoYXQgc2hvdWxkIGJlIG1vdmVkIHRvIFN0YWxlCisgICAgTGlzdDxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGZpbGVHcm91cHNUb0FkZEFzU3RhbGUgPSBuZXcgQXJyYXlMaXN0PD4oZ3JvdXBLZXlzLnNpemUoKSk7CisKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKAorICAgICAgICAgICAgUHJvcGFnYXRlZEZ1dHVyZXMuc3VibWl0QXN5bmMoCisgICAgICAgICAgICAgICAgKCkgLT4geworICAgICAgICAgICAgICAgICAgLy8gRmlyc3QsIENsZWFyIFNQRSBTeW5jIFJlYXNvbnMgKGlmIGFwcGxpY2FibGUpIGFuZCByZW1vdmUgcGVuZGluZyBmaWxlIGdyb3VwCisgICAgICAgICAgICAgICAgICAvLyBtZXRhZGF0YS4KKyAgICAgICAgICAgICAgICAgIExpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4gY2xlYXJTcGVTeW5jUmVhc29uRnV0dXJlcyA9CisgICAgICAgICAgICAgICAgICAgICAgbmV3IEFycmF5TGlzdDw+KGdyb3VwS2V5cy5zaXplKCkpOworICAgICAgICAgICAgICAgICAgZm9yIChHcm91cEtleSBncm91cEtleSA6IGdyb3VwS2V5cykgeworICAgICAgICAgICAgICAgICAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXkgPSBncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworCisgICAgICAgICAgICAgICAgICAgIGNsZWFyU3BlU3luY1JlYXNvbkZ1dHVyZXMuYWRkKAorICAgICAgICAgICAgICAgICAgICAgICAgUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKHBlbmRpbmdHcm91cEtleSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZW5kaW5nRmlsZUdyb3VwIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGVuZGluZ0ZpbGVHcm91cCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBubyBwZW5kaW5nIGdyb3VwIGZvdW5kLCByZXR1cm4gZWFybHkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGVuZGluZyBncm91cCBleGlzdHMsIGFkZCBpdCB0byByZW1vdmUgbGlzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlbmRpbmdHcm91cHNUb1JlbW92ZS5wdXQocGVuZGluZ0dyb3VwS2V5LCBwZW5kaW5nRmlsZUdyb3VwKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCBhbGwgcGVuZGluZyBmaWxlIGtleXMgdG8gY2FuY2VsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChEYXRhRmlsZSBkYXRhRmlsZSA6IHBlbmRpbmdGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUsIHBlbmRpbmdGaWxlR3JvdXAuZ2V0QWxsb3dlZFJlYWRlcnNFbnVtKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0ZpbGVLZXlzVG9DYW5jZWwuYWRkKG5ld0ZpbGVLZXkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikpOworICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMud2hlbkFsbENvbXBsZXRlKGNsZWFyU3BlU3luY1JlYXNvbkZ1dHVyZXMpCisgICAgICAgICAgICAgICAgICAgICAgLmNhbGxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKCkgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRocm93IGFnZ3JlZ2F0ZSBleGNlcHRpb24gaWYgYW55IHJlYXNvbnMgZmFpbGVkLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFnZ3JlZ2F0ZUV4Y2VwdGlvbi50aHJvd0lmRmFpbGVkKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclNwZVN5bmNSZWFzb25GdXR1cmVzLCAiVW5hYmxlIHRvIGNsZWFyIFNQRSBTeW5jIFJlYXNvbnMiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbW11dGFibGVMaXN0LmNvcHlPZihwZW5kaW5nR3JvdXBzVG9SZW1vdmUua2V5U2V0KCkpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlUGVuZGluZ0dyb3Vwc1Jlc3VsdCAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZW1vdmVQZW5kaW5nR3JvdXBzUmVzdWx0LmJvb2xlYW5WYWx1ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBGYWlsZWQgdG8gcmVtb3ZlICVkIHBlbmRpbmcgdmVyc2lvbnMgb2YgJWQgcmVxdWVzdGVkIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgZ3JvdXBzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUQUcsIHBlbmRpbmdHcm91cHNUb1JlbW92ZS5zaXplKCksIGdyb3VwS2V5cy5zaXplKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgSU9FeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gcmVtb3ZlIHBlbmRpbmcgZ3JvdXAga2V5cywgY291bnQgPSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGdyb3VwS2V5cy5zaXplKCkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvd25sb2FkU3RhZ2VNYW5hZ2VyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jbGVhckV4cGVyaW1lbnRJZHNGb3JCdWlsZHNJZk5vbmVBY3RpdmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZW5kaW5nR3JvdXBzVG9SZW1vdmUudmFsdWVzKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKSkKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgdW51c2VkIC0+IHsKKyAgICAgICAgICAgICAgLy8gU2Vjb25kLCByZW1vdmUgZG93bmxvYWRlZCBmaWxlIGdyb3VwIG1ldGFkYXRhLgorICAgICAgICAgICAgICBMaXN0PExpc3RlbmFibGVGdXR1cmU8Vm9pZD4+IHJlYWREb3dubG9hZGVkRmlsZUdyb3VwRnV0dXJlcyA9CisgICAgICAgICAgICAgICAgICBuZXcgQXJyYXlMaXN0PD4oZ3JvdXBLZXlzLnNpemUoKSk7CisgICAgICAgICAgICAgIGZvciAoR3JvdXBLZXkgZ3JvdXBLZXkgOiBncm91cEtleXMpIHsKKyAgICAgICAgICAgICAgICBHcm91cEtleSBkb3dubG9hZGVkR3JvdXBLZXkgPSBncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKHRydWUpLmJ1aWxkKCk7CisKKyAgICAgICAgICAgICAgICByZWFkRG93bmxvYWRlZEZpbGVHcm91cEZ1dHVyZXMuYWRkKAorICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChkb3dubG9hZGVkR3JvdXBLZXkpLAorICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRlZEZpbGVHcm91cCAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb3dubG9hZGVkRmlsZUdyb3VwICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEb3dubG9hZGVkIGdyb3VwIGV4aXN0cywgYWRkIHRvIHJlbW92ZSBsaXN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRlZEdyb3Vwc1RvUmVtb3ZlLnB1dChkb3dubG9hZGVkR3JvdXBLZXksIGRvd25sb2FkZWRGaWxlR3JvdXApOworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RvcmUgZG93bmxvYWRlZCBncm91cCBzbyBpdCBjYW4gYmUgbW92ZWQgdG8gc3RhbGUgd2hlbiBhbGwgbWV0YWRhdGEKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyB1cGRhdGVkLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cHNUb0FkZEFzU3RhbGUuYWRkKGRvd25sb2FkZWRGaWxlR3JvdXApOworICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9KSk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMud2hlbkFsbENvbXBsZXRlKHJlYWREb3dubG9hZGVkRmlsZUdyb3VwRnV0dXJlcykKKyAgICAgICAgICAgICAgICAgIC5jYWxsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgKCkgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgQWdncmVnYXRlRXhjZXB0aW9uLnRocm93SWZGYWlsZWQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZERvd25sb2FkZWRGaWxlR3JvdXBGdXR1cmVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmFibGUgdG8gcmVhZCBkb3dubG9hZGVkIGZpbGUgZ3JvdXBzIHRvIHJlbW92ZSIpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEltbXV0YWJsZUxpc3QuY29weU9mKGRvd25sb2FkZWRHcm91cHNUb1JlbW92ZS5rZXlTZXQoKSkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZURvd25sb2FkZWRHcm91cHNSZXN1bHQgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZW1vdmVEb3dubG9hZGVkR3JvdXBzUmVzdWx0LmJvb2xlYW5WYWx1ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogRmFpbGVkIHRvIHJlbW92ZSAlZCBkb3dubG9hZGVkIHZlcnNpb25zIG9mICVkIHJlcXVlc3RlZCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgZ3JvdXBzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRBRywgZG93bmxvYWRlZEdyb3Vwc1RvUmVtb3ZlLnNpemUoKSwgZ3JvdXBLZXlzLnNpemUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJT0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIHJlbW92ZSBkb3dubG9hZGVkIGdyb3VwcywgY291bnQgPSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZG93bmxvYWRlZEdyb3Vwc1RvUmVtb3ZlLnNpemUoKSkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvd25sb2FkU3RhZ2VNYW5hZ2VyLmNsZWFyRXhwZXJpbWVudElkc0ZvckJ1aWxkc0lmTm9uZUFjdGl2ZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZGVkR3JvdXBzVG9SZW1vdmUudmFsdWVzKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgdW51c2VkIC0+IHsKKyAgICAgICAgICAgICAgLy8gVGhpcmQsIG1vdmUgYW55IHJlbW92ZWQgZmlsZSBncm91cHMgZnJvbSBkb3dubG9hZGVkIHRvIHN0YWxlLgorICAgICAgICAgICAgICAvLyBUaGlzIHByZXZlbnRzIGEgZmlsZXMgaW4gdGhlIGdyb3VwIGZyb20gYmVpbmcgcmVtb3ZlZCBiZWZvcmUgaXRzCisgICAgICAgICAgICAgIC8vIHN0YWxlX2xpZmV0aW1lX3NlY3MgaGFzIGV4cGlyZWQuCisgICAgICAgICAgICAgIGlmIChkb3dubG9hZGVkR3JvdXBzVG9SZW1vdmUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgLy8gTm8gZG93bmxvYWRlZCBncm91cHMgd2VyZSByZW1vdmVkLCByZXR1cm4gZWFybHkKKyAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PiBhZGRTdGFsZUdyb3VwRnV0dXJlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICAgICAgICBmb3IgKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBzdGFsZUdyb3VwIDogZmlsZUdyb3Vwc1RvQWRkQXNTdGFsZSkgeworICAgICAgICAgICAgICAgIGFkZFN0YWxlR3JvdXBGdXR1cmVzLmFkZCgKKyAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLmFkZFN0YWxlR3JvdXAoc3RhbGVHcm91cCksCisgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGFsZUdyb3VwUmVzdWx0IC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhZGRTdGFsZUdyb3VwUmVzdWx0LmJvb2xlYW5WYWx1ZSgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IEZhaWxlZCB0byBhZGQgdG8gc3RhbGUgZm9yIGdyb3VwOiAnJXMnOyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRBRywgc3RhbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJT0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gYWRkIGRvd25sb2FkZWQgZ3JvdXAgdG8gc3RhbGU6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHN0YWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgfSkpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy53aGVuQWxsQ29tcGxldGUoYWRkU3RhbGVHcm91cEZ1dHVyZXMpCisgICAgICAgICAgICAgICAgICAuY2FsbCgKKyAgICAgICAgICAgICAgICAgICAgICAoKSAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICBBZ2dyZWdhdGVFeGNlcHRpb24udGhyb3dJZkZhaWxlZCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGFsZUdyb3VwRnV0dXJlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5hYmxlIHRvIGFkZCByZW1vdmVkIGRvd25sb2FkZWQgZ3JvdXBzIGFzIHN0YWxlIik7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIHVudXNlZCAtPiB7CisgICAgICAgICAgICAgIC8vIEZvdXJ0aCwgcmVtb3ZlIGFueSBwZW5kaW5nIGRvd25sb2FkcyBmb3IgZmlsZXMgbm8gbG9uZ2VyIHJlZmVyZW5jZWQuCisgICAgICAgICAgICAgIC8vIEEgZmlsZSB0aGF0IHdhcyByZWZlcmVuY2VkIGJ5IGEgcmVtb3ZlZCBmaWxlIGdyb3VwIG1heSBzdGlsbCBiZSByZWZlcmVuY2VkIGJ5IGFuCisgICAgICAgICAgICAgIC8vIGV4aXN0aW5nIHBlbmRpbmcgZ3JvdXAgYW5kIHNob3VsZCBub3QgYmUgY2FuY2VsbGVkLiBPbmx5IGNhbmNlbCBwZW5kaW5nIGRvd25sb2FkcworICAgICAgICAgICAgICAvLyB0aGF0IGFyZSBubyBsb25nZXIgcmVmZXJlbmNlZCBieSBhbnkgYWN0aXZlL3BlbmRpbmcgZmlsZSBncm91cHMuCisgICAgICAgICAgICAgIGlmIChwZW5kaW5nR3JvdXBzVG9SZW1vdmUuaXNFbXB0eSgpKSB7CisgICAgICAgICAgICAgICAgLy8gTm8gcGVuZGluZyBncm91cHMgd2VyZSByZW1vdmVkLCByZXR1cm4gZWFybHkKKyAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgIGdldEZpbGVLZXlzUmVmZXJlbmNlZEJ5RnJlc2hHcm91cHMoKSwKKyAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZWRGaWxlS2V5cyAtPiB7CisgICAgICAgICAgICAgICAgICAgIExpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4gY2FuY2VsRG93bmxvYWRGdXR1cmVzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgICAgICAgICAgICAgIGZvciAoTmV3RmlsZUtleSBuZXdGaWxlS2V5IDogcGVuZGluZ0ZpbGVLZXlzVG9DYW5jZWwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGNhbmNlbCBmaWxlIGRvd25sb2FkIGlmIGl0J3Mgbm90IHJlZmVyZW5jZWQgYnkgYSBmcmVzaCBncm91cAorICAgICAgICAgICAgICAgICAgICAgIGlmICghcmVmZXJlbmNlZEZpbGVLZXlzLmNvbnRhaW5zKG5ld0ZpbGVLZXkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBjYW5jZWxEb3dubG9hZEZ1dHVyZXMuYWRkKHNoYXJlZEZpbGVNYW5hZ2VyLmNhbmNlbERvd25sb2FkKG5ld0ZpbGVLZXkpKTsKKyAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLndoZW5BbGxDb21wbGV0ZShjYW5jZWxEb3dubG9hZEZ1dHVyZXMpCisgICAgICAgICAgICAgICAgICAgICAgICAuY2FsbCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKSAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBZ2dyZWdhdGVFeGNlcHRpb24udGhyb3dJZkZhaWxlZCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYW5jZWxEb3dubG9hZEZ1dHVyZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuYWJsZSB0byBjYW5jZWwgZG93bmxvYWRzIGZvciByZW1vdmVkIGdyb3VwcyIpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgdGhlIHJlcXVpcmVkIHZlcnNpb24gb2YgdGhlIGdyb3VwIHRoYXQgd2UgaGF2ZSBmb3IgdGhlIGdpdmVuIGNsaWVudCBrZXkuCisgICAqCisgICAqIDxwPklmIHRoZSBncm91cCBpcyBkb3dubG9hZGVkIGFuZCByZXF1aXJlcyBhbiBpc29sYXRlZCBzdHJ1Y3R1cmUsIHRoaXMgc3RydWN0dXJlIGlzIHZlcmlmaWVkCisgICAqIGJlZm9yZSByZXR1cm5pbmcuIElmIHdlIGFyZSB1bmFibGUgdG8gdmVyaWZ5IHRoZSBpc29sYXRlZCBzdHJ1Y3R1cmUsIG51bGwgd2lsbCBiZSByZXR1cm5lZC4KKyAgICoKKyAgICogQHBhcmFtIGdyb3VwS2V5IFRoZSBrZXkgZm9yIHRoZSBkYXRhIHRvIGJlIHJldHVybmVkLiBUaGlzIGlzIGEgY29tYmluYXRpb24gb2YgbWFueSBwYXJhbWV0ZXJzCisgICAqICAgICBsaWtlIGdyb3VwIG5hbWUsIHVzZXIgYWNjb3VudC4KKyAgICogQHJldHVybiBBIExpc3RlbmFibGVGdXR1cmUgdGhhdCByZXNvbHZlcyB0byB0aGUgcmVxdWVzdGVkIGRhdGEgZmlsZSBncm91cCBmb3IgdGhlIGdpdmVuIGdyb3VwCisgICAqICAgICBuYW1lLCBpZiBpdCBleGlzdHMsIG51bGwgb3RoZXJ3aXNlLgorICAgKi8KKyAgLy8gVE9ETyhiLzEyNDA3Mjc1NCk6IENoYW5nZSB0byBwYWNrYWdlIHByaXZhdGUgb25jZSBhbGwgY29kZSBpcyByZWZhY3RvcmVkLgorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxATnVsbGFibGVUeXBlIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZ2V0RmlsZUdyb3VwKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksIGJvb2xlYW4gZG93bmxvYWRlZCkgeworICAgIEdyb3VwS2V5IGRvd25sb2FkZWRLZXkgPSBncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGRvd25sb2FkZWQpLmJ1aWxkKCk7CisgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZG93bmxvYWRlZEtleSksCisgICAgICAgIGRhdGFGaWxlR3JvdXAgLT4KKyAgICAgICAgICAgIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAvLyBUT0RPKGIvMTk0Njg4Njg3KTogY29uc2lkZXIgbW92aW5nIHRoaXMgdmVyaWZpY2F0aW9uIHRvIHRoZQorICAgICAgICAgICAgICAgIC8vIE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIgbGV2ZWwgc2luY2UgdGhhdCBpcyB3aGVyZSB2ZXJpZmljYXRpb24gaGFwcGVucyBmb3IKKyAgICAgICAgICAgICAgICAvLyBnZXREYXRhRmlsZVVyaS4KKyAgICAgICAgICAgICAgICBtYXliZVZlcmlmeUlzb2xhdGVkU3RydWN0dXJlKGRhdGFGaWxlR3JvdXAsIGRvd25sb2FkZWQpLAorICAgICAgICAgICAgICAgIHJlc3VsdCAtPiBpbW1lZGlhdGVGdXR1cmUocmVzdWx0ID8gZGF0YUZpbGVHcm91cCA6IG51bGwpKSk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyBhIGZpbGUgZ3JvdXAvc3RhdGUgcGFpciBiYXNlZCBvbiB0aGUgZ2l2ZW4ga2V5IGFuZCBhZGRpdGlvbmFsIGlkZW50aWZ5aW5nIGluZm9ybWF0aW9uLgorICAgKgorICAgKiA8cD5UaGlzIG1ldGhvZCBhbGxvd3MgY2FsbGVycyB0byBzcGVjaWZ5IGlkZW50aWZ5aW5nIGluZm9ybWF0aW9uIChidWlsZElkLCB2YXJpYW50SWQgYW5kCisgICAqIGN1c3RvbVByb3BlcnR5T3B0aW9uYWwpLiBJdCBpcyBhc3N1bWVkIHRoYXQgZGlmZmVyZW50IGlkZW50aWZ5aW5nIGluZm9ybWF0aW9uIHdpbGwgYmUgdXNlZCBmb3IKKyAgICogcGVuZGluZy9kb3dubG9kZWQgc3RhdGVzIG9mIGEgZmlsZSBncm91cCwgc28gdGhlIGRvd25sb2FkZWQgc3RhdHVzIGluIHRoZSBnaXZlbiBncm91cEtleSBpcyBub3QKKyAgICogY29uc2lkZXJlZCBieSB0aGlzIG1ldGhvZC4KKyAgICoKKyAgICogPHA+SWYgYSBncm91cCBpcyBmb3VuZCwgc3RhdGUgb2YgdGhlIGZpbGUgZ3JvdXAgKGRvd25sb2FkZWQvcGVuZGluZykgYW5kIGZpbGUgZ3JvdXAgd2lsbCBiZQorICAgKiByZXR1cm5lZCBpbiBhIFBhaXIuIElmIGEgZ3JvdXAgaXMgbm90IGZvdW5kLCBudWxsIHdpbGwgYmUgcmV0dXJuZWQuIFRoZSBib29sZWFuIHJldHVybmVkIHdpbGwKKyAgICogYmUgdHJ1ZSBpZiB0aGUgZ3JvdXAgaXMgZG93bmxvYWRlZCBhbmQgZmFsc2UgaWYgdGhlIGdyb3VwIGlzIHBlbmRpbmcuCisgICAqCisgICAqIEBwYXJhbSBncm91cEtleSBUaGUga2V5IGZvciB0aGUgZGF0YSB0byBiZSByZXR1cm5lZC4gVGhpcyBpcyBzaG91bGQgaW5jbHVkZSBncm91cCBuYW1lLCBvd25lcgorICAgKiAgICAgcGFja2FnZSBhbmQgdXNlciBhY2NvdW50CisgICAqIEBwYXJhbSBidWlsZElkIFRoZSBleHBlY3RlZCBidWlsZElkIG9mIHRoZSBmaWxlIGdyb3VwCisgICAqIEBwYXJhbSB2YXJpYW50SWQgVGhlIGV4cGVjdGVkIHZhcmlhbnRJZCBvZiB0aGUgZmlsZSBncm91cAorICAgKiBAcGFyYW0gY3VzdG9tUHJvcGVydHlPcHRpb25hbCBUaGUgZXhwZWN0ZWQgY3VzdG9tUHJvcGVydHksIGlmIG5lY2Vzc2FyeQorICAgKiBAcmV0dXJuIEEgTGlzdGVuYWJsZUZ1dHVyZSB0aGF0IHJlc29sdmVzLCBpZiB0aGUgcmVxdWVzdGVkIGdyb3VwIGlzIGZvdW5kLCB3aXRoIGEgUGFpcgorICAgKiAgICAgY29udGFpbmluZyBCb29sZWFuIHZhbHVlIG9mIHdoZXRoZXIgb3Igbm90IHRoZSBHcm91cCBpcyBkb3dubG9hZGVkIGFuZCB0aGUgR3JvdXAgaXRzZWxmLCBvcgorICAgKiAgICAgbnVsbCBvdGhlcndpc2UuCisgICAqLworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8QE51bGxhYmxlVHlwZSBQYWlyPEJvb2xlYW4sIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4+IGdldEdyb3VwUGFpckJ5SWQoCisgICAgICBHcm91cEtleSBncm91cEtleSwgbG9uZyBidWlsZElkLCBTdHJpbmcgdmFyaWFudElkLCBPcHRpb25hbDxBbnk+IGN1c3RvbVByb3BlcnR5T3B0aW9uYWwpIHsKKyAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbCgKKyAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCksCisgICAgICAgIGZyZXNoR3JvdXBQYWlyTGlzdCAtPiB7CisgICAgICAgICAgZm9yIChQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGZyZXNoR3JvdXBQYWlyIDogZnJlc2hHcm91cFBhaXJMaXN0KSB7CisgICAgICAgICAgICBpZiAoIXZlcmlmeUdyb3VwUGFpck1hdGNoZXNJZGVudGlmaWVycygKKyAgICAgICAgICAgICAgICBmcmVzaEdyb3VwUGFpciwKKyAgICAgICAgICAgICAgICBncm91cEtleS5nZXRBY2NvdW50KCksCisgICAgICAgICAgICAgICAgYnVpbGRJZCwKKyAgICAgICAgICAgICAgICB2YXJpYW50SWQsCisgICAgICAgICAgICAgICAgY3VzdG9tUHJvcGVydHlPcHRpb25hbCkpIHsKKyAgICAgICAgICAgICAgLy8gSWRlbnRpZmllcnMgZG9uJ3QgbWF0Y2gsIGNvbnRpbnVlCisgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvLyBHcm91cCBtYXRjaGVzIElELCBidXQgZW5zdXJlIHRoYXQgaXQgYWxzbyBtYXRjaGVzIHJlcXVlc3RlZCBncm91cCBuYW1lCisgICAgICAgICAgICBpZiAoIWdyb3VwS2V5LmdldEdyb3VwTmFtZSgpLmVxdWFscyhmcmVzaEdyb3VwUGFpci5maXJzdC5nZXRHcm91cE5hbWUoKSkpIHsKKyAgICAgICAgICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICAgICAgICAgIiVzOiBnZXRHcm91cFBhaXJCeUlkOiBHcm91cCAlcyBtYXRjaGVzIHRoZSBnaXZlbiBidWlsZElkID0gJWQgYW5kIHZhcmlhbnRJZCA9IgorICAgICAgICAgICAgICAgICAgICAgICsgIiAlcywgYnV0IGRvZXMgbm90IG1hdGNoIHRoZSBnaXZlbiBncm91cCBuYW1lICVzIiwKKyAgICAgICAgICAgICAgICAgIFRBRywKKyAgICAgICAgICAgICAgICAgIGZyZXNoR3JvdXBQYWlyLmZpcnN0LmdldEdyb3VwTmFtZSgpLAorICAgICAgICAgICAgICAgICAgYnVpbGRJZCwKKyAgICAgICAgICAgICAgICAgIHZhcmlhbnRJZCwKKyAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBQYWlyLmNyZWF0ZShmcmVzaEdyb3VwUGFpci5maXJzdC5nZXREb3dubG9hZGVkKCksIGZyZXNoR3JvdXBQYWlyLnNlY29uZCk7CisgICAgICAgICAgfQorCisgICAgICAgICAgLy8gTm8gY29tcGF0aWJsZSBncm91cCBmb3VuZCwgcmV0dXJuIG51bGw7CisgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0pOworICB9CisKKyAgLyoqCisgICAqIFNldCB0aGUgYWN0aXZhdGlvbiBzdGF0dXMgZm9yIHRoZSBncm91cC4KKyAgICoKKyAgICogQHBhcmFtIGdyb3VwS2V5IFRoZSBrZXkgZm9yIHdoaWNoIHRoZSBhY3RpdmF0aW9uIGlzIHRvIGJlIHNldC4KKyAgICogQHBhcmFtIGFjdGl2YXRpb24gV2hldGhlciB0aGUgZ3JvdXAgc2hvdWxkIGJlIGFjdGl2YXRlZCBvciBkZWFjdGl2YXRlZC4KKyAgICogQHJldHVybiBmdXR1cmUgcmVzb2x2aW5nIHRvIHdoZXRoZXIgdGhlIGFjdGl2YXRpb24gd2FzIHN1Y2Nlc3NmdWwuCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiBzZXRHcm91cEFjdGl2YXRpb24oR3JvdXBLZXkgZ3JvdXBLZXksIGJvb2xlYW4gYWN0aXZhdGlvbikgeworICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkR3JvdXBLZXlQcm9wZXJ0aWVzKGdyb3VwS2V5KSwKKyAgICAgICAgZ3JvdXBLZXlQcm9wZXJ0aWVzIC0+IHsKKyAgICAgICAgICAvLyBJdCBzaG91bGRuJ3QgbWFrZSBhIGRpZmZlcmVuY2UgaWYgd2UgZm91bmQgYW4gZXhpc3RpbmcgdmFsdWUgb3Igbm90LgorICAgICAgICAgIGlmIChncm91cEtleVByb3BlcnRpZXMgPT0gbnVsbCkgeworICAgICAgICAgICAgZ3JvdXBLZXlQcm9wZXJ0aWVzID0gR3JvdXBLZXlQcm9wZXJ0aWVzLmdldERlZmF1bHRJbnN0YW5jZSgpOworICAgICAgICAgIH0KKworICAgICAgICAgIEdyb3VwS2V5UHJvcGVydGllcy5CdWlsZGVyIGdyb3VwS2V5UHJvcGVydGllc0J1aWxkZXIgPSBncm91cEtleVByb3BlcnRpZXMudG9CdWlsZGVyKCk7CisgICAgICAgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PiByZW1vdmVHcm91cEZ1dHVyZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgICBpZiAoYWN0aXZhdGlvbikgeworICAgICAgICAgICAgLy8gVGhlIGdyb3VwIHdpbGwgYmUgYWRkZWQgdG8gTUREIHdpdGggdGhlIG5leHQgcnVuIG9mIEFkZEZpbGVHcm91cE9wZXJhdGlvbi4KKyAgICAgICAgICAgIGdyb3VwS2V5UHJvcGVydGllc0J1aWxkZXIuc2V0QWN0aXZhdGVkT25EZXZpY2UodHJ1ZSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGdyb3VwS2V5UHJvcGVydGllc0J1aWxkZXIuc2V0QWN0aXZhdGVkT25EZXZpY2UoZmFsc2UpOworCisgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGV4aXN0aW5nIHBlbmRpbmcgYW5kIGRvd25sb2FkZWQgZ3JvdXBzIGZyb20gTUREIGluIGNhc2Ugb2YgZGVhY3RpdmF0aW9uLAorICAgICAgICAgICAgLy8gaWYgdGhleSByZXF1aXJlZCBhY3RpdmF0aW9uIHRvIGJlIGRvbmUgb24gdGhlIGRldmljZS4KKyAgICAgICAgICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleSA9IGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisgICAgICAgICAgICByZW1vdmVHcm91cEZ1dHVyZXMuYWRkKHJlbW92ZUFjdGl2YXRlZEdyb3VwKHBlbmRpbmdHcm91cEtleSkpOworCisgICAgICAgICAgICBHcm91cEtleSBkb3dubG9hZGVkR3JvdXBLZXkgPSBncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKHRydWUpLmJ1aWxkKCk7CisgICAgICAgICAgICByZW1vdmVHcm91cEZ1dHVyZXMuYWRkKHJlbW92ZUFjdGl2YXRlZEdyb3VwKGRvd25sb2FkZWRHcm91cEtleSkpOworICAgICAgICAgIH0KKworICAgICAgICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy53aGVuQWxsQ29tcGxldGUocmVtb3ZlR3JvdXBGdXR1cmVzKQorICAgICAgICAgICAgICAuY2FsbEFzeW5jKAorICAgICAgICAgICAgICAgICAgKCkgLT4KKyAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGVHcm91cEtleVByb3BlcnRpZXMoCisgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LCBncm91cEtleVByb3BlcnRpZXNCdWlsZGVyLmJ1aWxkKCkpLAorICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgIH0pOworICB9CisKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlbW92ZUFjdGl2YXRlZEdyb3VwKEdyb3VwS2V5IGdyb3VwS2V5KSB7CisgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZ3JvdXBLZXkpLAorICAgICAgICBncm91cCAtPiB7CisgICAgICAgICAgaWYgKGdyb3VwICE9IG51bGwKKyAgICAgICAgICAgICAgJiYgZ3JvdXAuZ2V0RG93bmxvYWRDb25kaXRpb25zKCkuZ2V0QWN0aXZhdGluZ0NvbmRpdGlvbigpCisgICAgICAgICAgICAgICAgICA9PSBBY3RpdmF0aW5nQ29uZGl0aW9uLkRFVklDRV9BQ1RJVkFURUQpIHsKKyAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlbW92ZShncm91cEtleSksCisgICAgICAgICAgICAgICAgcmVtb3ZlU3VjY2VzcyAtPiB7CisgICAgICAgICAgICAgICAgICBpZiAoIXJlbW92ZVN1Y2Nlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgfSk7CisgIH0KKworICAvKioKKyAgICogSW1wb3J0IGlubGluZSBmaWxlcyBpbnRvIGFuIGV4aXN0aW5nIERhdGFGaWxlR3JvdXAgYW5kIHVwZGF0ZSBpdHMgbWV0YWRhdGEgYWNjb3JkaW5nbHkuCisgICAqCisgICAqIDxwPlRoZSBnaXZlbiBHcm91cEtleSB3aWxsIGJlIHVzZWQgdG8gY2hlY2sgZm9yIGFuIGV4aXN0aW5nIERhdGFGaWxlR3JvdXAgdG8gdXBkYXRlIGFuZCB0aGUKKyAgICogZ2l2ZW4gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24gKGJ1aWxkSWQsIHZhcmlhbnRJZCwgY3VzdG9tUHJvcGVydHkpIHdpbGwgYmUgdXNlZCB0byBlbnN1cmUgYW4KKyAgICogZXhpc3RpbmcgZmlsZSBncm91cCBtYXRjaGVzIHRoZSBjYWxsZXIgZXhwZWN0ZWQgdmVyc2lvbi4gQW4gaW1wb3J0IHdpbGwgb25seSB0YWtlIHBsYWNlIGlmIGFuCisgICAqIGV4aXN0aW5nIGZpbGUgZ3JvdXAgb2YgdGhlIHNhbWUgdmVyc2lvbiBpcyBmb3VuZC4KKyAgICoKKyAgICogPHA+T25jZSBhIHZhbGlkIGZpbGUgZ3JvdXAgaXMgZm91bmQsIHRoZSBnaXZlbiB1cGRhdGVkRGF0YUZpbGVMaXN0IHdpbGwgYmUgbWVyZ2VkIGludG8gaXQuIElmIGEKKyAgICogRGF0YUZpbGUgZXhpc3RzIGluIGJvdGggdXBkYXRlZERhdGFGaWxlTGlzdCBhbmQgdGhlIGV4aXN0aW5nIERhdGFGaWxlR3JvdXAgKHRoZSBmaWxlSWQgaXMgdGhlCisgICAqIHNhbWUpLCB1cGRhdGVkRGF0YUZpbGVMaXN0J3MgdmVyc2lvbiB3aWxsIGJlIHByZWZlcnJlZC4gVGhlIHJlc3VsdGluZyBtZXJnZWQgRmlsZSBHcm91cCB3aWxsIGJlCisgICAqIHVzZWQgdG8gZGV0ZXJtaW5lIHdoaWNoIGZpbGVzIG5lZWQgdG8gYmUgaW1wb3J0ZWQuCisgICAqCisgICAqIDxwPk9ubHkgZmlsZXMgaW4gdGhlIHVwZGF0ZWQgRmlsZSBHcm91cCB3aWxsIGJlIGltcG9ydGVkICh0aGUgaW5saW5lRmlsZU1hcCBtYXkgY29udGFpbiBleHRyYQorICAgKiBmaWxlcywgYnV0IHRoZXkgd2lsbCBub3QgYmUgaW1wb3J0ZWQpLgorICAgKgorICAgKiA8cD5UaGlzIG1ldGhvZCBpcyBhbiBhdG9taWMgb3BlcmF0aW9uOiBhbGwgZmlsZXMgbXVzdCBiZSBzdWNjZXNzZnVsbHkgaW1wb3J0ZWQgYmVmb3JlIHRoZQorICAgKiBtZXJnZWQgZmlsZSBncm91cCBpcyB3cml0dGVuIGJhY2sgdG8gTUREIG1ldGFkYXRhLiBBIGZhaWx1cmUgdG8gaW1wb3J0IGFueSBmaWxlIHdpbGwgcmVzdWx0IGluCisgICAqIG5vIGNoYW5nZSB0byB0aGUgZXhpc3RpbmcgbWV0YWRhdGEgYW5kIGEgdGhpcyBmYWlsdXJlIHdpbGwgYmUgcmV0dXJuZWQuCisgICAqCisgICAqIEBwYXJhbSBncm91cEtleSBUaGUga2V5IG9mIHRoZSBleGlzdGluZyBncm91cCB0byB1cGRhdGUKKyAgICogQHBhcmFtIGJ1aWxkSWQgYnVpbGQgaWQgdG8gaWRlbnRpZnkgdGhlIGZpbGUgZ3JvdXAgdG8gdXBkYXRlCisgICAqIEBwYXJhbSB2YXJpYW50SWQgdmFyaWFudCBpZCB0byBpZGVudGlmeSB0aGUgZmlsZSBncm91cCB0byB1cGRhdGUKKyAgICogQHBhcmFtIHVwZGF0ZWREYXRhRmlsZUxpc3QgbGlzdCBvZiBEYXRhRmlsZXMgdG8gaW1wb3J0IGludG8gdGhlIGZpbGUgZ3JvdXAKKyAgICogQHBhcmFtIGlubGluZUZpbGVNYXAgTWFwIG9mIGlubGluZSBmaWxlIHNvdXJjZXMgdGhhdCB3aWxsIGJlIGltcG9ydGVkLCB3aGVyZSB0aGUga2V5IGlzIGZpbGUgaWQKKyAgICogICAgIGFuZCB0aGUgdmFsdWVzIGFyZSB7QGxpbmsgRmlsZVNvdXJjZX1zIGNvbnRhaW5pbmcgZmlsZSBjb250ZW50CisgICAqIEBwYXJhbSBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsIE9wdGlvbmFsIGN1c3RvbSBwcm9wZXJ0eSB1c2VkIHRvIGlkZW50aWZ5IHRoZSBmaWxlIGdyb3VwIHRvCisgICAqICAgICB1cGRhdGUKKyAgICogQHBhcmFtIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciBWYWxpZGF0aW9uIHRoYXQgcnVucyBhZnRlciB0aGUgZmlsZSBncm91cCBpcyBkb3dubG9hZGVkIGJ1dAorICAgKiAgICAgYmVmb3JlIHRoZSBmaWxlIGdyb3VwIGxlYXZlcyB0aGUgcGVuZGluZyBzdGF0ZS4KKyAgICogQHJldHVybiBBIExpc3RlbmFibGVGdXR1cmUgdGhhdCByZXNvbHZlcyB3aGVuIGlubGluZSBmaWxlcyBoYXZlIHN1Y2Nlc3NmdWxseSBpbXBvcnRlZAorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBpbXBvcnRGaWxlc0ludG9GaWxlR3JvdXAoCisgICAgICBHcm91cEtleSBncm91cEtleSwKKyAgICAgIGxvbmcgYnVpbGRJZCwKKyAgICAgIFN0cmluZyB2YXJpYW50SWQsCisgICAgICBJbW11dGFibGVMaXN0PERhdGFGaWxlPiB1cGRhdGVkRGF0YUZpbGVMaXN0LAorICAgICAgSW1tdXRhYmxlTWFwPFN0cmluZywgRmlsZVNvdXJjZT4gaW5saW5lRmlsZU1hcCwKKyAgICAgIE9wdGlvbmFsPEFueT4gY3VzdG9tUHJvcGVydHlPcHRpb25hbCwKKyAgICAgIEFzeW5jRnVuY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsLCBCb29sZWFuPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpIHsKKyAgICBEb3dubG9hZFN0YXRlTG9nZ2VyIGRvd25sb2FkU3RhdGVMb2dnZXIgPSBEb3dubG9hZFN0YXRlTG9nZ2VyLmZvckltcG9ydChldmVudExvZ2dlcik7CisKKyAgICAvLyBHZXQgZ3JvdXAgdGhhdCBzaG91bGQgYmUgdXBkYXRlZCBmb3IgaW1wb3J0LCBvciByZXR1cm4gZ3JvdXAgbm90IGZvdW5kIGZhaWx1cmUKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFBhaXI8Qm9vbGVhbiwgRGF0YUZpbGVHcm91cEludGVybmFsPj4gZ3JvdXBQYWlyVG9VcGRhdGVGdXR1cmUgPQorICAgICAgICB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICBnZXRHcm91cFBhaXJCeUlkKGdyb3VwS2V5LCBidWlsZElkLCB2YXJpYW50SWQsIGN1c3RvbVByb3BlcnR5T3B0aW9uYWwpLAorICAgICAgICAgICAgZm91bmRHcm91cFBhaXIgLT4geworICAgICAgICAgICAgICBpZiAoZm91bmRHcm91cFBhaXIgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIEdyb3VwIHdpdGggaWRlbnRpZmllcnMgY291bGQgbm90IGJlIGZvdW5kLCByZXR1cm4gZmFpbHVyZS4KKyAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICIlczogaW1wb3J0RmlsZXMgZm9yIGdyb3VwIG5hbWU6ICVzLCBidWlsZElkOiAlZCwgdmFyaWFudElkOiAlcywgYnV0IG5vIGdyb3VwIgorICAgICAgICAgICAgICAgICAgICAgICAgKyAiIHdhcyBmb3VuZCIsCisgICAgICAgICAgICAgICAgICAgIFRBRywgZ3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCksIGJ1aWxkSWQsIHZhcmlhbnRJZCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5HUk9VUF9OT1RfRk9VTkRfRVJST1IpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0TWVzc2FnZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlsZSBncm91cDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBub3QgZm91bmQhIE1ha2Ugc3VyZSBhZGRGaWxlR3JvdXAgaGFzIGJlZW4gY2FsbGVkLiIpCisgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAvLyB3cmFwIGluIGNoZWNrTm90TnVsbCB0byBlbnN1cmUgdHlwZSBzYWZldHkuCisgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUoY2hlY2tOb3ROdWxsKGZvdW5kR3JvdXBQYWlyKSk7CisgICAgICAgICAgICB9KTsKKworICAgIHJldHVybiBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlLmZyb20oZ3JvdXBQYWlyVG9VcGRhdGVGdXR1cmUpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIGdyb3VwUGFpclRvVXBkYXRlIC0+IHsKKyAgICAgICAgICAgICAgLy8gUGVyZm9ybSBhbiBpbi1tZW1vcnkgbWVyZ2Ugb2YgdXBkYXRlZERhdGFGaWxlTGlzdCBpbnRvIHRoZSBncm91cCwgc28gd2UgZ2V0IHRoZQorICAgICAgICAgICAgICAvLyBjb3JyZWN0IGxpc3Qgb2YgZmlsZXMgdG8gaW1wb3J0LgorICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgbWVyZ2VkRmlsZUdyb3VwID0KKyAgICAgICAgICAgICAgICAgIG1lcmdlRmlsZXNJbnRvRmlsZUdyb3VwKHVwZGF0ZWREYXRhRmlsZUxpc3QsIGdyb3VwUGFpclRvVXBkYXRlLnNlY29uZCk7CisKKyAgICAgICAgICAgICAgLy8gTG9nIHRoZSBzdGFydCBvZiB0aGUgaW1wb3J0IG5vdyB0aGF0IHdlIGhhdmUgdGhlIGdyb3VwLgorICAgICAgICAgICAgICBkb3dubG9hZFN0YXRlTG9nZ2VyLmxvZ1N0YXJ0ZWQobWVyZ2VkRmlsZUdyb3VwKTsKKworICAgICAgICAgICAgICAvLyBSZXNlcnZlIGZpbGUgZW50cmllcyBpbiBjYXNlIGFueSBuZXcgRGF0YUZpbGVzIHdlcmUgaW5jbHVkZWQgaW4gdGhlIG1lcmdlLiBUaGlzCisgICAgICAgICAgICAgIC8vIHdpbGwgYmUgYSBuby1vcCBmb3IgZXhpc3RpbmcgRGF0YUZpbGVzLgorICAgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlR3JvdXAobWVyZ2VkRmlsZUdyb3VwKSwKKyAgICAgICAgICAgICAgICAgIHN1YnNjcmliZWQgLT4geworICAgICAgICAgICAgICAgICAgICBpZiAoIXN1YnNjcmliZWQpIHsKKyAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRSZXN1bHRDb2RlLlVOQUJMRV9UT19SRVNFUlZFX0ZJTEVfRU5UUlkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0TWVzc2FnZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIHJlc2VydmUgbmV3IGZpbGUgZW50cmllcyBmb3IgZ3JvdXA6ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBtZXJnZWRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShtZXJnZWRGaWxlR3JvdXApOworICAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgbWVyZ2VkRmlsZUdyb3VwIC0+IHsKKyAgICAgICAgICAgICAgYm9vbGVhbiBncm91cElzRG93bmxvYWRlZCA9IEZ1dHVyZXMuZ2V0RG9uZShncm91cFBhaXJUb1VwZGF0ZUZ1dHVyZSkuZmlyc3Q7CisKKyAgICAgICAgICAgICAgLy8gSWYgd2UgYXJlIHVwZGF0aW5nIGEgcGVuZGluZyBncm91cCBhbmQgdGhlIGltcG9ydCBpcyBzdWNjZXNzZnVsLCB0aGUgcGVuZGluZworICAgICAgICAgICAgICAvLyB2ZXJzaW9uIHNob3VsZCBiZSByZW1vdmVkIGZyb20gbWV0YWRhdGEuCisgICAgICAgICAgICAgIGJvb2xlYW4gcmVtb3ZlUGVuZGluZ1ZlcnNpb24gPSAhZ3JvdXBJc0Rvd25sb2FkZWQ7CisKKyAgICAgICAgICAgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PiBhbGxJbXBvcnRGdXR1cmVzID0KKyAgICAgICAgICAgICAgICAgIHN0YXJ0SW1wb3J0RnV0dXJlcyhncm91cEtleSwgbWVyZ2VkRmlsZUdyb3VwLCBpbmxpbmVGaWxlTWFwKTsKKworICAgICAgICAgICAgICAvLyBDb21iaW5lIEZ1dHVyZXMgdXNpbmcgd2hlbkFsbENvbXBsZXRlIHNvIGFsbCBpbXBvcnRzIGFyZSBhdHRlbXB0ZWQsIGV2ZW4gaWYgc29tZQorICAgICAgICAgICAgICAvLyBmYWlsLgorICAgICAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPEdyb3VwRG93bmxvYWRTdGF0dXM+IGNvbWJpbmVkSW1wb3J0RnV0dXJlID0KKyAgICAgICAgICAgICAgICAgIFByb3BhZ2F0ZWRGdXR1cmVzLndoZW5BbGxDb21wbGV0ZShhbGxJbXBvcnRGdXR1cmVzKQorICAgICAgICAgICAgICAgICAgICAgIC5jYWxsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJpZnlHcm91cERvd25sb2FkZWQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2VkRmlsZUdyb3VwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVBlbmRpbmdWZXJzaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZFN0YXRlTG9nZ2VyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICBjb21iaW5lZEltcG9ydEZ1dHVyZSwKKyAgICAgICAgICAgICAgICAgIGdyb3VwRG93bmxvYWRTdGF0dXMgLT4geworICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgaW1wb3J0cyBmYWlsZWQsIHdlIHNob3VsZCByZXR1cm4gdGhpcyBpbW1lZGlhdGVseS4KKyAgICAgICAgICAgICAgICAgICAgQWdncmVnYXRlRXhjZXB0aW9uLnRocm93SWZGYWlsZWQoCisgICAgICAgICAgICAgICAgICAgICAgICBhbGxJbXBvcnRGdXR1cmVzLAorICAgICAgICAgICAgICAgICAgICAgICAgIkZhaWxlZCB0byBpbXBvcnQgZmlsZXMsICVkIGF0dGVtcHRlZCIsCisgICAgICAgICAgICAgICAgICAgICAgICBhbGxJbXBvcnRGdXR1cmVzLnNpemUoKSk7CisKKyAgICAgICAgICAgICAgICAgICAgLy8gV2UgbG9nIG90aGVyIHJlc3VsdHMgaW4gdmVyaWZ5R3JvdXBEb3dubG9hZGVkLCBzbyBvbmx5IGNoZWNrIGZvcgorICAgICAgICAgICAgICAgICAgICAvLyBkb3dubG9hZGVkIGhlcmUuCisgICAgICAgICAgICAgICAgICAgIGlmIChncm91cERvd25sb2FkU3RhdHVzID09IEdyb3VwRG93bmxvYWRTdGF0dXMuRE9XTkxPQURFRCkgeworICAgICAgICAgICAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ01kZERvd25sb2FkUmVzdWx0KDAsIG51bGwpOworICAgICAgICAgICAgICAgICAgICAgIC8vIGdyb3VwIGRvd25sb2FkZWQsIHNvIGl0IHdpbGwgYmUgd3JpdHRlbiBpbiB2ZXJpZnlHcm91cERvd25sb2FkZWQsIHJldHVybgorICAgICAgICAgICAgICAgICAgICAgIC8vIGVhcmx5LgorICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAvLyBHcm91cCB0byB1cGRhdGUgaXMgcGVuZGluZyBvciBmYWlsZWQuIEhvd2V2ZXIsIHRoaXMgc3RhdGUgaXMgbm90IGR1ZSB0byB0aGUKKyAgICAgICAgICAgICAgICAgICAgLy8gaW1wb3J0IGZ1dHVyZXMgKHdoaWNoIGFsbCBzdWNjZWVkZWQpLiBUaGVyZWZvcmUsIHdlIGFyZSBzYWZlIHRvIHdyaXRlCisgICAgICAgICAgICAgICAgICAgIC8vIG1lcmdlZCBmaWxlIGdyb3VwIHRvIG1ldGFkYXRhIHVzaW5nIHRoZSBvcmlnaW5hbCBzdGF0ZSAoZG93bmxvYWRlZC9wZW5kaW5nKQorICAgICAgICAgICAgICAgICAgICAvLyBhcyBiZWZvcmUuCisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChncm91cElzRG93bmxvYWRlZCkuYnVpbGQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXJnZWRGaWxlR3JvdXApLAorICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVTdWNjZXNzIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF3cml0ZVN1Y2Nlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudExvZ2dlci5sb2dFdmVudFNhbXBsZWQoMCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0TWVzc2FnZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRmlsZSBJbXBvcnQocykgc3VjY2VlZGVkLCBidXQgZmFpbGVkIHRvIHNhdmUgTUREIHN0YXRlLiIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERvd25sb2FkUmVzdWx0Q29kZS5VTkFCTEVfVE9fVVBEQVRFX0dST1VQX01FVEFEQVRBX0VSUk9SKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgIC5jYXRjaGluZ0FzeW5jKAorICAgICAgICAgICAgRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgZXhjZXB0aW9uIC0+IHsKKyAgICAgICAgICAgICAgLy8gTG9nIERvd25sb2FkRXhjZXB0aW9uIChvciBtdWx0aXBsZSBEb3dubG9hZEV4Y2VwdGlvbnMgaWYgd3JhcHBlZCBpbgorICAgICAgICAgICAgICAvLyBBZ2dyZWdhdGVFeGNlcHRpb24pIGZvciBkZWJ1Z2dpbmcuCisgICAgICAgICAgICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVzdWx0RnV0dXJlID0gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgRG93bmxvYWRFeGNlcHRpb24pIHsKKyAgICAgICAgICAgICAgICBMb2dVdGlsLmQoIiVzOiBMb2dnaW5nIERvd25sb2FkRXhjZXB0aW9uIiwgVEFHKTsKKworICAgICAgICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uIGRvd25sb2FkRXhjZXB0aW9uID0gKERvd25sb2FkRXhjZXB0aW9uKSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgcmVzdWx0RnV0dXJlID0KKyAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0RnV0dXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgdm9pZEFyZyAtPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ0Rvd25sb2FkRmFpbHVyZShncm91cEtleSwgZG93bmxvYWRFeGNlcHRpb24sIGJ1aWxkSWQsIHZhcmlhbnRJZCkpOworICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4Y2VwdGlvbiBpbnN0YW5jZW9mIEFnZ3JlZ2F0ZUV4Y2VwdGlvbikgeworICAgICAgICAgICAgICAgIExvZ1V0aWwuZCgiJXM6IExvZ2dpbmcgQWdncmVnYXRlRXhjZXB0aW9uIiwgVEFHKTsKKworICAgICAgICAgICAgICAgIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiBhZ2dyZWdhdGVFeGNlcHRpb24gPSAoQWdncmVnYXRlRXhjZXB0aW9uKSBleGNlcHRpb247CisgICAgICAgICAgICAgICAgZm9yIChUaHJvd2FibGUgdGhyb3dhYmxlIDogYWdncmVnYXRlRXhjZXB0aW9uLmdldEZhaWx1cmVzKCkpIHsKKyAgICAgICAgICAgICAgICAgIGlmICghKHRocm93YWJsZSBpbnN0YW5jZW9mIERvd25sb2FkRXhjZXB0aW9uKSkgeworICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoIiVzOiBFeHBlY3RpbmcgRG93bmxvYWRFeGNlcHRpb25zIGluIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiIsIFRBRyk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbiBkb3dubG9hZEV4Y2VwdGlvbiA9IChEb3dubG9hZEV4Y2VwdGlvbikgdGhyb3dhYmxlOworICAgICAgICAgICAgICAgICAgcmVzdWx0RnV0dXJlID0KKyAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEZ1dHVyZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZEFyZyAtPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nRG93bmxvYWRGYWlsdXJlKGdyb3VwS2V5LCBkb3dubG9hZEV4Y2VwdGlvbiwgYnVpbGRJZCwgdmFyaWFudElkKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgLy8gQWx3YXlzIHJldHVybiBmYWlsdXJlIHRvIHVwc3RyZWFtIGNhbGxlcnMgZm9yIGZ1cnRoZXIgZXJyb3IgaGFuZGxpbmcuCisgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICByZXN1bHRGdXR1cmUsIHZvaWRBcmcgLT4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGV4Y2VwdGlvbikpOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIFZlcmlmaWVzIGZpbGUgZ3JvdXAgcGFpciBtYXRjaGVzIGdpdmVuIGlkZW50aWZpZXJzLgorICAgKgorICAgKiA8cD5UaGUgZm9sbG93aW5nIHByb3BlcnRpZXMgYXJlIGNoZWNrZWQgdG8gZW5zdXJlIHRoZSBzYW1lIGlkIG9mIGEgZmlsZSBncm91cDoKKyAgICoKKyAgICogPHVsPgorICAgKiAgIDxsaT5hY2NvdW50CisgICAqICAgPGxpPmJ1aWxkIGlkCisgICAqICAgPGxpPnZhcmlhbnQgaWQKKyAgICogICA8bGk+Y3VzdG9tIHByb3BlcnR5CisgICAqIDwvdWw+CisgICAqLworICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHZlcmlmeUdyb3VwUGFpck1hdGNoZXNJZGVudGlmaWVycygKKyAgICAgIFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZ3JvdXBQYWlyLAorICAgICAgU3RyaW5nIHNlcmlhbGl6ZWRBY2NvdW50LAorICAgICAgbG9uZyBidWlsZElkLAorICAgICAgU3RyaW5nIHZhcmlhbnRJZCwKKyAgICAgIE9wdGlvbmFsPEFueT4gY3VzdG9tUHJvcGVydHlPcHRpb25hbCkgeworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPSBncm91cFBhaXIuc2Vjb25kOworICAgIGlmICghZ3JvdXBQYWlyLmZpcnN0LmdldEFjY291bnQoKS5lcXVhbHMoc2VyaWFsaXplZEFjY291bnQpKSB7CisgICAgICBMb2dVdGlsLnYoCisgICAgICAgICAgIiVzOiB2ZXJpZnlHcm91cFBhaXJNYXRjaGVzSWRlbnRpZmllcnMgZmFpbGVkIGZvciBncm91cCAlcyBkdWUgdG8gbWlzbWF0Y2hlZCBhY2NvdW50IiwKKyAgICAgICAgICBUQUcsIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmIChmaWxlR3JvdXAuZ2V0QnVpbGRJZCgpICE9IGJ1aWxkSWQpIHsKKyAgICAgIExvZ1V0aWwudigKKyAgICAgICAgICAiJXM6IHZlcmlmeUdyb3VwUGFpck1hdGNoZXNJZGVudGlmaWVycyBmYWlsZWQgZm9yIGdyb3VwICVzIGR1ZSB0byBtaXNtYXRjaGVkIGJ1aWxkSWQ6IgorICAgICAgICAgICAgICArICIgZXhpc3RpbmcgPSAlZCwgZXhwZWN0ZWQgPSAlZCIsCisgICAgICAgICAgVEFHLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCksIGZpbGVHcm91cC5nZXRCdWlsZElkKCksIGJ1aWxkSWQpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoIXZhcmlhbnRJZC5lcXVhbHMoZmlsZUdyb3VwLmdldFZhcmlhbnRJZCgpKSkgeworICAgICAgTG9nVXRpbC52KAorICAgICAgICAgICIlczogdmVyaWZ5R3JvdXBQYWlyTWF0Y2hlc0lkZW50aWZpZXJzIGZhaWxlZCBmb3IgZ3JvdXAgJXMgZHVlIHRvIG1pc21hdGNoZWQiCisgICAgICAgICAgICAgICsgIiB2YXJpYW50SWQ6IGV4aXN0aW5nID0gJXMsIGV4cGVjdGVkID0gJXMiLAorICAgICAgICAgIFRBRywgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpLCBmaWxlR3JvdXAuZ2V0VmFyaWFudElkKCksIHZhcmlhbnRJZCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgT3B0aW9uYWw8QW55PiBleGlzdGluZ0N1c3RvbVByb3BlcnR5T3B0aW9uYWwgPQorICAgICAgICBmaWxlR3JvdXAuaGFzQ3VzdG9tUHJvcGVydHkoKQorICAgICAgICAgICAgPyBPcHRpb25hbC5vZihmaWxlR3JvdXAuZ2V0Q3VzdG9tUHJvcGVydHkoKSkKKyAgICAgICAgICAgIDogT3B0aW9uYWwuYWJzZW50KCk7CisgICAgaWYgKCFleGlzdGluZ0N1c3RvbVByb3BlcnR5T3B0aW9uYWwuZXF1YWxzKGN1c3RvbVByb3BlcnR5T3B0aW9uYWwpKSB7CisgICAgICBMb2dVdGlsLnYoCisgICAgICAgICAgIiVzOiB2ZXJpZnlHcm91cFBhaXJNYXRjaGVzSWRlbnRpZmllcnMgZmFpbGVkIGZvciBncm91cCAlcyBkdWUgdG8gbWlzbWF0Y2hlZCBjdXN0b20iCisgICAgICAgICAgICAgICsgIiBwcm9wZXJ0eSBvcHRpb25hbDogZXhpc3RpbmcgPSAlcywgZXhwZWN0ZWQgPSAlcyIsCisgICAgICAgICAgVEFHLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCksIGV4aXN0aW5nQ3VzdG9tUHJvcGVydHlPcHRpb25hbCwgY3VzdG9tUHJvcGVydHlPcHRpb25hbCk7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLyoqCisgICAqIE1lcmdlIGZpbGVzIGZyb20gYSBMaXN0IG9mIERhdGFGaWxlcyBpbnRvIGEgRmlsZSBHcm91cC4KKyAgICoKKyAgICogPHA+VGhlIG1lcmdlIG9wZXJhdGlvbiB3aWxsICJvdmVycmlkZSIgRGF0YUZpbGVzIG9mIHtAY29kZSBleGlzdGluZ0ZpbGVHcm91cH0gd2l0aCBEYXRhRmlsZXMKKyAgICogZnJvbSB7QGNvZGUgZGF0YUZpbGVMaXN0fSBpZiB0aGV5IHNoYXJlIHRoZSBzYW1lIGZpbGVJZHMuIERhdGFGaWxlcyB0aGF0IGFyZSBpbiB7QGNvZGUKKyAgICogZXhpc3RpbmdGaWxlR3JvdXB9IGJ1dCBub3QgaW4ge0Bjb2RlIGRhdGFGaWxlTGlzdH0gd2lsbCByZW1haW4gdW5jaGFuZ2VkLiBEYXRhRmlsZXMgd2hpY2ggYXJlCisgICAqIGluIHtAY29kZSBkYXRhRmlsZUxpc3R9IGJ1dCBub3Qge0Bjb2RlIGV4aXN0aW5nRmlsZUdyb3VwfSB3aWxsIGJlIGFwcGVuZGVkIHRvIHRoZSBmaWxlIGxpc3QuCisgICAqCisgICAqIEBwYXJhbSBkYXRhRmlsZUxpc3QgZmlsZSBsaXN0IHRvIG1lcmdlIGludG8gZXhpc3RpbmcgZmlsZSBncm91cAorICAgKiBAcGFyYW0gZXhpc3RpbmdGaWxlR3JvdXAgZXhpc3RpbmcgZmlsZSBncm91cCB0byBjb250YWluIGZpbGUgbGlzdAorICAgKiBAcmV0dXJuIExGIG9mIGEgIm1lcmdlZCIgZmlsZSBncm91cCB3aXRoIGZpbGVzIGZyb20ge0Bjb2RlIGRhdGFGaWxlTGlzdH0gYW5kIGFueSBub24tdXBkYXRlZAorICAgKiAgICAgZmlsZXMgZnJvbSB7QGNvZGUgZXhpc3RpbmdGaWxlR3JvdXB9CisgICAqLworICBwcml2YXRlIHN0YXRpYyBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgbWVyZ2VGaWxlc0ludG9GaWxlR3JvdXAoCisgICAgICBJbW11dGFibGVMaXN0PERhdGFGaWxlPiBkYXRhRmlsZUxpc3QsIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBleGlzdGluZ0ZpbGVHcm91cCkgeworICAgIC8vIFN0YXJ0IHdpdGggZXhpc3RpbmdGaWxlR3JvdXAncyBwcm9wZXJ0aWVzLCBidXQgY2xlYXIgdGhlIGZpbGUgbGlzdAorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIG1lcmdlZEdyb3VwQnVpbGRlciA9IGV4aXN0aW5nRmlsZUdyb3VwLnRvQnVpbGRlcigpLmNsZWFyRmlsZSgpOworCisgICAgLy8gVXNlIGEgbWFwIHRvIHRyYWNrIGZpbGVzIGJ5IGZpbGVJZAorICAgIE1hcDxTdHJpbmcsIERhdGFGaWxlPiBmaWxlTWFwID0gbmV3IEhhc2hNYXA8PigpOworCisgICAgLy8gQWRkIGFsbCBmaWxlcyBmcm9tIGV4aXN0aW5nIGZpbGUgZ3JvdXAgdG8gbWFwIGZpcnN0CisgICAgZm9yIChEYXRhRmlsZSBmaWxlIDogZXhpc3RpbmdGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKSkgeworICAgICAgZmlsZU1hcC5wdXQoZmlsZS5nZXRGaWxlSWQoKSwgZmlsZSk7CisgICAgfQorCisgICAgLy8gQWRkIGFsbCBmaWxlcyBmcm9tIGRhdGEgZmlsZSBsaXN0IHRvIG1hcCBzZWNvbmQsIGVuc3VyaW5nIG5ldyBmaWxlcyB1cGRhdGUgdGhlIGV4aXN0aW5nCisgICAgLy8gZW50cmllcworICAgIGZvciAoRGF0YUZpbGUgZmlsZSA6IGRhdGFGaWxlTGlzdCkgeworICAgICAgZmlsZU1hcC5wdXQoZmlsZS5nZXRGaWxlSWQoKSwgZmlsZSk7CisgICAgfQorCisgICAgLy8gQWRkIGFsbCBmaWxlcyBmcm9tIG1hcCB0byB0aGUgZ3JvdXAgYW5kIGJ1aWxkCisgICAgcmV0dXJuIG1lcmdlZEdyb3VwQnVpbGRlci5hZGRBbGxGaWxlKGZpbGVNYXAudmFsdWVzKCkpLmJ1aWxkKCk7CisgIH0KKworICAvKiogU3RhcnRzIGltcG9ydHMgb2YgaW5saW5lIGZpbGVzIGluIGdpdmVuIGdyb3VwLiAqLworICBwcml2YXRlIExpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4gc3RhcnRJbXBvcnRGdXR1cmVzKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcGVuZGluZ0dyb3VwLAorICAgICAgTWFwPFN0cmluZywgRmlsZVNvdXJjZT4gaW5saW5lRmlsZU1hcCkgeworICAgIExpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4gYWxsSW1wb3J0RnV0dXJlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgIGZvciAoRGF0YUZpbGUgZGF0YUZpbGUgOiBwZW5kaW5nR3JvdXAuZ2V0RmlsZUxpc3QoKSkgeworICAgICAgaWYgKCFkYXRhRmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkuc3RhcnRzV2l0aChNZGRDb25zdGFudHMuSU5MSU5FX0ZJTEVfVVJMX1NDSEVNRSkpIHsKKyAgICAgICAgLy8gU2tpcCBub24taW5saW5lIGZpbGVzCisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShkYXRhRmlsZSwgcGVuZGluZ0dyb3VwLmdldEFsbG93ZWRSZWFkZXJzRW51bSgpKTsKKworICAgICAgYWxsSW1wb3J0RnV0dXJlcy5hZGQoCisgICAgICAgICAgdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICBzaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKG5ld0ZpbGVLZXkpLAorICAgICAgICAgICAgICBmaWxlU3RhdHVzIC0+IHsKKyAgICAgICAgICAgICAgICBpZiAoZmlsZVN0YXR1cy5lcXVhbHMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpIHsKKyAgICAgICAgICAgICAgICAgIC8vIGZpbGUgYWxyZWFkeSBkb3dubG9hZGVkLCByZXR1cm4gaW1tZWRpYXRlbHkKKyAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gRmlsZSBuZWVkcyB0byBiZSBkb3dubG9hZGVkLCBjaGVjayB0aGF0IGlubGluZSBmaWxlIHNvdXJjZSBpcyBhdmFpbGFibGUKKyAgICAgICAgICAgICAgICBpZiAoIWlubGluZUZpbGVNYXAuY29udGFpbnNLZXkoZGF0YUZpbGUuZ2V0RmlsZUlkKCkpKSB7CisgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICAgIiVzOkF0dGVtcHQgdG8gaW1wb3J0IGZpbGUgd2l0aG91dCBpbmxpbmUgZmlsZSBzb3VyY2UuIElkID0gJXMiLAorICAgICAgICAgICAgICAgICAgICAgIFRBRywgZGF0YUZpbGUuZ2V0RmlsZUlkKCkpOworICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuTUlTU0lOR19JTkxJTkVfRklMRV9TT1VSQ0UpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAvLyBGaWxlIHNvdXJjZSBpcyBwcm92aWRlZCwgcHJvY2VlZCB3aXRoIGltcG9ydC4KKyAgICAgICAgICAgICAgICAvLyBOT1RFOiB0aGUgdXNlIG9mIGNoZWNrTm90TnVsbCBoZXJlIGlzIGZpbmUgc2luY2Ugd2UgZXhwbGljaXRseSBjaGVjayB0aGF0IG1hcAorICAgICAgICAgICAgICAgIC8vIGNvbnRhaW5zIHRoZSBzb3VyY2UgYWJvdmUuCisgICAgICAgICAgICAgICAgcmV0dXJuIHNoYXJlZEZpbGVNYW5hZ2VyLnN0YXJ0SW1wb3J0KAorICAgICAgICAgICAgICAgICAgICBncm91cEtleSwKKyAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUsCisgICAgICAgICAgICAgICAgICAgIG5ld0ZpbGVLZXksCisgICAgICAgICAgICAgICAgICAgIHBlbmRpbmdHcm91cC5nZXREb3dubG9hZENvbmRpdGlvbnMoKSwKKyAgICAgICAgICAgICAgICAgICAgY2hlY2tOb3ROdWxsKGlubGluZUZpbGVNYXAuZ2V0KGRhdGFGaWxlLmdldEZpbGVJZCgpKSkpOworICAgICAgICAgICAgICB9KSk7CisgICAgfQorCisgICAgcmV0dXJuIGFsbEltcG9ydEZ1dHVyZXM7CisgIH0KKworICAvKioKKyAgICogSW5pdGlhdGVzIGRvd25sb2FkIG9mIHRoZSBmaWxlIGdyb3VwIGFuZCByZXR1cm5zIGEgbGlzdGVuYWJsZSBmdXR1cmUgdG8gdHJhY2sgaXQuIFRoZQorICAgKiBMaXN0ZW5hYmxlRnV0dXJlIHJlc29sdmVzIHRvIHRoZSBub24tbnVsbCBEYXRhRmlsZUdyb3VwIGlmIHRoZSBncm91cCBpcyBzdWNjZXNzZnVsbHkKKyAgICogZG93bmxvYWRlZC4gT3RoZXJ3aXNlIGl0IHJldHVybnMgYSBudWxsLgorICAgKgorICAgKiBAcGFyYW0gZ3JvdXBLZXkgVGhlIGtleSBvZiB0aGUgZ3JvdXAgdG8gc2NoZWR1bGUgZm9yIGRvd25sb2FkLgorICAgKiBAcGFyYW0gZG93bmxvYWRDb25kaXRpb25zIFRoZSBkb3dubG9hZCBjb25kaXRpb25zIHRoYXQgd2Ugc2hvdWxkIGRvd25sb2FkIHRoZSBncm91cCB1bmRlci4KKyAgICogQHJldHVybiB0aGUgTGlzdGVuYWJsZUZ1dHVyZSBvZiB0aGUgZG93bmxvYWQgb2YgYWxsIGZpbGVzIGluIHRoZSBmaWxlIGdyb3VwLgorICAgKi8KKyAgLy8gVE9ETyhiLzEyNDA3Mjc1NCk6IENoYW5nZSB0byBwYWNrYWdlIHByaXZhdGUgb25jZSBhbGwgY29kZSBpcyByZWZhY3RvcmVkLgorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRvd25sb2FkRmlsZUdyb3VwKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksCisgICAgICBATnVsbGFibGUgRG93bmxvYWRDb25kaXRpb25zIGRvd25sb2FkQ29uZGl0aW9uc1BhcmFtLAorICAgICAgQXN5bmNGdW5jdGlvbjxEYXRhRmlsZUdyb3VwSW50ZXJuYWwsIEJvb2xlYW4+IGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvcikgeworCisgICAgLy8gQ2FwdHVyZSBhIHJlZmVyZW5jZSB0byB0aGUgRGF0YUZpbGVHcm91cCBzbyB3ZSBjYW4gaW5jbHVkZSBidWlsZCBpZCBhbmQgdmFyaWFudCBpZCBpbiBvdXIKKyAgICAvLyBsb2dzLgorICAgIEF0b21pY1JlZmVyZW5jZTxATnVsbGFibGVUeXBlIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZmlsZUdyb3VwRm9yTG9nZ2luZyA9CisgICAgICAgIG5ldyBBdG9taWNSZWZlcmVuY2U8PigpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgZ2V0RmlsZUdyb3VwKGdyb3VwS2V5LCBmYWxzZSAvKiBkb3dubG9hZGVkICovKSwKKyAgICAgICAgICAgIHBlbmRpbmdHcm91cCAtPiB7CisgICAgICAgICAgICAgIGlmIChwZW5kaW5nR3JvdXAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIFRoZXJlIGlzIG5vIHBlbmRpbmcgZ3JvdXAuIFNlZSBpZiB0aGVyZSBpcyBhIGRvd25sb2FkZWQgdmVyc2lvbiBhbmQgcmV0dXJuIGlmIGl0CisgICAgICAgICAgICAgICAgLy8gZXhpc3RzLgorICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgIGdldEZpbGVHcm91cChncm91cEtleSwgdHJ1ZSAvKiBkb3dubG9hZGVkICovKSwKKyAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRlZEdyb3VwIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICBpZiAoZG93bmxvYWRlZEdyb3VwID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLkdST1VQX05PVF9GT1VORF9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldE1lc3NhZ2UoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm90aGluZyB0byBkb3dubG9hZCBmb3IgZmlsZSBncm91cDogIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZ3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwRm9yTG9nZ2luZy5zZXQoZG93bmxvYWRlZEdyb3VwKTsKKyAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRnV0dXJlKGRvd25sb2FkZWRHcm91cCk7CisgICAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGZpbGVHcm91cEZvckxvZ2dpbmcuc2V0KHBlbmRpbmdHcm91cCk7CisKKyAgICAgICAgICAgICAgLy8gU2V0IHRoZSBkb3dubG9hZCBzdGFydGVkIHRpbWVzdGFtcCBhbmQgbG9nIGRvd25sb2FkIHN0YXJ0ZWQgZXZlbnQuCisgICAgICAgICAgICAgIHJldHVybiBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlLmZyb20oCisgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlQm9va2tlZXBpbmdPblN0YXJ0RG93bmxvYWQoZ3JvdXBLZXksIHBlbmRpbmdHcm91cCkpCisgICAgICAgICAgICAgICAgICAuY2F0Y2hpbmdBc3luYygKKyAgICAgICAgICAgICAgICAgICAgICBJT0V4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgICBleCAtPgorICAgICAgICAgICAgICAgICAgICAgICAgICBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEb3dubG9hZFJlc3VsdENvZGUuVU5BQkxFX1RPX1VQREFURV9HUk9VUF9NRVRBREFUQV9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0Q2F1c2UoZXgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpLAorICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgICAgICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZFBlbmRpbmdHcm91cCAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICBMaXN0PExpc3RlbmFibGVGdXR1cmU8Vm9pZD4+IGFsbEZpbGVGdXR1cmVzID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydERvd25sb2FkRnV0dXJlcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRDb25kaXRpb25zUGFyYW0sIHVwZGF0ZWRQZW5kaW5nR3JvdXAsIGdyb3VwS2V5KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGU6IFdlIHVzZSB3aGVuQWxsQ29tcGxldGUgaW5zdGVhZCBvZiB3aGVuQWxsU3VjY2VlZCBzaW5jZSB3ZSB3YW50IHRvCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb250aW51ZSB0byBkb3dubG9hZCBhbGwgb3RoZXIgZmlsZXMgZXZlbiBpZiBvbmUgb3IgbW9yZSBmYWlsLiBWZXJpZnkgdGhlCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlIGdyb3VwLgorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLndoZW5BbGxDb21wbGV0ZShhbGxGaWxlRnV0dXJlcykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2FsbEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeVBlbmRpbmdHcm91cERvd25sb2FkZWQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkUGVuZGluZ0dyb3VwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwRG93bmxvYWRTdGF0dXMgLT4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxpemVEb3dubG9hZEZpbGVGdXR1cmVzKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsRmlsZUZ1dHVyZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cERvd25sb2FkU3RhdHVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZFBlbmRpbmdHcm91cCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5KSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICB9KTsKKworICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy5jYXRjaGluZ0FzeW5jKAorICAgICAgICBkb3dubG9hZEZ1dHVyZSwKKyAgICAgICAgRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICBleGNlcHRpb24gLT4geworICAgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkZmdJbnRlcm5hbCA9IGZpbGVHcm91cEZvckxvZ2dpbmcuZ2V0KCk7CisKKyAgICAgICAgICBmaW5hbCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmluYWxEZmdJbnRlcm5hbCA9CisgICAgICAgICAgICAgIChkZmdJbnRlcm5hbCA9PSBudWxsKSA/IERhdGFGaWxlR3JvdXBJbnRlcm5hbC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGRmZ0ludGVybmFsOworCisgICAgICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiByZXN1bHRGdXR1cmUgPSBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgaWYgKGV4Y2VwdGlvbiBpbnN0YW5jZW9mIERvd25sb2FkRXhjZXB0aW9uKSB7CisgICAgICAgICAgICBMb2dVdGlsLmQoIiVzOiBMb2dnaW5nIERvd25sb2FkRXhjZXB0aW9uIiwgVEFHKTsKKworICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24gZG93bmxvYWRFeGNlcHRpb24gPSAoRG93bmxvYWRFeGNlcHRpb24pIGV4Y2VwdGlvbjsKKyAgICAgICAgICAgIHJlc3VsdEZ1dHVyZSA9CisgICAgICAgICAgICAgICAgdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgICByZXN1bHRGdXR1cmUsCisgICAgICAgICAgICAgICAgICAgIHZvaWRBcmcgLT4KKyAgICAgICAgICAgICAgICAgICAgICAgIGxvZ0Rvd25sb2FkRmFpbHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cEtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZEV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbERmZ0ludGVybmFsLmdldEJ1aWxkSWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbERmZ0ludGVybmFsLmdldFZhcmlhbnRJZCgpKSk7CisgICAgICAgICAgfSBlbHNlIGlmIChleGNlcHRpb24gaW5zdGFuY2VvZiBBZ2dyZWdhdGVFeGNlcHRpb24pIHsKKyAgICAgICAgICAgIExvZ1V0aWwuZCgiJXM6IExvZ2dpbmcgQWdncmVnYXRlRXhjZXB0aW9uIiwgVEFHKTsKKworICAgICAgICAgICAgQWdncmVnYXRlRXhjZXB0aW9uIGFnZ3JlZ2F0ZUV4Y2VwdGlvbiA9IChBZ2dyZWdhdGVFeGNlcHRpb24pIGV4Y2VwdGlvbjsKKyAgICAgICAgICAgIGZvciAoVGhyb3dhYmxlIHRocm93YWJsZSA6IGFnZ3JlZ2F0ZUV4Y2VwdGlvbi5nZXRGYWlsdXJlcygpKSB7CisgICAgICAgICAgICAgIGlmICghKHRocm93YWJsZSBpbnN0YW5jZW9mIERvd25sb2FkRXhjZXB0aW9uKSkgeworICAgICAgICAgICAgICAgIExvZ1V0aWwuZSgiJXM6IEV4cGVjdGluZyBEb3dubG9hZEV4Y2VwdGlvbidzIGluIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiIsIFRBRyk7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbiBkb3dubG9hZEV4Y2VwdGlvbiA9IChEb3dubG9hZEV4Y2VwdGlvbikgdGhyb3dhYmxlOworICAgICAgICAgICAgICByZXN1bHRGdXR1cmUgPQorICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdEZ1dHVyZSwKKyAgICAgICAgICAgICAgICAgICAgICB2b2lkQXJnIC0+CisgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ0Rvd25sb2FkRmFpbHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRFeGNlcHRpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbERmZ0ludGVybmFsLmdldEJ1aWxkSWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsRGZnSW50ZXJuYWwuZ2V0VmFyaWFudElkKCkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgcmVzdWx0RnV0dXJlLAorICAgICAgICAgICAgICB2b2lkQXJnIC0+IHsKKyAgICAgICAgICAgICAgICB0aHJvdyBleGNlcHRpb247CisgICAgICAgICAgICAgIH0pOworICAgICAgICB9LAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PiBzdGFydERvd25sb2FkRnV0dXJlcygKKyAgICAgIEBOdWxsYWJsZSBEb3dubG9hZENvbmRpdGlvbnMgZG93bmxvYWRDb25kaXRpb25zLAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdHcm91cCwKKyAgICAgIEdyb3VwS2V5IGdyb3VwS2V5KSB7CisgICAgLy8gSWYgYWJzZW50LCB1c2UgdGhlIGNvbmZpZyBmcm9tIHNlcnZlci4KKyAgICBEb3dubG9hZENvbmRpdGlvbnMgZG93bmxvYWRDb25kaXRpb25zRmluYWwgPQorICAgICAgICBkb3dubG9hZENvbmRpdGlvbnMgIT0gbnVsbCA/IGRvd25sb2FkQ29uZGl0aW9ucyA6IHBlbmRpbmdHcm91cC5nZXREb3dubG9hZENvbmRpdGlvbnMoKTsKKworICAgIExpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4gYWxsRmlsZUZ1dHVyZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBmb3IgKERhdGFGaWxlIGRhdGFGaWxlIDogcGVuZGluZ0dyb3VwLmdldEZpbGVMaXN0KCkpIHsKKyAgICAgIC8vIFNraXAgc2lkZWxvYWRlZCBmaWxlcyAtLSB0aGV5LCBieSBkZWZpbml0aW9uLCBjYW4ndCBiZSBkb3dubG9hZGVkLgorICAgICAgaWYgKEZpbGVHcm91cFV0aWwuaXNTaWRlbG9hZGVkRmlsZShkYXRhRmlsZSkpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGRhdGFGaWxlLCBwZW5kaW5nR3JvdXAuZ2V0QWxsb3dlZFJlYWRlcnNFbnVtKCkpOworICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBmaWxlRnV0dXJlOworICAgICAgaWYgKFZFUlNJT04uU0RLX0lOVCA+PSBWRVJTSU9OX0NPREVTLlIpIHsKKyAgICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiB0cnlUb1NoYXJlQmVmb3JlRG93bmxvYWQgPQorICAgICAgICAgICAgdHJ5VG9TaGFyZUJlZm9yZURvd25sb2FkKHBlbmRpbmdHcm91cCwgZGF0YUZpbGUsIG5ld0ZpbGVLZXkpOworICAgICAgICBmaWxlRnV0dXJlID0KKyAgICAgICAgICAgIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICB0cnlUb1NoYXJlQmVmb3JlRG93bmxvYWQsCisgICAgICAgICAgICAgICAgKHZvaWRBcmcpIC0+IHsKKyAgICAgICAgICAgICAgICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gc3RhcnREb3dubG9hZEZ1dHVyZTsKKyAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIHN0YXJ0RG93bmxvYWRGdXR1cmUgPQorICAgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZU1hbmFnZXIuc3RhcnREb3dubG9hZCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cEtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkQ29uZGl0aW9uc0ZpbmFsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlbmRpbmdHcm91cC5nZXRUcmFmZmljVGFnKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0dyb3VwLmdldEdyb3VwRXh0cmFIdHRwSGVhZGVyc0xpc3QoKSk7CisgICAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gQ2F0Y2ggYW55IHVuY2hlY2tlZCBleGNlcHRpb25zIHRoYXQgcHJldmVudGVkIHRoZSBkb3dubG9hZCBmcm9tIHN0YXJ0aW5nLgorICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0Q2F1c2UoZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAvLyBBZnRlciBmaWxlIGFzIGJlaW5nIGRvd25sb2FkZWQgbG9jYWxseQorICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgICBzdGFydERvd25sb2FkRnV0dXJlLAorICAgICAgICAgICAgICAgICAgICAgIChkb3dubG9hZFJlc3VsdCkgLT4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5VG9TaGFyZUFmdGVyRG93bmxvYWQocGVuZGluZ0dyb3VwLCBkYXRhRmlsZSwgbmV3RmlsZUtleSkpOworICAgICAgICAgICAgICAgIH0pOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdHJ5IHsKKyAgICAgICAgICBmaWxlRnV0dXJlID0KKyAgICAgICAgICAgICAgc2hhcmVkRmlsZU1hbmFnZXIuc3RhcnREb3dubG9hZCgKKyAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgICAgICAgZGF0YUZpbGUsCisgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LAorICAgICAgICAgICAgICAgICAgZG93bmxvYWRDb25kaXRpb25zRmluYWwsCisgICAgICAgICAgICAgICAgICBwZW5kaW5nR3JvdXAuZ2V0VHJhZmZpY1RhZygpLAorICAgICAgICAgICAgICAgICAgcGVuZGluZ0dyb3VwLmdldEdyb3VwRXh0cmFIdHRwSGVhZGVyc0xpc3QoKSk7CisgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgeworICAgICAgICAgIC8vIENhdGNoIGFueSB1bmNoZWNrZWQgZXhjZXB0aW9ucyB0aGF0IHByZXZlbnRlZCB0aGUgZG93bmxvYWQgZnJvbSBzdGFydGluZy4KKyAgICAgICAgICBmaWxlRnV0dXJlID0KKyAgICAgICAgICAgICAgaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgICAuc2V0Q2F1c2UoZSkKKyAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGFsbEZpbGVGdXR1cmVzLmFkZChmaWxlRnV0dXJlKTsKKyAgICB9CisgICAgcmV0dXJuIGFsbEZpbGVGdXR1cmVzOworICB9CisKKyAgLy8gUmVxdWlyZXMgdGhhdCBhbGwgZnV0dXJlcyBpbiBhbGxGaWxlRnV0dXJlcyBhcmUgY29tcGxldGVkLgorICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8RGF0YUZpbGVHcm91cEludGVybmFsPiBmaW5hbGl6ZURvd25sb2FkRmlsZUZ1dHVyZXMoCisgICAgICBMaXN0PExpc3RlbmFibGVGdXR1cmU8Vm9pZD4+IGFsbEZpbGVGdXR1cmVzLAorICAgICAgR3JvdXBEb3dubG9hZFN0YXR1cyBncm91cERvd25sb2FkU3RhdHVzLAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdHcm91cCwKKyAgICAgIEdyb3VwS2V5IGdyb3VwS2V5KQorICAgICAgdGhyb3dzIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiwgRG93bmxvYWRFeGNlcHRpb24geworICAgIC8vIFRPRE8oYi8xMzYxMTI4NDgpOiBXaGVuIGFsbCBmaWxlRnV0dXJlcyBzdWNjZWVkLCB3ZSBkb24ndCBuZWVkIHRvIHZlcmlmeSB0aGVtIGFnYWluLiBIb3dldmVyCisgICAgLy8gd2Ugc3RpbGwgbmVlZCBsb2dpYyB0byByZW1vdmUgcGVuZGluZyBhbmQgdXBkYXRlIHN0YWxlIGdyb3VwLgorICAgIGlmIChncm91cERvd25sb2FkU3RhdHVzICE9IEdyb3VwRG93bmxvYWRTdGF0dXMuRE9XTkxPQURFRCkgeworICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICIlcyBkb3dubG9hZEZpbGVHcm91cCAlcyAlcyBjYW4ndCBmaW5pc2ghIiwKKyAgICAgICAgICBUQUcsIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpLCBncm91cEtleS5nZXRPd25lclBhY2thZ2UoKSk7CisKKyAgICAgIEFnZ3JlZ2F0ZUV4Y2VwdGlvbi50aHJvd0lmRmFpbGVkKAorICAgICAgICAgIGFsbEZpbGVGdXR1cmVzLCAiRmFpbGVkIHRvIGRvd25sb2FkIGZpbGUgZ3JvdXAgJXMiLCBncm91cEtleS5nZXRHcm91cE5hbWUoKSk7CisKKyAgICAgIC8vIFRPRE8oYi8xMTgxMzc2NzIpOiBJbnZlc3RpZ2F0ZSBvbiB0aGUgdW5rbm93biBlcnJvciB0aGF0IHdlJ3ZlIG1pc3NlZC4gVGhlcmUgaXMgYSBkb3dubG9hZAorICAgICAgLy8gZmFpbHVyZSB0aGF0IHdlIGRvbid0IHJlY29nbml6ZS4KKyAgICAgIExvZ1V0aWwuZSgiJXM6IEFuIHVua25vd24gZXJyb3IgaGFzIG9jY3VycmVkIGR1cmluZyIgKyAiIGRvd25sb2FkIiwgVEFHKTsKKyAgICAgIHRocm93IERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLlVOS05PV05fRVJST1IpCisgICAgICAgICAgLmJ1aWxkKCk7CisgICAgfQorCisgICAgZXZlbnRMb2dnZXIubG9nTWRkRG93bmxvYWRSZXN1bHQoMCwgbnVsbCk7CisgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShwZW5kaW5nR3JvdXApOworICB9CisKKyAgLyoqCisgICAqIElmIHRoZSBmaWxlIGlzIGF2YWlsYWJsZSBpbiB0aGUgc2hhcmVkIGJsb2Igc3RvcmFnZSwgaXQgYWNxdWlyZXMgdGhlIGxlYXNlIGFuZCB1cGRhdGVzIHRoZQorICAgKiBzaGFyZWQgZmlsZSBtZXRhZGF0YS4gVGhlIHtAY29kZSBGaWxlU3RhdHVzfSB3aWxsIGJlIHNldCB0byBET1dOTE9BRF9DT01QTEVURSBzbyB0aGF0IHRoZSBmaWxlCisgICAqIHdvbid0IGJlIGRvd25sb2FkZWQgYWdhaW4uCisgICAqCisgICAqIDxwPlRoZSBmaWxlIGlzIGF2YWlsYWJsZSBpbiB0aGUgc2hhcmVkIGJsb2Igc3RvcmFnZSBpZjoKKyAgICoKKyAgICogPHVsPgorICAgKiAgIDxsaT50aGUgZmlsZSBpcyBhbHJlYWR5IGF2YWlsYWJsZSBpbiB0aGUgc2hhcmVkIHN0b3JhZ2UsIG9yCisgICAqICAgPGxpPnRoZSBmaWxlIGNhbiBiZSBjb3BpZWQgZnJvbSB0aGUgbG9jYWwgTUREIHN0b3JhZ2UgdG8gdGhlIHNoYXJlZCBzdG9yYWdlCisgICAqIDwvdWw+CisgICAqCisgICAqIE5PVEU6IHdlIGNvcHkgdGhlIGZpbGUgb25seSBpZiB0aGUgZmlsZSBpcyBjb25maWd1cmVkIHRvIGJlIHNoYXJlZCB0aHJvdWdoIHRoZSB7QGNvZGUKKyAgICogYW5kcm9pZF9zaGFyaW5nX3R5cGV9IGZpZWxkLgorICAgKgorICAgKiA8cD5OT1RFOiBhbmRyb2lkLXNoYXJpbmcgaXMgYSBiZXN0IGVmZm9ydCBmZWF0dXJlLCBoZW5jZSBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgdHJ5aW5nIHRvCisgICAqIHNoYXJlIGEgZmlsZSwgdGhlIGRvd25sb2FkIG9wZXJhdGlvbiB3b24ndCBiZSBzdG9wcGVkLgorICAgKgorICAgKiBAcmV0dXJuIExpc3RlbmFibGVGdXR1cmUgdGhhdCBtYXkgdGhyb3cgYSBTaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbiBpZiB0aGUgc2hhcmVkIGZpbGUKKyAgICogICAgIG1ldGFkYXRhIGlzIG1pc3NpbmcuCisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHRyeVRvU2hhcmVCZWZvcmVEb3dubG9hZCgKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAsIERhdGFGaWxlIGRhdGFGaWxlLCBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkpIHsKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFNoYXJlZEZpbGU+IHNoYXJlZEZpbGVGdXR1cmUgPQorICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy5jYXRjaGluZ0FzeW5jKAorICAgICAgICAgICAgc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KSwKKyAgICAgICAgICAgIFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgZSAtPiB7CisgICAgICAgICAgICAgIC8vIFRPRE8oYi8xMzExNjY5MjUpOiBNREQgZHVtcCBzaG91bGQgbm90IHVzZSBsaXRlIHByb3RvIHRvU3RyaW5nLgorICAgICAgICAgICAgICBMb2dVdGlsLmUoIiVzOiBTaGFyZWQgZmlsZSBub3QgZm91bmQsIG5ld0ZpbGVLZXkgPSAlcyIsIFRBRywgbmV3RmlsZUtleSk7CisgICAgICAgICAgICAgIHNpbGVudEZlZWRiYWNrLnNlbmQoZSwgIlNoYXJlZCBmaWxlIG5vdCBmb3VuZCBpbiBkb3dubG9hZEZpbGVHcm91cCIpOworICAgICAgICAgICAgICBsb2dNZGRBbmRyb2lkU2hhcmluZ0xvZyhldmVudExvZ2dlciwgZmlsZUdyb3VwLCBkYXRhRmlsZSwgMCk7CisgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoZSk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgc2hhcmVkRmlsZUZ1dHVyZSwKKyAgICAgICAgc2hhcmVkRmlsZSAtPiB7CisgICAgICAgICAgbG9uZyBmaWxlRXhwaXJhdGlvbkRhdGVTZWNzID0gZmlsZUdyb3VwLmdldEV4cGlyYXRpb25EYXRlU2VjcygpOworICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAvLyBjYXNlIDE6IHRoZSBmaWxlIGlzIGFscmVhZHkgc2hhcmVkIGluIHRoZSBibG9iIHN0b3JhZ2UuCisgICAgICAgICAgICBpZiAoc2hhcmVkRmlsZS5nZXRBbmRyb2lkU2hhcmVkKCkpIHsKKyAgICAgICAgICAgICAgTG9nVXRpbC5kKAorICAgICAgICAgICAgICAgICAgIiVzOiBBbmRyb2lkIHNoYXJpbmcgQ0FTRSAxIGZvciBmaWxlICVzLCBmaWxlZ3JvdXAgJXMiLAorICAgICAgICAgICAgICAgICAgVEFHLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgIG1heWJlVXBkYXRlTGVhc2VBbmRTaGFyZWRNZXRhZGF0YSgKKyAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LAorICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLAorICAgICAgICAgICAgICAgICAgICAgIGZpbGVFeHBpcmF0aW9uRGF0ZVNlY3MsCisgICAgICAgICAgICAgICAgICAgICAgMCksCisgICAgICAgICAgICAgICAgICByZXMgLT4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgU3RyaW5nIGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0gPSBkYXRhRmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCk7CisgICAgICAgICAgICBpZiAoIVRleHRVdGlscy5pc0VtcHR5KGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0pKSB7CisgICAgICAgICAgICAgIC8vIGNhc2UgMjogdGhlIGZpbGUgaXMgYXZhaWxhYmxlIGluIHRoZSBibG9iIHN0b3JhZ2UuCisgICAgICAgICAgICAgIGlmIChBbmRyb2lkU2hhcmluZ1V0aWwuYmxvYkV4aXN0cygKKyAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0sIGZpbGVHcm91cCwgZGF0YUZpbGUsIGZpbGVTdG9yYWdlKSkgeworICAgICAgICAgICAgICAgIExvZ1V0aWwuZCgKKyAgICAgICAgICAgICAgICAgICAgIiVzOiBBbmRyb2lkIHNoYXJpbmcgQ0FTRSAyIGZvciBmaWxlICVzLCBmaWxlZ3JvdXAgJXMiLAorICAgICAgICAgICAgICAgICAgICBUQUcsIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgIG1heWJlVXBkYXRlTGVhc2VBbmRTaGFyZWRNZXRhZGF0YSgKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZpbGVLZXksCisgICAgICAgICAgICAgICAgICAgICAgICBhbmRyb2lkU2hhcmluZ0NoZWNrc3VtLAorICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUV4cGlyYXRpb25EYXRlU2VjcywKKyAgICAgICAgICAgICAgICAgICAgICAgIDApLAorICAgICAgICAgICAgICAgICAgICByZXMgLT4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIC8vIGNhc2UgMzogdGhlIHRvLWJlLXNoYXJlZCBmaWxlIGlzIGF2YWlsYWJsZSBpbiB0aGUgbG9jYWwgc3RvcmFnZS4KKyAgICAgICAgICAgICAgaWYgKGRhdGFGaWxlLmdldEFuZHJvaWRTaGFyaW5nVHlwZSgpCisgICAgICAgICAgICAgICAgICAgICAgPT0gRGF0YUZpbGUuQW5kcm9pZFNoYXJpbmdUeXBlLkFORFJPSURfQkxPQl9XSEVOX0FWQUlMQUJMRQorICAgICAgICAgICAgICAgICAgJiYgc2hhcmVkRmlsZS5nZXRGaWxlU3RhdHVzKCkgPT0gRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkgeworICAgICAgICAgICAgICAgIExvZ1V0aWwuZCgKKyAgICAgICAgICAgICAgICAgICAgIiVzOiBBbmRyb2lkIHNoYXJpbmcgQ0FTRSAzIGZvciBmaWxlICVzLCBmaWxlZ3JvdXAgJXMiLAorICAgICAgICAgICAgICAgICAgICBUQUcsIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICAgIFVyaSBkb3dubG9hZEZpbGVPbkRldmljZVVyaSA9IGdldExvY2FsVXJpKGRhdGFGaWxlLCBuZXdGaWxlS2V5LCBzaGFyZWRGaWxlKTsKKyAgICAgICAgICAgICAgICBBbmRyb2lkU2hhcmluZ1V0aWwuY29weUZpbGVUb0Jsb2JTdG9yZSgKKyAgICAgICAgICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSwKKyAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRGaWxlT25EZXZpY2VVcmksCisgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUsCisgICAgICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgICAgICAgICAvKiBhZnRlckRvd25sb2FkID0gKi8gZmFsc2UpOworICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgIG1heWJlVXBkYXRlTGVhc2VBbmRTaGFyZWRNZXRhZGF0YSgKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZpbGVLZXksCisgICAgICAgICAgICAgICAgICAgICAgICBhbmRyb2lkU2hhcmluZ0NoZWNrc3VtLAorICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUV4cGlyYXRpb25EYXRlU2VjcywKKyAgICAgICAgICAgICAgICAgICAgICAgIDApLAorICAgICAgICAgICAgICAgICAgICByZXMgLT4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgIH0gY2F0Y2ggKEFuZHJvaWRTaGFyaW5nRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIGxvZ01kZEFuZHJvaWRTaGFyaW5nTG9nKGV2ZW50TG9nZ2VyLCBmaWxlR3JvdXAsIGRhdGFGaWxlLCBlLmdldEVycm9yQ29kZSgpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgTG9nVXRpbC5kKAorICAgICAgICAgICAgICAiJXM6IEZpbGUgY291bGRuJ3QgYmUgc2hhcmVkIGJlZm9yZSBkb3dubG9hZCAlcywgZmlsZWdyb3VwICVzIiwKKyAgICAgICAgICAgICAgVEFHLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICB9KTsKKyAgfQorCisgIC8qKgorICAgKiBJZiBzaGFyaW5nIHRoZSBmaWxlIHN1Y2NlZWRzLCBpdCBhY3F1aXJlcyB0aGUgbGVhc2UsIHVwZGF0ZXMgdGhlIGZpbGUgc3RhdHVzIGFuZCBkZWxldGVzIHRoZQorICAgKiBsb2NhbCBjb3B5LgorICAgKgorICAgKiA8cD5TaGFyaW5nIHRoZSBmaWxlIHN1Y2NlZWRzIGlmOgorICAgKgorICAgKiA8dWw+CisgICAqICAgPGxpPnRoZSBmaWxlIGlzIGFscmVhZHkgYXZhaWxhYmxlIGluIHRoZSBzaGFyZWQgc3RvcmFnZSwgb3IKKyAgICogICA8bGk+dGhlIGZpbGUgY2FuIGJlIGNvcGllZCBmcm9tIHRoZSBsb2NhbCBNREQgc3RvcmFnZSB0byB0aGUgc2hhcmVkIHN0b3JhZ2UKKyAgICogPC91bD4KKyAgICoKKyAgICogTk9URTogd2UgY29weSB0aGUgZmlsZSBvbmx5IGlmIHRoZSBmaWxlIGlzIGNvbmZpZ3VyZWQgdG8gYmUgc2hhcmVkIHRocm91Z2ggdGhlIHtAY29kZQorICAgKiBhbmRyb2lkX3NoYXJpbmdfdHlwZX0gZmllbGQuCisgICAqCisgICAqIDxwPk5PVEU6IGFuZHJvaWQtc2hhcmluZyBpcyBhIGJlc3QgZWZmb3J0IGZlYXR1cmUsIGhlbmNlIGlmIHRoZSBmaWxlIHdhcyBkb3dubGFvZGVkCisgICAqIHN1Y2Nlc3NmdWxseSBhbmQgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHRyeWluZyB0byBzaGFyZSBpdCwgdGhlIGZpbGUgd2lsbCBiZSBzdG9yZWQgbG9jYWxseS4KKyAgICoKKyAgICogQHJldHVybiBMaXN0ZW5hYmxlRnV0dXJlIHRoYXQgbWF5IHRocm93IGEgU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24gaWYgdGhlIHNoYXJlZCBmaWxlCisgICAqICAgICBtZXRhZGF0YSBpcyBtaXNzaW5nLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiB0cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZCgKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAsIERhdGFGaWxlIGRhdGFGaWxlLCBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkpIHsKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFNoYXJlZEZpbGU+IHNoYXJlZEZpbGVGdXR1cmUgPQorICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy5jYXRjaGluZ0FzeW5jKAorICAgICAgICAgICAgc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KSwKKyAgICAgICAgICAgIFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgZSAtPiB7CisgICAgICAgICAgICAgIC8vIFRPRE8oYi8xMzExNjY5MjUpOiBNREQgZHVtcCBzaG91bGQgbm90IHVzZSBsaXRlIHByb3RvIHRvU3RyaW5nLgorICAgICAgICAgICAgICBMb2dVdGlsLmUoIiVzOiBTaGFyZWQgZmlsZSBub3QgZm91bmQsIG5ld0ZpbGVLZXkgPSAlcyIsIFRBRywgbmV3RmlsZUtleSk7CisgICAgICAgICAgICAgIHNpbGVudEZlZWRiYWNrLnNlbmQoZSwgIlNoYXJlZCBmaWxlIG5vdCBmb3VuZCBpbiBkb3dubG9hZEZpbGVHcm91cCIpOworICAgICAgICAgICAgICBsb2dNZGRBbmRyb2lkU2hhcmluZ0xvZyhldmVudExvZ2dlciwgZmlsZUdyb3VwLCBkYXRhRmlsZSwgMCk7CisgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoZSk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgc2hhcmVkRmlsZUZ1dHVyZSwKKyAgICAgICAgc2hhcmVkRmlsZSAtPiB7CisgICAgICAgICAgU3RyaW5nIGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0gPSBkYXRhRmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCk7CisgICAgICAgICAgbG9uZyBmaWxlRXhwaXJhdGlvbkRhdGVTZWNzID0gZmlsZUdyb3VwLmdldEV4cGlyYXRpb25EYXRlU2VjcygpOworICAgICAgICAgIC8vIE5PVEU6IGlmIHRoZSBmaWxlIHdhc24ndCBkb3dubG9hZGVkIHRoaXMgbWV0aG9kIHNob3VsZCBiZSBuby1vcC4KKyAgICAgICAgICBpZiAoc2hhcmVkRmlsZS5nZXRGaWxlU3RhdHVzKCkgIT0gRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkgeworICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICBpZiAoc2hhcmVkRmlsZS5nZXRBbmRyb2lkU2hhcmVkKCkpIHsKKyAgICAgICAgICAgIC8vIElmIHRoZSBmaWxlIGhhZCBiZWVuIGFuZHJvaWQtc2hhcmVkIGluIGFub3RoZXIgZmlsZSBncm91cCB3aGlsZSB0aGlzIGZpbGUgaW5zdGFuY2UKKyAgICAgICAgICAgIC8vIHdhcyBiZWluZyBkb3dubG9hZGVkLCB1cGRhdGUgdGhlIGxlYXNlIGlmIG5lY2Vzc2FyeS4KKyAgICAgICAgICAgIGlmIChzaG91bGRVcGRhdGVNYXhFeHBpcnlEYXRlKHNoYXJlZEZpbGUsIGZpbGVFeHBpcmF0aW9uRGF0ZVNlY3MpKSB7CisgICAgICAgICAgICAgIExvZ1V0aWwuZCgKKyAgICAgICAgICAgICAgICAgICIlczogRmlsZSBhbHJlYWR5IHNoYXJlZCBhZnRlciBkb3dubG9hZGVkIGJ1dCBsZWFzZSBoYXMgdG8gYmUgdXBkYXRlZCIKKyAgICAgICAgICAgICAgICAgICAgICArICIgZm9yIGZpbGUgJXMsIGZpbGVncm91cCAlcyIsCisgICAgICAgICAgICAgICAgICBUQUcsIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgbWF5YmVVcGRhdGVMZWFzZUFuZFNoYXJlZE1ldGFkYXRhKAorICAgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlLAorICAgICAgICAgICAgICAgICAgICAgIG5ld0ZpbGVLZXksCisgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCksCisgICAgICAgICAgICAgICAgICAgICAgZmlsZUV4cGlyYXRpb25EYXRlU2VjcywKKyAgICAgICAgICAgICAgICAgICAgICAwKSwKKyAgICAgICAgICAgICAgICAgIHJlcyAtPiB7CisgICAgICAgICAgICAgICAgICAgIGlmICghcmVzKSB7CisgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZU1heEV4cGlyYXRpb25EYXRlU2VjcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwLCBkYXRhRmlsZSwgbmV3RmlsZUtleSwgZmlsZUV4cGlyYXRpb25EYXRlU2Vjcyk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICB9CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGlmICghVGV4dFV0aWxzLmlzRW1wdHkoYW5kcm9pZFNoYXJpbmdDaGVja3N1bSkpIHsKKyAgICAgICAgICAgICAgVXJpIGRvd25sb2FkRmlsZU9uRGV2aWNlVXJpID0gZ2V0TG9jYWxVcmkoZGF0YUZpbGUsIG5ld0ZpbGVLZXksIHNoYXJlZEZpbGUpOworICAgICAgICAgICAgICAvLyBjYXNlIDE6IHRoZSBmaWxlIGlzIGF2YWlsYWJsZSBpbiB0aGUgYmxvYiBzdG9yYWdlLgorICAgICAgICAgICAgICBpZiAoQW5kcm9pZFNoYXJpbmdVdGlsLmJsb2JFeGlzdHMoCisgICAgICAgICAgICAgICAgICBjb250ZXh0LCBhbmRyb2lkU2hhcmluZ0NoZWNrc3VtLCBmaWxlR3JvdXAsIGRhdGFGaWxlLCBmaWxlU3RvcmFnZSkpIHsKKyAgICAgICAgICAgICAgICBMb2dVdGlsLmQoCisgICAgICAgICAgICAgICAgICAgICIlczogQW5kcm9pZCBzaGFyaW5nIGFmdGVyIGRvd25sb2FkZWQsIENBU0UgMSBmb3IgZmlsZSAlcywgZmlsZWdyb3VwICVzIiwKKyAgICAgICAgICAgICAgICAgICAgVEFHLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgICBtYXliZVVwZGF0ZUxlYXNlQW5kU2hhcmVkTWV0YWRhdGEoCisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVFeHBpcmF0aW9uRGF0ZVNlY3MsCisgICAgICAgICAgICAgICAgICAgICAgICAwKSwKKyAgICAgICAgICAgICAgICAgICAgcmVzIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGVMb2NhbENvcHkoZG93bmxvYWRGaWxlT25EZXZpY2VVcmksIGZpbGVHcm91cCwgZGF0YUZpbGUpOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZU1heEV4cGlyYXRpb25EYXRlU2VjcygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwLCBkYXRhRmlsZSwgbmV3RmlsZUtleSwgZmlsZUV4cGlyYXRpb25EYXRlU2Vjcyk7CisgICAgICAgICAgICAgICAgICAgIH0pOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgLy8gY2FzZSAyOiB0aGUgZmlsZSBpcyBjb25maWd1cmVkIHRvIGJlIHNoYXJlZC4KKyAgICAgICAgICAgICAgaWYgKGRhdGFGaWxlLmdldEFuZHJvaWRTaGFyaW5nVHlwZSgpCisgICAgICAgICAgICAgICAgICA9PSBEYXRhRmlsZS5BbmRyb2lkU2hhcmluZ1R5cGUuQU5EUk9JRF9CTE9CX1dIRU5fQVZBSUxBQkxFKSB7CisgICAgICAgICAgICAgICAgTG9nVXRpbC5kKAorICAgICAgICAgICAgICAgICAgICAiJXM6IEFuZHJvaWQgc2hhcmluZyBhZnRlciBkb3dubG9hZGVkLCBDQVNFIDIgZm9yIGZpbGUgJXMsIGZpbGVncm91cCAlcyIsCisgICAgICAgICAgICAgICAgICAgIFRBRywgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICAgICAgICAgICAgQW5kcm9pZFNoYXJpbmdVdGlsLmNvcHlGaWxlVG9CbG9iU3RvcmUoCisgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgIGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0sCisgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZU9uRGV2aWNlVXJpLAorICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLAorICAgICAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgICAgICAgICAgLyogYWZ0ZXJEb3dubG9hZCA9ICovIHRydWUpOworICAgICAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgICAgICAgIG1heWJlVXBkYXRlTGVhc2VBbmRTaGFyZWRNZXRhZGF0YSgKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZpbGVLZXksCisgICAgICAgICAgICAgICAgICAgICAgICBhbmRyb2lkU2hhcmluZ0NoZWNrc3VtLAorICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUV4cGlyYXRpb25EYXRlU2VjcywKKyAgICAgICAgICAgICAgICAgICAgICAgIDApLAorICAgICAgICAgICAgICAgICAgICByZXMgLT4geworICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXMpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZUxvY2FsQ29weShkb3dubG9hZEZpbGVPbkRldmljZVVyaSwgZmlsZUdyb3VwLCBkYXRhRmlsZSk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdXBkYXRlTWF4RXhwaXJhdGlvbkRhdGVTZWNzKAorICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXAsIGRhdGFGaWxlLCBuZXdGaWxlS2V5LCBmaWxlRXhwaXJhdGlvbkRhdGVTZWNzKTsKKyAgICAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8vIFRoZSBmaWxlIHdhcyBzdXBwb3NlZCB0byBiZSBzaGFyZWQgYnV0IGl0IHdhc24ndC4KKyAgICAgICAgICAgIC8vIE5PVEU6IHRoaXMgc2NlbmFyaW8gc2hvdWxkIG5ldmVyIGhhcHBlbmVkIGJ1dCB3ZSB3YW50IHRvIG1ha2Ugc3VyZSBvZiBpdCB3aXRoIHNvbWUKKyAgICAgICAgICAgIC8vIGxvZ3MuCisgICAgICAgICAgICBpZiAoZGF0YUZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdUeXBlKCkKKyAgICAgICAgICAgICAgICA9PSBEYXRhRmlsZS5BbmRyb2lkU2hhcmluZ1R5cGUuQU5EUk9JRF9CTE9CX1dIRU5fQVZBSUxBQkxFKSB7CisgICAgICAgICAgICAgIGxvZ01kZEFuZHJvaWRTaGFyaW5nTG9nKGV2ZW50TG9nZ2VyLCBmaWxlR3JvdXAsIGRhdGFGaWxlLCAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGNhdGNoIChBbmRyb2lkU2hhcmluZ0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBsb2dNZGRBbmRyb2lkU2hhcmluZ0xvZyhldmVudExvZ2dlciwgZmlsZUdyb3VwLCBkYXRhRmlsZSwgZS5nZXRFcnJvckNvZGUoKSk7CisgICAgICAgICAgfQorICAgICAgICAgIExvZ1V0aWwuZCgKKyAgICAgICAgICAgICAgIiVzOiBGaWxlIGNvdWxkbid0IGJlIHNoYXJlZCBhZnRlciBkb3dubG9hZCAlcywgZmlsZWdyb3VwICVzIiwKKyAgICAgICAgICAgICAgVEFHLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICByZXR1cm4gdXBkYXRlTWF4RXhwaXJhdGlvbkRhdGVTZWNzKAorICAgICAgICAgICAgICBmaWxlR3JvdXAsIGRhdGFGaWxlLCBuZXdGaWxlS2V5LCBmaWxlRXhwaXJhdGlvbkRhdGVTZWNzKTsKKyAgICAgICAgfSk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyBpbW1lZGlhdGVWb2lkRnV0dXJlIGV2ZW4gaW4gY2FzZSBvZiBlcnJvci4gVGhpcyBpcyBiZWNhdXNlIGl0IGlzIHRoZSBsYXN0IG1ldGhvZCB0byBiZQorICAgKiBjYWxsZWQgYnkge0Bjb2RlIHRyeVRvU2hhcmVBZnRlckRvd25sb2FkfSwgd2hpY2ggaW1wbGVtZW50cyBhIGJlc3QgZWZmb3J0IGZlYXR1cmUgYW5kIGlzIG5vLW9wCisgICAqIGluIGNhc2Ugb2YgZXJyb3IuCisgICAqLworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gdXBkYXRlTWF4RXhwaXJhdGlvbkRhdGVTZWNzKAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCwKKyAgICAgIERhdGFGaWxlIGRhdGFGaWxlLAorICAgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5LAorICAgICAgbG9uZyBmaWxlRXhwaXJhdGlvbkRhdGVTZWNzKSB7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiB1cGRhdGVGdXR1cmUgPQorICAgICAgICBzaGFyZWRGaWxlTWFuYWdlci51cGRhdGVNYXhFeHBpcmF0aW9uRGF0ZVNlY3MobmV3RmlsZUtleSwgZmlsZUV4cGlyYXRpb25EYXRlU2Vjcyk7CisgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgdXBkYXRlRnV0dXJlLAorICAgICAgICByZXMgLT4geworICAgICAgICAgIGlmICghcmVzKSB7CisgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgIiVzOiBGYWlsZWQgdG8gc2V0IG5ldyBzdGF0ZSBmb3IgZmlsZSAlcywgZmlsZWdyb3VwICVzIiwKKyAgICAgICAgICAgICAgICBUQUcsIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgbG9nTWRkQW5kcm9pZFNoYXJpbmdMb2coZXZlbnRMb2dnZXIsIGZpbGVHcm91cCwgZGF0YUZpbGUsIDApOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICB9KTsKKyAgfQorCisgIC8qKgorICAgKiBBY3F1aXJlcyBvciB1cGRhdGVzIHRoZSBsZWFzZSB0byB0aGUgRGF0YUZpbGUge0Bjb2RlIGRhdGFGaWxlfSBhbmQgdXBkYXRlcyB0aGUgc2hhcmVkIGZpbGUKKyAgICogbWV0YWRhdGEuIFRoZSBzaGFyZWRGaWxlJ3Mge0Bjb2RlIEZpbGVTdGF0dXN9IHdpbGwgYmUgc2V0IHRvIERPV05MT0FEX0NPTVBMRVRFIHNvIHRoYXQgdGhlIGZpbGUKKyAgICogd29uJ3QgYmUgZG93bmxvYWRlZCBhZ2Fpbi4KKyAgICoKKyAgICogPHA+Tm8tb3Agb3BlcmF0aW9uIGlmIHRoZSBsZWFzZSBoYWQgYWxyZWFkeSBiZWVuIGFjcXVpcmVkIGFuZCBpdCBzaG91bGRuJ3QgYmVlbiB1cGRhdGVkLgorICAgKgorICAgKiA8cD5UaGlzIGxlYXNlIGluZGljYXRlcyB0byB0aGUgc3lzdGVtIHRoYXQgdGhlIGNhbGxpbmcgcGFja2FnZSB3YW50cyB0aGUgZGF0YUZpbGUgdG8gYmUga2VwdAorICAgKiBhcm91bmQuCisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IG1heWJlVXBkYXRlTGVhc2VBbmRTaGFyZWRNZXRhZGF0YSgKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAsCisgICAgICBEYXRhRmlsZSBkYXRhRmlsZSwKKyAgICAgIFNoYXJlZEZpbGUgc2hhcmVkRmlsZSwKKyAgICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSwKKyAgICAgIFN0cmluZyBhbmRyb2lkU2hhcmluZ0NoZWNrc3VtLAorICAgICAgbG9uZyBmaWxlRXhwaXJhdGlvbkRhdGVTZWNzLAorICAgICAgaW50IGV2ZXRUeXBlVG9Mb2cpCisgICAgICB0aHJvd3MgQW5kcm9pZFNoYXJpbmdFeGNlcHRpb24geworICAgIGlmIChzaGFyZWRGaWxlLmdldEFuZHJvaWRTaGFyZWQoKQorICAgICAgICAmJiAhc2hvdWxkVXBkYXRlTWF4RXhwaXJ5RGF0ZShzaGFyZWRGaWxlLCBmaWxlRXhwaXJhdGlvbkRhdGVTZWNzKSkgeworICAgICAgLy8gVGhlIGNhbGxpbmdQYWNrYWdlIGhhcyBhbHJlYWR5IGEgbGVhc2Ugb24gdGhlIGZpbGUgd2hpY2ggZXhwaXJlcyBhZnRlciB0aGUgY3VycmVudAorICAgICAgLy8gZXhwaXJhdGlvbiBkYXRlLgorICAgICAgbG9nTWRkQW5kcm9pZFNoYXJpbmdMb2coZXZlbnRMb2dnZXIsIGZpbGVHcm91cCwgZGF0YUZpbGUsIGV2ZXRUeXBlVG9Mb2cpOworICAgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZSh0cnVlKTsKKyAgICB9CisKKyAgICBsb25nIG1heEV4cGlyeURhdGUgPSBtYXgoZmlsZUV4cGlyYXRpb25EYXRlU2Vjcywgc2hhcmVkRmlsZS5nZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoKSk7CisgICAgQW5kcm9pZFNoYXJpbmdVdGlsLmFjcXVpcmVMZWFzZSgKKyAgICAgICAgY29udGV4dCwgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSwgbWF4RXhwaXJ5RGF0ZSwgZmlsZUdyb3VwLCBkYXRhRmlsZSwgZmlsZVN0b3JhZ2UpOworICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyLnNldEFuZHJvaWRTaGFyZWREb3dubG9hZGVkRmlsZUVudHJ5KAorICAgICAgICAgICAgbmV3RmlsZUtleSwgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSwgbWF4RXhwaXJ5RGF0ZSksCisgICAgICAgIHJlcyAtPiB7CisgICAgICAgICAgaWYgKCFyZXMpIHsKKyAgICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgICAiJXM6IEZhaWxlZCB0byBzZXQgbmV3IHN0YXRlIGZvciBmaWxlICVzLCBmaWxlZ3JvdXAgJXMiLAorICAgICAgICAgICAgICAgIFRBRywgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICAgICAgICBsb2dNZGRBbmRyb2lkU2hhcmluZ0xvZyhldmVudExvZ2dlciwgZmlsZUdyb3VwLCBkYXRhRmlsZSwgMCk7CisgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRnV0dXJlKGZhbHNlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgbG9nTWRkQW5kcm9pZFNoYXJpbmdMb2coCisgICAgICAgICAgICAgIGV2ZW50TG9nZ2VyLCBmaWxlR3JvdXAsIGRhdGFGaWxlLCBldmV0VHlwZVRvTG9nLCB0cnVlLCBtYXhFeHBpcnlEYXRlKTsKKyAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRnV0dXJlKHRydWUpOworICAgICAgICB9KTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGZpbGUge0Bjb2RlIGV4cGlyYXRpb25EYXRlU2Vjc30gaXMgZ3JlYXRlciB0aGFuIHRoZSBjdXJyZW50IHNoYXJlZEZpbGUKKyAgICoge0Bjb2RlIG1heF9leHBpcmF0aW9uX2RhdGV9LgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBzaG91bGRVcGRhdGVNYXhFeHBpcnlEYXRlKFNoYXJlZEZpbGUgc2hhcmVkRmlsZSwgbG9uZyBleHBpcmF0aW9uRGF0ZVNlY3MpIHsKKyAgICByZXR1cm4gZXhwaXJhdGlvbkRhdGVTZWNzID4gc2hhcmVkRmlsZS5nZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoKTsKKyAgfQorCisgIC8vIFRPRE8oYi8xMTgxMzc2NzIpOiByZW1vdmUgdGhpcyBoZWxwZXIgbWV0aG9kIG9uY2UgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSB0aHJvd3MgYW4KKyAgLy8gZXhjZXB0aW9uIGluc3RlYWQgb2YgcmV0dXJuaW5nIG51bGwuCisgIHByaXZhdGUgVXJpIGdldExvY2FsVXJpKERhdGFGaWxlIGRhdGFGaWxlLCBOZXdGaWxlS2V5IG5ld0ZpbGVLZXksIFNoYXJlZEZpbGUgc2hhcmVkRmlsZSkKKyAgICAgIHRocm93cyBBbmRyb2lkU2hhcmluZ0V4Y2VwdGlvbiB7CisgICAgVXJpIGRvd25sb2FkRmlsZU9uRGV2aWNlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBzaGFyZWRGaWxlLmdldEZpbGVOYW1lKCksCisgICAgICAgICAgICBkYXRhRmlsZS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgc2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICBpbnN0YW5jZUlkLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKyAgICBpZiAoZG93bmxvYWRGaWxlT25EZXZpY2VVcmkgPT0gbnVsbCkgeworICAgICAgTG9nVXRpbC5lKCIlczogRmFpbGVkIHRvIGdldCBmaWxlIHVyaSEiLCBUQUcpOworICAgICAgdGhyb3cgbmV3IEFuZHJvaWRTaGFyaW5nRXhjZXB0aW9uKDAsICJGYWlsZWQgdG8gZ2V0IGxvY2FsIGZpbGUgdXJpIik7CisgICAgfQorICAgIHJldHVybiBkb3dubG9hZEZpbGVPbkRldmljZVVyaTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBkZWxldGVMb2NhbENvcHkoCisgICAgICBVcmkgZG93bmxvYWRGaWxlT25EZXZpY2VVcmksIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAsIERhdGFGaWxlIGRhdGFGaWxlKSB7CisgICAgdHJ5IHsKKyAgICAgIGZpbGVTdG9yYWdlLmRlbGV0ZUZpbGUoZG93bmxvYWRGaWxlT25EZXZpY2VVcmkpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAiJXM6IEZhaWxlZCB0byBkZWxldGUgdGhlIGxvY2FsIGNvcHkgYWZ0ZXIgYW5kcm9pZC1zaGFyaW5nIHRoZSBmaWxlIgorICAgICAgICAgICAgICArICIgJXMsIGZpbGUgZ3JvdXAgJXMiLAorICAgICAgICAgIFRBRywgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICBsb2dNZGRBbmRyb2lkU2hhcmluZ0xvZyhldmVudExvZ2dlciwgZmlsZUdyb3VwLCBkYXRhRmlsZSwgMCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIERvd25sb2FkIGFuZCBWZXJpZnkgYWxsIGZpbGVzIHByZXNlbnQgaW4gYW55IHBlbmRpbmcgZ3JvdXBzLgorICAgKgorICAgKiBAcGFyYW0gb25XaWZpIHdoZXRoZXIgdGhlIGRldmljZSBpcyBvbiB3aWZpIGF0IHRoZSBtb21lbnQuCisgICAqIEByZXR1cm4gQSBDb21iaW5lZCBGdXR1cmUgb2YgYWxsIGZpbGUgZ3JvdXAgZG93bmxvYWRzLgorICAgKi8KKyAgLy8gVE9ETyhiLzEyNDA3Mjc1NCk6IENoYW5nZSB0byBwYWNrYWdlIHByaXZhdGUgb25jZSBhbGwgY29kZSBpcyByZWZhY3RvcmVkLgorICAvLyBUT0RPOiBDaGFuZ2UgbmFtZSB0byBkb3dubG9hZEFuZFZlcmlmeUFsbFBlbmRpbmdHcm91cHMuCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHNjaGVkdWxlQWxsUGVuZGluZ0dyb3Vwc0ZvckRvd25sb2FkKAorICAgICAgYm9vbGVhbiBvbldpZmksIEFzeW5jRnVuY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsLCBCb29sZWFuPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpIHsKKyAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsR3JvdXBLZXlzKCksCisgICAgICAgIHByb3BhZ2F0ZUFzeW5jRnVuY3Rpb24oCisgICAgICAgICAgICBncm91cEtleUxpc3QgLT4KKyAgICAgICAgICAgICAgICBzY2hlZHVsZVBlbmRpbmdEb3dubG9hZHMoZ3JvdXBLZXlMaXN0LCBvbldpZmksIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvcikpKTsKKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJudWxsbmVzcyIpCisgIC8vIFN1cHByZXNzIG51bGxuZXNzIHdhcm5pbmdzIGJlY2F1c2Ugb3RoZXJ3aXNlIHN0YXRpYyBhbmFseXNpcyB3b3VsZCByZXF1aXJlIHVzIHRvIGZhbHNlbHkgbGFiZWwKKyAgLy8gZG93bmxvYWRGaWxlR3JvdXAgd2l0aCBATnVsbGFibGVUeXBlCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBzY2hlZHVsZVBlbmRpbmdEb3dubG9hZHMoCisgICAgICBMaXN0PEdyb3VwS2V5PiBncm91cEtleUxpc3QsCisgICAgICBib29sZWFuIG9uV2lmaSwKKyAgICAgIEFzeW5jRnVuY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsLCBCb29sZWFuPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpIHsKKyAgICBMaXN0PExpc3RlbmFibGVGdXR1cmU8RGF0YUZpbGVHcm91cEludGVybmFsPj4gYWxsR3JvdXBGdXR1cmVzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgZm9yIChHcm91cEtleSBrZXkgOiBncm91cEtleUxpc3QpIHsKKyAgICAgIC8vIFdlIGFyZSBvbmx5IGNoZWNraW5nIHRoZSBub24tZG93bmxvYWRlZCBncm91cHMKKyAgICAgIGlmIChrZXkuZ2V0RG93bmxvYWRlZCgpKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorCisgICAgICBhbGxHcm91cEZ1dHVyZXMuYWRkKAorICAgICAgICAgIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoa2V5KSwKKyAgICAgICAgICAgICAgcGVuZGluZ0dyb3VwIC0+IHsKKyAgICAgICAgICAgICAgICBpZiAocGVuZGluZ0dyb3VwID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBib29sZWFuIGFsbG93RG93bmxvYWRXaXRob3V0V2lmaSA9IGZhbHNlOworICAgICAgICAgICAgICAgIGlmIChwZW5kaW5nR3JvdXAuZ2V0RG93bmxvYWRDb25kaXRpb25zKCkuZ2V0RGV2aWNlTmV0d29ya1BvbGljeSgpCisgICAgICAgICAgICAgICAgICAgID09IERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05fQU5ZX05FVFdPUkspIHsKKyAgICAgICAgICAgICAgICAgIGFsbG93RG93bmxvYWRXaXRob3V0V2lmaSA9IHRydWU7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwZW5kaW5nR3JvdXAuZ2V0RG93bmxvYWRDb25kaXRpb25zKCkuZ2V0RGV2aWNlTmV0d29ya1BvbGljeSgpCisgICAgICAgICAgICAgICAgICAgID09IERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfRklSU1RfT05fV0lGSV9USEVOX09OX0FOWV9ORVRXT1JLKSB7CisgICAgICAgICAgICAgICAgICBsb25nIHRpbWVEb3dubG9hZGluZ1dpdGhXaWZpU2VjcyA9CisgICAgICAgICAgICAgICAgICAgICAgKHRpbWVTb3VyY2UuY3VycmVudFRpbWVNaWxsaXMoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBwZW5kaW5nR3JvdXAuZ2V0Qm9va2tlZXBpbmcoKS5nZXRHcm91cE5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXAoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLyAxMDAwOworICAgICAgICAgICAgICAgICAgaWYgKHRpbWVEb3dubG9hZGluZ1dpdGhXaWZpU2VjcworICAgICAgICAgICAgICAgICAgICAgID4gcGVuZGluZ0dyb3VwLmdldERvd25sb2FkQ29uZGl0aW9ucygpLmdldERvd25sb2FkRmlyc3RPbldpZmlQZXJpb2RTZWNzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgYWxsb3dEb3dubG9hZFdpdGhvdXRXaWZpID0gdHJ1ZTsKKworICAgICAgICAgICAgICAgICAgICBwZW5kaW5nR3JvdXAgPQorICAgICAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0dyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVuZGluZ0dyb3VwLmdldERvd25sb2FkQ29uZGl0aW9ucygpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RGV2aWNlTmV0d29ya1BvbGljeSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBMb2dVdGlsLmQoCisgICAgICAgICAgICAgICAgICAgICIlczogVHJ5IHRvIGRvd25sb2FkIHBlbmRpbmcgZmlsZSBncm91cDogJXMsIGRvd25sb2FkIG92ZXIgY2VsbHVsYXIgPSAlcyIsCisgICAgICAgICAgICAgICAgICAgIFRBRywgcGVuZGluZ0dyb3VwLmdldEdyb3VwTmFtZSgpLCBhbGxvd0Rvd25sb2FkV2l0aG91dFdpZmkpOworCisgICAgICAgICAgICAgICAgaWYgKG9uV2lmaSB8fCBhbGxvd0Rvd25sb2FkV2l0aG91dFdpZmkpIHsKKyAgICAgICAgICAgICAgICAgIHJldHVybiBkb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgICBrZXksIHBlbmRpbmdHcm91cC5nZXREb3dubG9hZENvbmRpdGlvbnMoKSwgY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShudWxsKTsKKyAgICAgICAgICAgICAgfSkpOworICAgIH0KKyAgICAvLyBOb3RlOiBXZSB1c2Ugd2hlbkFsbENvbXBsZXRlIGluc3RlYWQgb2Ygd2hlbkFsbFN1Y2NlZWQgc2luY2Ugd2Ugd2FudCB0byBjb250aW51ZSB0byBkb3dubG9hZAorICAgIC8vIGFsbCBvdGhlciBmaWxlIGdyb3VwcyBldmVuIGlmIG9uZSBvciBtb3JlIGZhaWwuCisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLndoZW5BbGxDb21wbGV0ZShhbGxHcm91cEZ1dHVyZXMpCisgICAgICAgIC5jYWxsKCgpIC0+IG51bGwsIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIFZlcmlmaWVzIHRoYXQgdGhlIGdpdmVuIHBlbmRpbmcgZ3JvdXAgd2FzIGRvd25sb2FkZWQsIGFuZCB1cGRhdGVzIHRoZSBtZXRhZGF0YSBpZiB0aGUgZG93bmxvYWQKKyAgICogaGFzIGNvbXBsZXRlZC4KKyAgICoKKyAgICogQHBhcmFtIGdyb3VwS2V5IFRoZSBrZXkgb2YgdGhlIGdyb3VwIHRvIHZlcmlmeSBmb3IgZG93bmxvYWQuCisgICAqIEBwYXJhbSBwZW5kaW5nR3JvdXAgVGhlIGdyb3VwIHRvIHZlcmlmeSBmb3IgZG93bmxvYWQuCisgICAqIEByZXR1cm4gQSBmdXR1cmUgdGhhdCByZXNvbHZlcyB0byB0cnVlIGlmIHRoZSBnaXZlbiBncm91cCB3YXMgdmVyaWZ5IGZvciBkb3dubG9hZCwgZmFsc2UKKyAgICogICAgIG90aGVyd2lzZS4KKyAgICovCisgIC8vIFRPRE8oYi8xMjQwNzI3NTQpOiBDaGFuZ2UgdG8gcGFja2FnZSBwcml2YXRlIG9uY2UgYWxsIGNvZGUgaXMgcmVmYWN0b3JlZC4KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8R3JvdXBEb3dubG9hZFN0YXR1cz4gdmVyaWZ5UGVuZGluZ0dyb3VwRG93bmxvYWRlZCgKKyAgICAgIEdyb3VwS2V5IGdyb3VwS2V5LAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdHcm91cCwKKyAgICAgIEFzeW5jRnVuY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsLCBCb29sZWFuPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpIHsKKyAgICByZXR1cm4gdmVyaWZ5R3JvdXBEb3dubG9hZGVkKAorICAgICAgICBncm91cEtleSwKKyAgICAgICAgcGVuZGluZ0dyb3VwLAorICAgICAgICAvKiByZW1vdmVQZW5kaW5nVmVyc2lvbiA9ICovIHRydWUsCisgICAgICAgIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciwKKyAgICAgICAgLyogZG93bmxvYWRTdGF0ZUxvZ2dlciA9ICovIERvd25sb2FkU3RhdGVMb2dnZXIuZm9yRG93bmxvYWQoZXZlbnRMb2dnZXIpKTsKKyAgfQorCisgIC8qKgorICAgKiBWZXJpZmllcyB0aGF0IHRoZSBnaXZlbiBwZW5kaW5nIGdyb3VwIHdhcyBkb3dubG9hZGVkLCBhbmQgdXBkYXRlcyB0aGUgbWV0YWRhdGEgaWYgdGhlIGRvd25sb2FkCisgICAqIGhhcyBjb21wbGV0ZWQuCisgICAqCisgICAqIEBwYXJhbSBncm91cEtleSBUaGUga2V5IG9mIHRoZSBncm91cCB0byB2ZXJpZnkgZm9yIGRvd25sb2FkLgorICAgKiBAcGFyYW0gZmlsZUdyb3VwIFRoZSBncm91cCB0byB2ZXJpZnkgZm9yIGRvd25sb2FkLgorICAgKiBAcGFyYW0gcmVtb3ZlUGVuZGluZ1ZlcnNpb24gYm9vbGVhbiB0byB0ZWxsIHdoZXRoZXIgb3Igbm90IHRoZSBwZW5kaW5nIHZlcnNpb24gc2hvdWxkIGJlCisgICAqICAgICByZW1vdmVkLgorICAgKiBAcmV0dXJuIEEgZnV0dXJlIHRoYXQgcmVzb2x2ZXMgdG8gdHJ1ZSBpZiB0aGUgZ2l2ZW4gZ3JvdXAgd2FzIHZlcmlmeSBmb3IgZG93bmxvYWQsIGZhbHNlCisgICAqICAgICBvdGhlcndpc2UuCisgICAqLworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8R3JvdXBEb3dubG9hZFN0YXR1cz4gdmVyaWZ5R3JvdXBEb3dubG9hZGVkKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwLAorICAgICAgYm9vbGVhbiByZW1vdmVQZW5kaW5nVmVyc2lvbiwKKyAgICAgIEFzeW5jRnVuY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsLCBCb29sZWFuPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IsCisgICAgICBEb3dubG9hZFN0YXRlTG9nZ2VyIGRvd25sb2FkU3RhdGVMb2dnZXIpIHsKKyAgICBMb2dVdGlsLmQoCisgICAgICAgICIlczogVmVyaWZ5IGdyb3VwOiAlcywgcmVtb3ZlIHBlbmRpbmcgdmVyc2lvbjogJXMiLAorICAgICAgICBUQUcsIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSwgcmVtb3ZlUGVuZGluZ1ZlcnNpb24pOworCisgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5ID0gZ3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZCh0cnVlKS5idWlsZCgpOworICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleSA9IGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZEZpbGVHcm91cFdpdGhUaW1lc3RhbXAgPQorICAgICAgICBGaWxlR3JvdXBVdGlsLnNldERvd25sb2FkZWRUaW1lc3RhbXBJbk1pbGxpcyhmaWxlR3JvdXAsIHRpbWVTb3VyY2UuY3VycmVudFRpbWVNaWxsaXMoKSk7CisKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKGdldEZpbGVHcm91cERvd25sb2FkU3RhdHVzKGZpbGVHcm91cCkpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIGdyb3VwRG93bmxvYWRTdGF0dXMgLT4geworICAgICAgICAgICAgICAvLyBUT0RPKGIvMTU5ODI4MTk5KSBVc2UgZXhjZXB0aW9ucyBpbnN0ZWFkIG9mIG5lc3RpbmcgdG8gZXhpdCBlYXJseSBmcm9tIHRyYW5zZm9ybQorICAgICAgICAgICAgICAvLyBjaGFpbi4KKyAgICAgICAgICAgICAgaWYgKGdyb3VwRG93bmxvYWRTdGF0dXMgPT0gR3JvdXBEb3dubG9hZFN0YXR1cy5GQUlMRUQpIHsKKyAgICAgICAgICAgICAgICBkb3dubG9hZFN0YXRlTG9nZ2VyLmxvZ0ZhaWxlZChmaWxlR3JvdXApOworICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShHcm91cERvd25sb2FkU3RhdHVzLkZBSUxFRCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgaWYgKGdyb3VwRG93bmxvYWRTdGF0dXMgPT0gR3JvdXBEb3dubG9hZFN0YXR1cy5QRU5ESU5HKSB7CisgICAgICAgICAgICAgICAgZG93bmxvYWRTdGF0ZUxvZ2dlci5sb2dQZW5kaW5nKGZpbGVHcm91cCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEdyb3VwRG93bmxvYWRTdGF0dXMuUEVORElORyk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICBQcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoZ3JvdXBEb3dubG9hZFN0YXR1cyA9PSBHcm91cERvd25sb2FkU3RhdHVzLkRPV05MT0FERUQpOworICAgICAgICAgICAgICByZXR1cm4gdmFsaWRhdGVGaWxlR3JvdXBBbmRNYXliZVJlbW92ZUlmRmFpbGVkKAorICAgICAgICAgICAgICAgICAgICAgIHBlbmRpbmdHcm91cEtleSwKKyAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRTdGF0ZUxvZ2dlciwKKyAgICAgICAgICAgICAgICAgICAgICByZW1vdmVQZW5kaW5nVmVyc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpCisgICAgICAgICAgICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgdW51c2VkIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBpc29sYXRlZCBmaWxlIHN0cnVjdHVyZSAodXNpbmcgc3ltbGlua3MpIGlmIG5lY2Vzc2FyeSBhbmQKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIHN1cHBvcnRlZAorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEZpbGVHcm91cFV0aWwuaXNJc29sYXRlZFN0cnVjdHVyZUFsbG93ZWQoZmlsZUdyb3VwKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIFZFUlNJT04uU0RLX0lOVCA+PSBWRVJTSU9OX0NPREVTLkxPTExJUE9QKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVJc29sYXRlZEZpbGVQYXRocyhmaWxlR3JvdXApOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgICAgICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgdW51c2VkIC0+CisgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlTmV3R3JvdXBBbmRSZXR1cm5PbGRHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkZWRHcm91cEtleSwgZG93bmxvYWRlZEZpbGVHcm91cFdpdGhUaW1lc3RhbXApLAorICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgICAgICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRlZEdyb3VwT3B0aW9uYWwgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZVBlbmRpbmdWZXJzaW9uKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZW1vdmVQZW5kaW5nR3JvdXAocGVuZGluZ0dyb3VwS2V5LCBkb3dubG9hZGVkR3JvdXBPcHRpb25hbCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUoZG93bmxvYWRlZEdyb3VwT3B0aW9uYWwpOworICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikKKyAgICAgICAgICAgICAgICAgIC50cmFuc2Zvcm1Bc3luYyh0aGlzOjphZGRHcm91cEFzU3RhbGVJZlByZXNlbnQsIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgICAgICAgICAgICAudHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgIHZvaWRBcmcgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRTdGF0ZUxvZ2dlci5sb2dDb21wbGV0ZShkb3dubG9hZGVkRmlsZUdyb3VwV2l0aFRpbWVzdGFtcCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gR3JvdXBEb3dubG9hZFN0YXR1cy5ET1dOTE9BREVEOworICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgZG93bmxvYWRTdGF0dXMgLT4KKyAgICAgICAgICAgICAgICB0cmFuc2Zvcm1TZXF1ZW50aWFsKAorICAgICAgICAgICAgICAgICAgICBkb3dubG9hZFN0YWdlTWFuYWdlci51cGRhdGVFeHBlcmltZW50SWRzKGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSksCisgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgLT4gZG93bmxvYWRTdGF0dXMpLAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8T3B0aW9uYWw8RGF0YUZpbGVHcm91cEludGVybmFsPj4gd3JpdGVOZXdHcm91cEFuZFJldHVybk9sZEdyb3VwKAorICAgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgbmV3R3JvdXApIHsKKyAgICBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlPE9wdGlvbmFsPERhdGFGaWxlR3JvdXBJbnRlcm5hbD4+IGV4aXN0aW5nRmlsZUdyb3VwID0KKyAgICAgICAgUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGRvd25sb2FkZWRHcm91cEtleSkpCisgICAgICAgICAgICAudHJhbnNmb3JtKE9wdGlvbmFsOjpmcm9tTnVsbGFibGUsIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworCisgICAgcmV0dXJuIGV4aXN0aW5nRmlsZUdyb3VwCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIHVudXNlZCAtPiBmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUoZG93bmxvYWRlZEdyb3VwS2V5LCBuZXdHcm91cCksCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICB3cml0ZVN1Y2Nlc3MgLT4geworICAgICAgICAgICAgICBpZiAoIXdyaXRlU3VjY2VzcykgeworICAgICAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICAgICAgICBuZXcgSU9FeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIHdyaXRlIHVwZGF0ZWQgZ3JvdXA6ICIgKyBkb3dubG9hZGVkR3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCkpKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIHJldHVybiBleGlzdGluZ0ZpbGVHcm91cDsKKyAgICAgICAgICAgIH0sCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxPcHRpb25hbDxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiByZW1vdmVQZW5kaW5nR3JvdXAoCisgICAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXksIE9wdGlvbmFsPERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gdG9SZXR1cm4pIHsKKyAgICAvLyBSZW1vdmUgdGhlIG5ld2x5IGRvd25sb2FkZWQgdmVyc2lvbiBmcm9tIHRoZSBwZW5kaW5nIGdyb3VwcyBsaXN0LAorICAgIC8vIGlmIHJlbW92aW5nIGZhaWxzLCB3ZSB3aWxsIHZlcmlmeSBpdCBhZ2FpbiB0aGUgbmV4dCB0aW1lLgorICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsKAorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlKHBlbmRpbmdHcm91cEtleSksCisgICAgICAgIHJlbW92ZVN1Y2Nlc3MgLT4geworICAgICAgICAgIGlmICghcmVtb3ZlU3VjY2VzcykgeworICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gdG9SZXR1cm47CisgICAgICAgIH0pOworICB9CisKKyAgcHJpdmF0ZSBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlPFZvaWQ+IHZhbGlkYXRlRmlsZUdyb3VwQW5kTWF5YmVSZW1vdmVJZkZhaWxlZCgKKyAgICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleSwKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAsCisgICAgICBEb3dubG9hZFN0YXRlTG9nZ2VyIGRvd25sb2FkU3RhdGVMb2dnZXIsCisgICAgICBib29sZWFuIHJlbW92ZVBlbmRpbmdWZXJzaW9uLAorICAgICAgQXN5bmNGdW5jdGlvbjxEYXRhRmlsZUdyb3VwSW50ZXJuYWwsIEJvb2xlYW4+IGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvcikKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIHJldHVybiBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlLmZyb20oY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yLmFwcGx5KGZpbGVHcm91cCkpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIHZhbGlkYXRlZE9rIC0+IHsKKyAgICAgICAgICAgICAgaWYgKHZhbGlkYXRlZE9rKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIGRvd25sb2FkU3RhdGVMb2dnZXIubG9nRmFpbGVkKGZpbGVHcm91cCk7CisKKyAgICAgICAgICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiByZW1vdmVQZW5kaW5nR3JvdXBGdXR1cmUgPSBpbW1lZGlhdGVGdXR1cmUodHJ1ZSk7CisgICAgICAgICAgICAgIGlmIChyZW1vdmVQZW5kaW5nVmVyc2lvbikgeworICAgICAgICAgICAgICAgIHJlbW92ZVBlbmRpbmdHcm91cEZ1dHVyZSA9IGZpbGVHcm91cHNNZXRhZGF0YS5yZW1vdmUocGVuZGluZ0dyb3VwS2V5KTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgcmVtb3ZlUGVuZGluZ0dyb3VwRnV0dXJlLAorICAgICAgICAgICAgICAgICAgcmVtb3ZlU3VjY2VzcyAtPiB7CisgICAgICAgICAgICAgICAgICAgIGlmICghcmVtb3ZlU3VjY2VzcykgeworICAgICAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBGYWlsZWQgdG8gcmVtb3ZlIHBlbmRpbmcgdmVyc2lvbiBmb3IgZ3JvdXA6ICclcyc7IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIGFjY291bnQ6ICclcyciLAorICAgICAgICAgICAgICAgICAgICAgICAgICBUQUcsIHBlbmRpbmdHcm91cEtleS5nZXRHcm91cE5hbWUoKSwgcGVuZGluZ0dyb3VwS2V5LmdldEFjY291bnQoKSk7CisgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBJT0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gcmVtb3ZlIHBlbmRpbmcgZ3JvdXA6ICIgKyBwZW5kaW5nR3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCkpKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRSZXN1bHRDb2RlLkNVU1RPTV9GSUxFR1JPVVBfVkFMSURBVElPTl9GQUlMRUQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldE1lc3NhZ2UoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERvd25sb2FkUmVzdWx0Q29kZS5DVVNUT01fRklMRUdST1VQX1ZBTElEQVRJT05fRkFJTEVELm5hbWUoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgIH0sCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBhZGRHcm91cEFzU3RhbGVJZlByZXNlbnQoCisgICAgICBPcHRpb25hbDxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IG9sZEdyb3VwKSB7CisgICAgaWYgKCFvbGRHcm91cC5pc1ByZXNlbnQoKSkgeworICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICB9CisKKyAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEuYWRkU3RhbGVHcm91cChvbGRHcm91cC5nZXQoKSksCisgICAgICAgIGFkZFN1Y2Nlc3MgLT4geworICAgICAgICAgIGlmICghYWRkU3VjY2VzcykgeworICAgICAgICAgICAgLy8gSWYgdGhpcyBmYWlscywgdGhlIHN0YWxlIGZpbGUgZ3JvdXAgd2lsbCBiZQorICAgICAgICAgICAgLy8gdW5hY2NvdW50ZWQgZm9yLCBhbmQgdGhlIGZpbGVzIHdpbGwgZ2V0IGRlbGV0ZWQKKyAgICAgICAgICAgIC8vIGluIHRoZSBuZXh0IGRhaWx5IG1haW50ZW5hbmNlLCBoZW5jZSBub3QKKyAgICAgICAgICAgIC8vIGVuZm9yY2luZyBpdHMgc3RhbGUgbGlmZXRpbWUuCisgICAgICAgICAgICBldmVudExvZ2dlci5sb2dFdmVudFNhbXBsZWQoMCk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgIH0pOworICB9CisKKyAgLyoqCisgICAqIFdoZW4gYSBEYXRhRmlsZUdyb3VwIGhhcyBwcmVzZXJ2ZV9maWxlbmFtZXNfYW5kX2lzb2xhdGVfZmlsZXMgc2V0LCB0aGlzIG1ldGhvZCB3aWxsIGNyZWF0ZSBhbgorICAgKiBpc29sYXRlZCBmaWxlIHN0cnVjdHVyZSAodXNpbmcgc3ltbGlua3MgdG8gdGhlIHNoYXJlZCBmaWxlcykuCisgICAqCisgICAqIDxwPlRoaXMgbWV0aG9kIHdpbGwgYWxzbyByZXNwZWN0IGEgRGF0YUZpbGVzIHJlbGF0aXZlX2ZpbGVfcGF0aCBmaWVsZCAoaWYgc2V0KSwgb3RoZXJ3aXNlIGl0CisgICAqIHdpbGwgdXNlIHRoZSBsYXN0IHNlZ21lbnQgb2YgdGhlIGRvd25sb2FkIHVybC4KKyAgICoKKyAgICogPHA+SWYgcHJlc2VydmVfZmlsZW5hbWVzX2FuZF9pc29sYXRlX2ZpbGVzIGlzIG5vdCBzZXQsIHRoaXMgbWV0aG9kIGlzIGEgbm9vcCBhbmQgd2lsbAorICAgKiBpbW1lZGlhdGVseSByZXR1cm4KKyAgICoKKyAgICogQHJldHVybiBGdXR1cmUgdGhhdCByZXNvbHZlcyBvbmNlIGlzb2xhdGVkIHBhdGhzIGFyZSBjcmVhdGVkLCBvciBmYWlsdXJlIHdpdGggRG93bmxvYWRFeGNlcHRpb24KKyAgICogICAgIGlmIHVuYWJsZSB0byBjcmVhdGUgaXNvbGF0ZWQgc3RydWN0dXJlLgorICAgKi8KKyAgQFJlcXVpcmVzQXBpKFZFUlNJT05fQ09ERVMuTE9MTElQT1ApCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjcmVhdGVJc29sYXRlZEZpbGVQYXRocyhEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCkgeworICAgIC8vIElmIG5vIGlzb2xhdGVkIHN0cnVjdHVyZSBpcyByZXF1aXJlZCwgcmV0dXJuIGVhcmx5LgorICAgIGlmICghZGF0YUZpbGVHcm91cC5nZXRQcmVzZXJ2ZUZpbGVuYW1lc0FuZElzb2xhdGVGaWxlcygpKSB7CisgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgIH0KKworICAgIC8vIFJlbW92ZSBleGlzdGluZyBzeW1saW5rcyBpZiB0aGV5IGV4aXN0CisgICAgdHJ5IHsKKyAgICAgIEZpbGVHcm91cFV0aWwucmVtb3ZlSXNvbGF0ZWRGaWxlU3RydWN0dXJlKGNvbnRleHQsIGluc3RhbmNlSWQsIGRhdGFGaWxlR3JvdXAsIGZpbGVTdG9yYWdlKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5VTkFCTEVfVE9fUkVNT1ZFX1NZTUxJTktfU1RSVUNUVVJFKQorICAgICAgICAgICAgICAuc2V0TWVzc2FnZSgiVW5hYmxlIHRvIGNsZWFudXAgc3ltbGluayBzdHJ1Y3R1cmUiKQorICAgICAgICAgICAgICAuc2V0Q2F1c2UoZSkKKyAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgIH0KKyAgICBMaXN0PExpc3RlbmFibGVGdXR1cmU8Vm9pZD4+IGNyZWF0ZVN5bWxpbmtGdXR1cmVzID0KKyAgICAgICAgbmV3IEFycmF5TGlzdDw+KGRhdGFGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCkpOworCisgICAgZm9yIChEYXRhRmlsZSBkYXRhRmlsZSA6IGRhdGFGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKSkgeworICAgICAgaWYgKGRhdGFGaWxlLmdldEFuZHJvaWRTaGFyaW5nVHlwZSgpID09IEFuZHJvaWRTaGFyaW5nVHlwZS5BTkRST0lEX0JMT0JfV0hFTl9BVkFJTEFCTEUpIHsKKyAgICAgICAgY3JlYXRlU3ltbGlua0Z1dHVyZXMuYWRkKAorICAgICAgICAgICAgaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICAgIG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAgICAgIlByZXNlcnZlIEZpbGUgUGF0aHMgaXMgaW52YWxpZCB3aXRoIEFuZHJvaWQgQmxvYiBTaGFyaW5nIikpKTsKKyAgICAgICAgLy8gYnJlYWsgb3V0IG9mIGxvb3Agc2luY2Ugd2UndmUgYWxyZWFkeSBoaXQgYSBmYWlsdXJlLgorICAgICAgICBicmVhazsKKyAgICAgIH0KKworICAgICAgLy8gR2V0IHRoZSBvcmlnaW5hbCBwYXRoCisgICAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNyZWF0ZVN5bWxpbmtGdXR1cmUgPQorICAgICAgICAgIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgZ2V0T25EZXZpY2VVcmkoZGF0YUZpbGUsIGRhdGFGaWxlR3JvdXApLAorICAgICAgICAgICAgICAoVXJpIG9yaWdpbmFsVXJpKSAtPiB7CisgICAgICAgICAgICAgICAgVXJpIHN5bWxpbmtVcmkgPQorICAgICAgICAgICAgICAgICAgICBGaWxlR3JvdXBVdGlsLmdldElzb2xhdGVkRmlsZVVyaShjb250ZXh0LCBpbnN0YW5jZUlkLCBkYXRhRmlsZSwgZGF0YUZpbGVHcm91cCk7CisKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgLy8gQ2hlY2svY3JlYXRlIHBhcmVudCBkaXIgb2Ygc3ltbGluay4KKyAgICAgICAgICAgICAgICAgIFVyaSBzeW1saW5rUGFyZW50RGlyID0KKyAgICAgICAgICAgICAgICAgICAgICBVcmkucGFyc2UoCisgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bWxpbmtVcmkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50b1N0cmluZygpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3Vic3RyaW5nKDAsIHN5bWxpbmtVcmkudG9TdHJpbmcoKS5sYXN0SW5kZXhPZigiLyIpKSk7CisgICAgICAgICAgICAgICAgICBpZiAoIWZpbGVTdG9yYWdlLmV4aXN0cyhzeW1saW5rUGFyZW50RGlyKSkgeworICAgICAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZS5jcmVhdGVEaXJlY3Rvcnkoc3ltbGlua1BhcmVudERpcik7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICBTeW1saW5rVXRpbC5jcmVhdGVTeW1saW5rKGNvbnRleHQsIHN5bWxpbmtVcmksIGNoZWNrTm90TnVsbChvcmlnaW5hbFVyaSkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEb3dubG9hZFJlc3VsdENvZGUuVU5BQkxFX1RPX0NSRUFURV9TWU1MSU5LX1NUUlVDVFVSRSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldE1lc3NhZ2UoIlVuYWJsZSB0byBjcmVhdGUgc3ltbGluayIpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRDYXVzZShlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgIH0pOworICAgICAgY3JlYXRlU3ltbGlua0Z1dHVyZXMuYWRkKGNyZWF0ZVN5bWxpbmtGdXR1cmUpOworICAgIH0KKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNvbWJpbmVkRnV0dXJlID0KKyAgICAgICAgRnV0dXJlcy53aGVuQWxsU3VjY2VlZChjcmVhdGVTeW1saW5rRnV0dXJlcykuY2FsbCgoKSAtPiBudWxsLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKworICAgIFByb3BhZ2F0ZWRGdXR1cmVzLmFkZENhbGxiYWNrKAorICAgICAgICBjb21iaW5lZEZ1dHVyZSwKKyAgICAgICAgbmV3IEZ1dHVyZUNhbGxiYWNrPFZvaWQ+KCkgeworICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgIHB1YmxpYyB2b2lkIG9uU3VjY2VzcyhWb2lkIHVudXNlZCkge30KKworICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgIHB1YmxpYyB2b2lkIG9uRmFpbHVyZShUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgLy8gY2xlYW51cCBzeW1saW5rIHN0cnVjdHVyZSBvbiBmYWlsdXJlCisgICAgICAgICAgICBMb2dVdGlsLmQodCwgIiVzOiBVbmFibGUgdG8gY3JlYXRlIHN5bWxpbmsgc3RydWN0dXJlLCBjbGVhbmluZyB1cCBzeW1saW5rcy4uLiIsIFRBRyk7CisgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICBGaWxlR3JvdXBVdGlsLnJlbW92ZUlzb2xhdGVkRmlsZVN0cnVjdHVyZSgKKyAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGluc3RhbmNlSWQsIGRhdGFGaWxlR3JvdXAsIGZpbGVTdG9yYWdlKTsKKyAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgTG9nVXRpbC5kKGUsICIlczogVW5hYmxlIHRvIGNsZWFuIHVwIHN5bWxpbmsgc3RydWN0dXJlIGFmdGVyIGZhaWx1cmUiLCBUQUcpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisKKyAgICByZXR1cm4gY29tYmluZWRGdXR1cmU7CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgSXNvbGF0ZWQgRmlsZSBVcmkgYW5kIHZlcmlmaWVzIHRoYXQgaXQgZXhpc3RzIGFuZCBwb2ludHMgdG8gdGhlIGdpdmVuIHVyaS4KKyAgICoKKyAgICogPHA+VGhyb3dzIElPRXhjZXB0aW9uIHdoZW4gdmVyaWZ5aW5nIHRoZSBzeW1saW5rIGZhaWxzLgorICAgKi8KKyAgQFJlcXVpcmVzQXBpKFZFUlNJT05fQ09ERVMuTE9MTElQT1ApCisgIFVyaSBnZXRBbmRWZXJpZnlJc29sYXRlZEZpbGVVcmkoCisgICAgICBVcmkgb3JpZ2luYWxGaWxlVXJpLCBEYXRhRmlsZSBkYXRhRmlsZSwgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXApCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVyaSBpc29sYXRlZEZpbGVVcmkgPQorICAgICAgICBGaWxlR3JvdXBVdGlsLmdldElzb2xhdGVkRmlsZVVyaShjb250ZXh0LCBpbnN0YW5jZUlkLCBkYXRhRmlsZSwgZGF0YUZpbGVHcm91cCk7CisKKyAgICBVcmkgdGFyZ2V0RmlsZVVyaSA9IFN5bWxpbmtVdGlsLnJlYWRTeW1saW5rKGNvbnRleHQsIGlzb2xhdGVkRmlsZVVyaSk7CisKKyAgICBpZiAoIWZpbGVTdG9yYWdlLmV4aXN0cyhpc29sYXRlZEZpbGVVcmkpCisgICAgICAgIHx8ICF0YXJnZXRGaWxlVXJpLnRvU3RyaW5nKCkuZXF1YWxzKG9yaWdpbmFsRmlsZVVyaS50b1N0cmluZygpKSkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJJc29sYXRlZCBmaWxlIHVyaSBkb2VzIG5vdCBleGlzdCBvciBwb2ludHMgdG8gYW4gdW5leHBlY3RlZCB0YXJnZXQiKTsKKyAgICB9CisKKyAgICByZXR1cm4gaXNvbGF0ZWRGaWxlVXJpOworICB9CisKKyAgLyoqCisgICAqIFZlcmlmaWVzIGEgZmlsZSBncm91cCdzIGlzb2xhdGVkIHN0cnVjdHVyZSBpcyBjb3JyZWN0LgorICAgKgorICAgKiA8cD5UaGlzIHZlcmlmaWNhdGlvbiBpcyBvbmx5IHBlcmZvcm1lZCB1bmRlciB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CisgICAqCisgICAqIDx1bD4KKyAgICogICA8bGk+TUREIEZsYWdzIGVuYWJsZSB0aGlzIHZlcmlmaWNhdGlvbgorICAgKiAgIDxsaT5UaGUgZ3JvdXAgaXMgbm90IG51bGwKKyAgICogICA8bGk+VGhlIGdyb3VwIGlzIGRvd25sb2FkZWQKKyAgICogICA8bGk+VGhlIGdyb3VwIHVzZXMgYW4gaXNvbGF0ZWQgc3RydWN0dXJlCisgICAqIDwvdWw+CisgICAqCisgICAqIDxwPklmIGFueSBvZiB0aGVzZSBjb25kaXRpb25zIGFyZSBub3QgbWV0LCB0aGlzIG1ldGhvZCBpcyBhIG5vb3AgYW5kIHJldHVybnMgdHJ1ZSBpbW1lZGlhdGVseS4KKyAgICoKKyAgICogPHA+SWYgc3RydWN0dXJlIGlzIGNvcnJlY3QsIHRoaXMgbWV0aG9kIHJldHVybnMgdHJ1ZS4KKyAgICoKKyAgICogPHA+SWYgdGhlIGlzb2xhdGVkIHN0cnVjdHVyZSBpcyBjb3JydXB0ZWQgKG1pc3Npbmcgc3ltbGluayBvciBpbnZhbGlkIHN5bWxpbmspLCB0aGlzIG1ldGhvZAorICAgKiB3aWxsIHJldHVybiBmYWxzZS4KKyAgICoKKyAgICogPHA+VGhpcyBtZXRob2QgaXMgYW5ub3RhdGVkIHdpdGggQFRhcmdldEFwaSgyMSkgc2luY2Ugc3ltbGluayBzdHJ1Y3R1cmUgbWV0aG9kcyByZXF1aXJlIEFQSQorICAgKiBsZXZlbCAyMSBvciBsYXRlci4gVGhlIEZpbGVHcm91cFV0aWwuaXNJc29sYXRlZFN0cnVjdHVyZUFsbG93ZWQgY2hlY2sgd2lsbCBlbnN1cmUgdGhpcworICAgKiBjb25kaXRpb24gaXMgbWV0IGJlZm9yZSBjYWxsaW5nIGdldEFuZFZlcmlmeUlzb2xhdGVkRmlsZVVyaSBhbmQgY3JlYXRlSXNvbGF0ZWRGaWxlUGF0aHMuCisgICAqCisgICAqIEByZXR1cm4gRnV0dXJlIHRoYXQgcmVzb2x2ZXMgdG8gdHJ1ZSBpZiB0aGUgaXNvbGF0ZWQgc3RydWN0dXJlIGlzIHZlcmlmaWVkLCBvciBmYWxzZSBpZiB0aGUKKyAgICogICAgIHN0cnVjdHVyZSBjb3VsZG4ndCBiZSB2ZXJpZmllZAorICAgKi8KKyAgQFRhcmdldEFwaSgyMSkKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IG1heWJlVmVyaWZ5SXNvbGF0ZWRTdHJ1Y3R1cmUoCisgICAgICBATnVsbGFibGVUeXBlIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwLCBib29sZWFuIGlzRG93bmxvYWRlZCkgeworICAgIC8vIFJldHVybiBlYXJseSBpZiBjb25kaXRpb25zIGFyZSBub3QgbWV0CisgICAgaWYgKCFmbGFncy5lbmFibGVJc29sYXRlZFN0cnVjdHVyZVZlcmlmaWNhdGlvbigpCisgICAgICAgIHx8IGRhdGFGaWxlR3JvdXAgPT0gbnVsbAorICAgICAgICB8fCAhaXNEb3dubG9hZGVkCisgICAgICAgIHx8ICFGaWxlR3JvdXBVdGlsLmlzSXNvbGF0ZWRTdHJ1Y3R1cmVBbGxvd2VkKGRhdGFGaWxlR3JvdXApKSB7CisgICAgICByZXR1cm4gaW1tZWRpYXRlRnV0dXJlKHRydWUpOworICAgIH0KKworICAgIExpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4gdmVyaWZ5SXNvbGF0ZWRGaWxlRnV0dXJlcyA9CisgICAgICAgIG5ldyBBcnJheUxpc3Q8PihkYXRhRmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKTsKKyAgICBmb3IgKERhdGFGaWxlIGRhdGFGaWxlIDogZGF0YUZpbGVHcm91cC5nZXRGaWxlTGlzdCgpKSB7CisgICAgICB2ZXJpZnlJc29sYXRlZEZpbGVGdXR1cmVzLmFkZCgKKyAgICAgICAgICB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgIGdldE9uRGV2aWNlVXJpKGRhdGFGaWxlLCBkYXRhRmlsZUdyb3VwKSwKKyAgICAgICAgICAgICAgb25EZXZpY2VVcmkgLT4geworICAgICAgICAgICAgICAgIGlmIChvbkRldmljZVVyaSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICBVcmkgdW51c2VkID0gZ2V0QW5kVmVyaWZ5SXNvbGF0ZWRGaWxlVXJpKG9uRGV2aWNlVXJpLCBkYXRhRmlsZSwgZGF0YUZpbGVHcm91cCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgIH0pKTsKKyAgICB9CisKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMuY2F0Y2hpbmcoCisgICAgICAgIEZ1dHVyZXMud2hlbkFsbFN1Y2NlZWQodmVyaWZ5SXNvbGF0ZWRGaWxlRnV0dXJlcykKKyAgICAgICAgICAgIC5jYWxsKCgpIC0+IHRydWUsIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpLAorICAgICAgICBJT0V4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgZXggLT4geworICAgICAgICAgIC8vIFRPRE8oYi8xOTQ2ODg2ODcpOiBMb2cgdGhlc2UgZXZlbnRzIHRvIGNsZWFyY3V0IGFsb25nIHdpdGggdGhlaXIgZmlsZSBncm91cCBpbmZvIHNvCisgICAgICAgICAgLy8gd2UgY2FuIHVuZGVyc3RhbmQgaG93IG9mdGVuIHRoaXMgaXMgaGFwcGVuaW5nLgorICAgICAgICAgIExvZ1V0aWwudygKKyAgICAgICAgICAgICAgZXgsCisgICAgICAgICAgICAgICIlczogRGV0ZWN0ZWQgY29ycnVwdGlvbiBvZiBpc29sYXRlZCBzdHJ1Y3R1cmUgZm9yIGdyb3VwICVzIiwKKyAgICAgICAgICAgICAgVEFHLAorICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKworICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgb24gZGV2aWNlIHVyaSBvZiB0aGUgZ2l2ZW4ge0BsaW5rIERhdGFGaWxlfS4KKyAgICoKKyAgICogPHA+Q2hlY2tzIGZvciBzaWRlbG9hZGluZyBzdXBwb3J0LiBJZiBmaWxlIGlzIHNpZGVsb2FkZWQgYW5kIHNpZGVsb2FkaW5nIGlzIGVuYWJsZWQsIHRoZQorICAgKiBzaWRlbG9hZCB1cmkgd2lsbCBiZSByZXR1cm5lZCBpbW1lZGlhdGVseS4gSWYgc2lkZWxvYWRpbmcgaXMgbm90IGVuYWJsZWQsIHJldHVybnMgZmFpbHVyZS4KKyAgICoKKyAgICogPHA+SWYgZmlsZSBpcyBub3Qgc2lkZWxvYWRlZCwgZGVsZWdhdGVzIHRvIHtAbGluaworICAgKiBTaGFyZWRGaWxlTWFuYWdlciNnZXRPbkRldmljZVVyaShOZXdGaWxlS2V5KX0uCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxATnVsbGFibGVUeXBlIFVyaT4gZ2V0T25EZXZpY2VVcmkoCisgICAgICBEYXRhRmlsZSBkYXRhRmlsZSwgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXApIHsKKyAgICAvLyBJZiBzaWRlbG9hZGVkIGZpbGUgLS0gcmV0dXJuIHVybCBpbW1lZGlhdGVseQorICAgIGlmIChGaWxlR3JvdXBVdGlsLmlzU2lkZWxvYWRlZEZpbGUoZGF0YUZpbGUpKSB7CisgICAgICByZXR1cm4gaW1tZWRpYXRlRnV0dXJlKFVyaS5wYXJzZShkYXRhRmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkpKTsKKyAgICB9CisKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShkYXRhRmlsZSwgZGF0YUZpbGVHcm91cC5nZXRBbGxvd2VkUmVhZGVyc0VudW0oKSk7CisKKyAgICByZXR1cm4gc2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkobmV3RmlsZUtleSk7CisgIH0KKworICAvKioKKyAgICogR2V0IHRoZSBjdXJyZW50IHN0YXR1cyBvZiB0aGUgZmlsZSBncm91cC4gU2luY2UgdGhlIHN0YXR1cyBvZiB0aGUgZ3JvdXAgaXMgbm90IHN0b3JlZCBpbiB0aGUKKyAgICogZmlsZSBncm91cCwgdGhpcyBtZXRob2QgaXRlcmF0ZXMgb3ZlciBhbGwgZmlsZXMgYW5kIHJlLWNhbGN1bGF0ZXMgdGhlIGN1cnJlbnQgc3RhdHVzLgorICAgKgorICAgKiA8cD5Ob3RlIHRoYXQgdGhpcyBtZXRob2QgZG9lc24ndCBtb2RpZnkgdGhlIHN0YXR1cyBvZiB0aGUgZmlsZSBncm91cCBvbiBkaXNrLgorICAgKi8KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8R3JvdXBEb3dubG9hZFN0YXR1cz4gZ2V0RmlsZUdyb3VwRG93bmxvYWRTdGF0dXMoCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCkgeworICAgIHJldHVybiBnZXRGaWxlR3JvdXBEb3dubG9hZFN0YXR1c0l0ZXIoCisgICAgICAgIGRhdGFGaWxlR3JvdXAsCisgICAgICAgIC8qIGRvd25sb2FkRmFpbGVkID0gKi8gZmFsc2UsCisgICAgICAgIC8qIGRvd25sb2FkUGVuZGluZyA9ICovIGZhbHNlLAorICAgICAgICAvKiBpbmRleCA9ICovIDAsCisgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCkpOworICB9CisKKyAgLy8gQmVjYXVzZSB0aGUgZGVjaXNpb24gdG8gY29udGludWUgaXRlcmF0aW5nIGRlcGVuZHMgb24gdGhlIHJlc3VsdCBvZiB0aGUgYXN5bmNocm9ub3VzCisgIC8vIGdldEZpbGVTdGF0dXMgb3BlcmF0aW9uLCB3ZSBoYXZlIHRvIHVzZSByZWN1cnNpb24gaGVyZSBpbnN0ZWFkIG9mIGEgbG9vcCBjb25zdHJ1Y3QuCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxHcm91cERvd25sb2FkU3RhdHVzPiBnZXRGaWxlR3JvdXBEb3dubG9hZFN0YXR1c0l0ZXIoCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCwKKyAgICAgIGJvb2xlYW4gZG93bmxvYWRGYWlsZWQsCisgICAgICBib29sZWFuIGRvd25sb2FkUGVuZGluZywKKyAgICAgIGludCBpbmRleCwKKyAgICAgIGludCBmaWxlQ291bnQpIHsKKyAgICBpZiAoaW5kZXggPCBmaWxlQ291bnQpIHsKKyAgICAgIERhdGFGaWxlIGRhdGFGaWxlID0gZGF0YUZpbGVHcm91cC5nZXRGaWxlKGluZGV4KTsKKworICAgICAgLy8gU2tpcCBzaWRlbG9hZGVkIGZpbGVzIC0tIHRoZXkgYXJlIGFsd2F5cyBjb25zaWRlcmVkIGRvd25sb2FkZWQuCisgICAgICBpZiAoRmlsZUdyb3VwVXRpbC5pc1NpZGVsb2FkZWRGaWxlKGRhdGFGaWxlKSkgeworICAgICAgICByZXR1cm4gZ2V0RmlsZUdyb3VwRG93bmxvYWRTdGF0dXNJdGVyKAorICAgICAgICAgICAgZGF0YUZpbGVHcm91cCwgZG93bmxvYWRGYWlsZWQsIGRvd25sb2FkUGVuZGluZywgaW5kZXggKyAxLCBmaWxlQ291bnQpOworICAgICAgfQorCisgICAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgICBkYXRhRmlsZSwgZGF0YUZpbGVHcm91cC5nZXRBbGxvd2VkUmVhZGVyc0VudW0oKSk7CisgICAgICByZXR1cm4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKHNoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMobmV3RmlsZUtleSkpCisgICAgICAgICAgLmNhdGNoaW5nQXN5bmMoCisgICAgICAgICAgICAgIFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICBlIC0+IHsKKyAgICAgICAgICAgICAgICAvLyBUT0RPKGIvMTE4MTM3NjcyKTogcmVjb25zaWRlciBvbiB0aGUgc3dhbGxvd2VkIGV4Y2VwdGlvbi4KKyAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICIlczogRW5jb3VudGVyZWQgU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24gZm9yIGdyb3VwOiAlcyIsCisgICAgICAgICAgICAgICAgICAgIFRBRywgZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICAgICAgICAgICAgc2lsZW50RmVlZGJhY2suc2VuZChlLCAiU2hhcmVkIGZpbGUgbm90IGZvdW5kIGluIGdldEZpbGVHcm91cERvd25sb2FkU3RhdHVzIik7CisgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLk5PTkUpOworICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgZmlsZVN0YXR1cyAtPiB7CisgICAgICAgICAgICAgICAgaWYgKGZpbGVTdGF0dXMgPT0gRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkgeworICAgICAgICAgICAgICAgICAgTG9nVXRpbC5kKAorICAgICAgICAgICAgICAgICAgICAgICIlczogRmlsZSAlcyBkb3dubG9hZGVkIGZvciBncm91cDogJXMiLAorICAgICAgICAgICAgICAgICAgICAgIFRBRywgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldEZpbGVHcm91cERvd25sb2FkU3RhdHVzSXRlcigKKyAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLCBkb3dubG9hZEZhaWxlZCwgZG93bmxvYWRQZW5kaW5nLCBpbmRleCArIDEsIGZpbGVDb3VudCk7CisgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChmaWxlU3RhdHVzID09IEZpbGVTdGF0dXMuU1VCU0NSSUJFRAorICAgICAgICAgICAgICAgICAgICB8fCBmaWxlU3RhdHVzID09IEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpIHsKKyAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZCgKKyAgICAgICAgICAgICAgICAgICAgICAiJXM6IEZpbGUgJXMgbm90IGRvd25sb2FkZWQgZm9yIGdyb3VwOiAlcyIsCisgICAgICAgICAgICAgICAgICAgICAgVEFHLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICByZXR1cm4gZ2V0RmlsZUdyb3VwRG93bmxvYWRTdGF0dXNJdGVyKAorICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAsCisgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRGYWlsZWQsCisgICAgICAgICAgICAgICAgICAgICAgLyogZG93bmxvYWRQZW5kaW5nID0gKi8gdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgICBpbmRleCArIDEsCisgICAgICAgICAgICAgICAgICAgICAgZmlsZUNvdW50KTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgTG9nVXRpbC5kKAorICAgICAgICAgICAgICAgICAgICAgICIlczogRmlsZSAlcyBub3QgZG93bmxvYWRlZCBmb3IgZ3JvdXA6ICVzIiwKKyAgICAgICAgICAgICAgICAgICAgICBUQUcsIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBkYXRhRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRGaWxlR3JvdXBEb3dubG9hZFN0YXR1c0l0ZXIoCisgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cCwKKyAgICAgICAgICAgICAgICAgICAgICAvKiBkb3dubG9hZEZhaWxlZCA9ICovIHRydWUsCisgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRQZW5kaW5nLAorICAgICAgICAgICAgICAgICAgICAgIGluZGV4ICsgMSwKKyAgICAgICAgICAgICAgICAgICAgICBmaWxlQ291bnQpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgfSBlbHNlIGlmIChkb3dubG9hZEZhaWxlZCkgeyAvLyBpbmRleCA9PSBmaWxlQ291bnQKKyAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUoR3JvdXBEb3dubG9hZFN0YXR1cy5GQUlMRUQpOworICAgIH0gZWxzZSBpZiAoZG93bmxvYWRQZW5kaW5nKSB7CisgICAgICByZXR1cm4gaW1tZWRpYXRlRnV0dXJlKEdyb3VwRG93bmxvYWRTdGF0dXMuUEVORElORyk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUoR3JvdXBEb3dubG9hZFN0YXR1cy5ET1dOTE9BREVEKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogVmVyaWZ5IGlmIGFueSBvZiB0aGUgcGVuZGluZyBncm91cHMgd2FzIGRvd25sb2FkZWQuCisgICAqCisgICAqIDxwPklmIGEgZ3JvdXAgaGFzIGJlZW4gY29tcGxldGVseSBkb3dubG9hZGVkLCBpdCB3aWxsIGJlIG1hZGUgYXZhaWxhYmxlIHRoZSBuZXh0IHRpbWUgYSB7QGxpbmsKKyAgICogI2dldEZpbGVHcm91cH0gaXMgY2FsbGVkLgorICAgKi8KKyAgLy8gVE9ETyhiLzEyNDA3Mjc1NCk6IENoYW5nZSB0byBwYWNrYWdlIHByaXZhdGUgb25jZSBhbGwgY29kZSBpcyByZWZhY3RvcmVkLgorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiB2ZXJpZnlBbGxQZW5kaW5nR3JvdXBzRG93bmxvYWRlZCgKKyAgICAgIEFzeW5jRnVuY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsLCBCb29sZWFuPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpIHsKKyAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsR3JvdXBLZXlzKCksCisgICAgICAgIHByb3BhZ2F0ZUFzeW5jRnVuY3Rpb24oCisgICAgICAgICAgICBncm91cEtleUxpc3QgLT4KKyAgICAgICAgICAgICAgICB2ZXJpZnlBbGxQZW5kaW5nR3JvdXBzRG93bmxvYWRlZChncm91cEtleUxpc3QsIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvcikpKTsKKyAgfQorCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJudWxsbmVzcyIpCisgIC8vIFN1cHByZXNzIG51bGxuZXNzIHdhcm5pbmdzIGJlY2F1c2Ugb3RoZXJ3aXNlIHN0YXRpYyBhbmFseXNpcyB3b3VsZCByZXF1aXJlIHVzIHRvIGZhbHNlbHkgbGFiZWwKKyAgLy8gdmVyaWZ5UGVuZGluZ0dyb3VwRG93bmxvYWRlZCB3aXRoIEBOdWxsYWJsZVR5cGUKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHZlcmlmeUFsbFBlbmRpbmdHcm91cHNEb3dubG9hZGVkKAorICAgICAgTGlzdDxHcm91cEtleT4gZ3JvdXBLZXlMaXN0LAorICAgICAgQXN5bmNGdW5jdGlvbjxEYXRhRmlsZUdyb3VwSW50ZXJuYWwsIEJvb2xlYW4+IGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvcikgeworICAgIExpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxHcm91cERvd25sb2FkU3RhdHVzPj4gYWxsRmlsZUZ1dHVyZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBmb3IgKEdyb3VwS2V5IGdyb3VwS2V5IDogZ3JvdXBLZXlMaXN0KSB7CisgICAgICBpZiAoZ3JvdXBLZXkuZ2V0RG93bmxvYWRlZCgpKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgYWxsRmlsZUZ1dHVyZXMuYWRkKAorICAgICAgICAgIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZ3JvdXBLZXkpLAorICAgICAgICAgICAgICBwZW5kaW5nR3JvdXAgLT4geworICAgICAgICAgICAgICAgIGlmIChwZW5kaW5nR3JvdXAgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShudWxsKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIHZlcmlmeVBlbmRpbmdHcm91cERvd25sb2FkZWQoCisgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LCBwZW5kaW5nR3JvdXAsIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvcik7CisgICAgICAgICAgICAgIH0pKTsKKyAgICB9CisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLndoZW5BbGxDb21wbGV0ZShhbGxGaWxlRnV0dXJlcykKKyAgICAgICAgLmNhbGwoKCkgLT4gbnVsbCwgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvLyBUT0RPKGIvMTI0MDcyNzU0KTogQ2hhbmdlIHRvIHBhY2thZ2UgcHJpdmF0ZSBvbmNlIGFsbCBjb2RlIGlzIHJlZmFjdG9yZWQuCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRlbGV0ZVVuaW5zdGFsbGVkQXBwR3JvdXBzKCkgeworICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxHcm91cEtleXMoKSwKKyAgICAgICAgZ3JvdXBLZXlMaXN0IC0+IHsKKyAgICAgICAgICBMaXN0PExpc3RlbmFibGVGdXR1cmU8Vm9pZD4+IHJlbW92ZUdyb3VwRnV0dXJlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICAgIGZvciAoR3JvdXBLZXkga2V5IDogZ3JvdXBLZXlMaXN0KSB7CisgICAgICAgICAgICBpZiAoIWlzQXBwSW5zdGFsbGVkKGtleS5nZXRPd25lclBhY2thZ2UoKSkpIHsKKyAgICAgICAgICAgICAgcmVtb3ZlR3JvdXBGdXR1cmVzLmFkZCgKKyAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChrZXkpLAorICAgICAgICAgICAgICAgICAgICAgIGdyb3VwIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncm91cCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBEZWxldGluZyBmaWxlIGdyb3VwICVzIGZvciB1bmluc3RhbGxlZCBhcHAgJXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRBRywga2V5LmdldEdyb3VwTmFtZSgpLCBrZXkuZ2V0T3duZXJQYWNrYWdlKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlKGtleSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlU3VjY2VzcyAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlbW92ZVN1Y2Nlc3MpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgICAgICAgICAgICB9KSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy53aGVuQWxsQ29tcGxldGUocmVtb3ZlR3JvdXBGdXR1cmVzKQorICAgICAgICAgICAgICAuY2FsbCgoKSAtPiBudWxsLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgfSk7CisgIH0KKworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRlbGV0ZVJlbW92ZWRBY2NvdW50R3JvdXBzKCkgeworICAgIC8vIEluIHRoZSBsaWJyYXJ5IGNhc2UsIHRoZSBhY2NvdW50IG1hbmFnZXIgc2hvdWxkIGJlIHByZXNlbnQuIEJ1dCBpbiB0aGUgR21zQ29yZSBzZXJ2aWNlIGNhc2UsCisgICAgLy8gdGhlIGFjY291bnQgbWFuYWdlciBpcyBhYnNlbnQsIGFuZCB0aGUgcmVtb3ZlZC1hY2NvdW50IGNoZWNrIGlzIHNraXBwZWQuCisgICAgaWYgKCFhY2NvdW50U291cmNlT3B0aW9uYWwuaXNQcmVzZW50KCkpIHsKKyAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgfQorCisgICAgSW1tdXRhYmxlU2V0PFN0cmluZz4gc2VyaWFsaXplZEFjY291bnRzOworICAgIHRyeSB7CisgICAgICBzZXJpYWxpemVkQWNjb3VudHMgPSBnZXRTZXJpYWxpemVkR29vZ2xlQWNjb3VudHMoYWNjb3VudFNvdXJjZU9wdGlvbmFsLmdldCgpKTsKKyAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIGdldFNlcmlhbGl6ZWRHb29nbGVBY2NvdW50cyBjb3VsZCB0aHJvdyBhIFNlY3VyaXR5RXhjZXB0aW9uLCB3aGljaCB3aWxsIGJ1YmJsZSB1cCBhbmQKKyAgICAgIC8vIHByZXZlbnQgYW55IG90aGVyIG1haW50ZW5hbmNlIHRhc2tzIGZyb20gYmVpbmcgcGVyZm9ybWVkLiBJbnN0ZWFkLCBjYXRjaCBpdCBhbmQgd3JhcCBpdCBpbgorICAgICAgLy8gYW4gTEYgc28gb3RoZXIgdGFza3MgYXJlIHBlcmZvcm1lZCBldmVuIGlmIHRoaXMgZmFpbHMuCisgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGUpOworICAgIH0KKworICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxHcm91cEtleXMoKSwKKyAgICAgICAgZ3JvdXBLZXlMaXN0IC0+IHsKKyAgICAgICAgICBMaXN0PExpc3RlbmFibGVGdXR1cmU8Vm9pZD4+IHJlbW92ZUdyb3VwRnV0dXJlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICAgIGZvciAoR3JvdXBLZXkga2V5IDogZ3JvdXBLZXlMaXN0KSB7CisgICAgICAgICAgICBpZiAoa2V5LmdldEFjY291bnQoKS5pc0VtcHR5KCkgfHwgc2VyaWFsaXplZEFjY291bnRzLmNvbnRhaW5zKGtleS5nZXRBY2NvdW50KCkpKSB7CisgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZW1vdmVHcm91cEZ1dHVyZXMuYWRkKAorICAgICAgICAgICAgICAgIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoa2V5KSwKKyAgICAgICAgICAgICAgICAgICAgZ3JvdXAgLT4geworICAgICAgICAgICAgICAgICAgICAgIGlmIChncm91cCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBEZWxldGluZyBmaWxlIGdyb3VwICVzIGZvciByZW1vdmVkIGFjY291bnQgJXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICBUQUcsIGtleS5nZXRHcm91cE5hbWUoKSwga2V5LmdldE93bmVyUGFja2FnZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICBsb2dFdmVudFdpdGhEYXRhRmlsZUdyb3VwKDAsIGV2ZW50TG9nZ2VyLCBncm91cCk7CisKKyAgICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGdyb3VwIGZyb20gZnJlc2ggZmlsZSBncm91cHMgaWYgdGhlIGFjY291bnQgaXMgcmVtb3ZlZC4KKyAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlKGtleSksCisgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVN1Y2Nlc3MgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcmVtb3ZlU3VjY2VzcykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nRXZlbnRXaXRoRGF0YUZpbGVHcm91cCgwLCBldmVudExvZ2dlciwgZ3JvdXApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgICAgICAgICAgICAgfSkpOworICAgICAgICAgIH0KKworICAgICAgICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy53aGVuQWxsQ29tcGxldGUocmVtb3ZlR3JvdXBGdXR1cmVzKQorICAgICAgICAgICAgICAuY2FsbCgoKSAtPiBudWxsLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgfSk7CisgIH0KKworICAvKioKKyAgICogQWNjdW11bGF0ZXMgZG93bmxvYWQgc3RhcnRlZCBjb3VudC4gU2V0cyBkb3dubG9hZCBzdGFydGVkIHRpbWVzdGFtcCBpZiBpdCBoYXMgbm90IGJlZW4gc2V0CisgICAqIGJlZm9yZS4gV3JpdGVzIHRoZSBwZW5kaW5nIGdyb3VwIGJhY2sgdG8gbWV0YWRhdGEgYWZ0ZXIgdGhlIHRpbWVzdGFtcCBpcyBzZXQuIExvZ3MgZG93bmxvYWQKKyAgICogc3RhcnRlZCBldmVudC4KKyAgICovCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IHVwZGF0ZUJvb2trZWVwaW5nT25TdGFydERvd25sb2FkKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXApIHsKKyAgICAvLyBBY2N1bXVsYXRlIGRvd25sb2FkIHN0YXJ0ZWQgY291bnQsIHNpbmNlIHdlJ3JlIHNjaGVkdWxpbmcgZG93bmxvYWQgZm9yIHRoZSBmaWxlIGdyb3VwLgorICAgIERhdGFGaWxlR3JvdXBCb29ra2VlcGluZyBib29ra2VlcGluZyA9IHBlbmRpbmdHcm91cC5nZXRCb29ra2VlcGluZygpOworICAgIGludCBkb3dubG9hZFN0YXJ0ZWRDb3VudCA9IGJvb2trZWVwaW5nLmdldERvd25sb2FkU3RhcnRlZENvdW50KCkgKyAxOworICAgIHBlbmRpbmdHcm91cCA9CisgICAgICAgIHBlbmRpbmdHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEJvb2trZWVwaW5nKGJvb2trZWVwaW5nLnRvQnVpbGRlcigpLnNldERvd25sb2FkU3RhcnRlZENvdW50KGRvd25sb2FkU3RhcnRlZENvdW50KSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gT25seSBzZXQgdGhlIGRvd25sb2FkIHN0YXJ0ZWQgdGltZXN0YW1wIG9uY2UuCisgICAgYm9vbGVhbiBmaXJzdERvd25sb2FkQXR0ZW1wdCA9ICFib29ra2VlcGluZy5oYXNHcm91cERvd25sb2FkU3RhcnRlZFRpbWVzdGFtcEluTWlsbGlzKCk7CisgICAgaWYgKGZpcnN0RG93bmxvYWRBdHRlbXB0KSB7CisgICAgICBwZW5kaW5nR3JvdXAgPQorICAgICAgICAgIEZpbGVHcm91cFV0aWwuc2V0RG93bmxvYWRTdGFydGVkVGltZXN0YW1wSW5NaWxsaXMoCisgICAgICAgICAgICAgIHBlbmRpbmdHcm91cCwgdGltZVNvdXJjZS5jdXJyZW50VGltZU1pbGxpcygpKTsKKyAgICB9CisKKyAgICAvLyBWYXJpYWJsZXMgY2FwdHVyZWQgaW4gbGFtYmRhcyBtdXN0IGJlIGVmZmVjdGl2ZWx5IGZpbmFsLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXBDYXB0dXJlID0gcGVuZGluZ0dyb3VwOworICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleSA9IGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLndyaXRlKHBlbmRpbmdHcm91cEtleSwgcGVuZGluZ0dyb3VwKSwKKyAgICAgICAgd3JpdGVTdWNjZXNzIC0+IHsKKyAgICAgICAgICBpZiAoIXdyaXRlU3VjY2VzcykgeworICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZShuZXcgSU9FeGNlcHRpb24oIlVuYWJsZSB0byB1cGRhdGUgZmlsZSBncm91cCBtZXRhZGF0YSIpKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICAvLyBPbmx5IGxvZyBkb3dubG9hZCBzdGF0ZWQgZXZlbnQgd2hlbiBib29ra2VwaW5nIGlzIHN1Y2Nlc3NmdWxseSB1cGRhdGVkIHVwb24gdGhlIGZpcnN0CisgICAgICAgICAgLy8gZG93bmxvYWQgYXR0ZW1wdCAoZm9yIGRlZHVwIHB1cnBvc2VzKS4KKyAgICAgICAgICBpZiAoZmlyc3REb3dubG9hZEF0dGVtcHQpIHsKKyAgICAgICAgICAgIERvd25sb2FkU3RhdGVMb2dnZXIuZm9yRG93bmxvYWQoZXZlbnRMb2dnZXIpLmxvZ1N0YXJ0ZWQocGVuZGluZ0dyb3VwQ2FwdHVyZSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShwZW5kaW5nR3JvdXBDYXB0dXJlKTsKKyAgICAgICAgfSk7CisgIH0KKworICAvKiogR2V0cyBhIHNldCBvZiB7QGxpbmsgTmV3RmlsZUtleX0ncyB3aGljaCBhcmUgcmVmZXJlbmNlZCBieSBzb21lIGZyZXNoIGdyb3VwLiAqLworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8SW1tdXRhYmxlU2V0PE5ld0ZpbGVLZXk+PiBnZXRGaWxlS2V5c1JlZmVyZW5jZWRCeUZyZXNoR3JvdXBzKCkgeworICAgIEltbXV0YWJsZVNldC5CdWlsZGVyPE5ld0ZpbGVLZXk+IHJlZmVyZW5jZWRGaWxlS2V5cyA9IEltbXV0YWJsZVNldC5idWlsZGVyKCk7CisgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWwoCisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpLAorICAgICAgICBwYWlycyAtPiB7CisgICAgICAgICAgZm9yIChQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IHBhaXIgOiBwYWlycykgeworICAgICAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9IHBhaXIuc2Vjb25kOworICAgICAgICAgICAgZm9yIChEYXRhRmlsZSBkYXRhRmlsZSA6IGZpbGVHcm91cC5nZXRGaWxlTGlzdCgpKSB7CisgICAgICAgICAgICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgICAgICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZSwgZmlsZUdyb3VwLmdldEFsbG93ZWRSZWFkZXJzRW51bSgpKTsKKyAgICAgICAgICAgICAgcmVmZXJlbmNlZEZpbGVLZXlzLmFkZChuZXdGaWxlS2V5KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIHJlZmVyZW5jZWRGaWxlS2V5cy5idWlsZCgpOworICAgICAgICB9KTsKKyAgfQorCisgIC8qKiBMb2dzIGRvd25sb2FkIGZhaWx1cmUgcmVtb3RlbHkgdmlhIHtAY29kZSBldmVudExvZ2dlcn0uICovCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBsb2dEb3dubG9hZEZhaWx1cmUoCisgICAgICBHcm91cEtleSBncm91cEtleSwgRG93bmxvYWRFeGNlcHRpb24gZG93bmxvYWRFeGNlcHRpb24sIGxvbmcgYnVpbGRJZCwgU3RyaW5nIHZhcmlhbnRJZCkgeworICAgIFZvaWQgZ3JvdXBEZXRhaWxzID0gbnVsbDsKKworICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCkpLAorICAgICAgICBkYXRhRmlsZUdyb3VwIC0+IHsKKyAgICAgICAgICBldmVudExvZ2dlci5sb2dNZGREb3dubG9hZFJlc3VsdCgwLCBncm91cERldGFpbHMpOworICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgIH0pOworICB9CisKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IHN1YnNjcmliZUdyb3VwKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwKSB7CisgICAgcmV0dXJuIHN1YnNjcmliZUdyb3VwKGRhdGFGaWxlR3JvdXAsIC8qIGluZGV4ID0gKi8gMCwgZGF0YUZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSk7CisgIH0KKworICAvLyBCZWNhdXNlIHRoZSBkZWNpc2lvbiB0byBjb250aW51ZSBpdGVyYXRpbmcgb3Igbm90IGRlcGVuZHMgb24gdGhlIHJlc3VsdCBvZiB0aGUgYXN5bmNocm9ub3VzCisgIC8vIHJlc2VydmVGaWxlRW50cnkgb3BlcmF0aW9uLCB3ZSBoYXZlIHRvIHVzZSByZWN1cnNpb24gaW5zdGVhZCBvZiBhIGxvb3AgY29uc3RydWN0LgorICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gc3Vic2NyaWJlR3JvdXAoCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCwgaW50IGluZGV4LCBpbnQgZmlsZUNvdW50KSB7CisgICAgaWYgKGluZGV4IDwgZmlsZUNvdW50KSB7CisgICAgICBEYXRhRmlsZSBkYXRhRmlsZSA9IGRhdGFGaWxlR3JvdXAuZ2V0RmlsZShpbmRleCk7CisKKyAgICAgIC8vIFNraXAgc2lkZWxvYWRlZCBmaWxlcyBzaW5jZSB0aGV5IHdpbGwgbm90IGludGVyYWN0IHdpdGggU2hhcmVkRmlsZU1hbmFnZXIKKyAgICAgIGlmIChGaWxlR3JvdXBVdGlsLmlzU2lkZWxvYWRlZEZpbGUoZGF0YUZpbGUpKSB7CisgICAgICAgIHJldHVybiBzdWJzY3JpYmVHcm91cChkYXRhRmlsZUdyb3VwLCBpbmRleCArIDEsIGZpbGVDb3VudCk7CisgICAgICB9CisKKyAgICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoCisgICAgICAgICAgICAgIGRhdGFGaWxlLCBkYXRhRmlsZUdyb3VwLmdldEFsbG93ZWRSZWFkZXJzRW51bSgpKTsKKyAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgc2hhcmVkRmlsZU1hbmFnZXIucmVzZXJ2ZUZpbGVFbnRyeShuZXdGaWxlS2V5KSwKKyAgICAgICAgICBzdWNjZXNzIC0+IHsKKyAgICAgICAgICAgIGlmICghc3VjY2VzcykgeworICAgICAgICAgICAgICAvLyBJZiB3ZSBmYWlsIHRvIHJlc2VydmUgZm9yIG9uZSBvZiB0aGUgZmlsZXMsIHJldHVybiBpbW1lZGlhdGVseS4gQW55IGZpbGVzIGFkZGVkCisgICAgICAgICAgICAgIC8vIGFscmVhZHkgd2lsbCBiZSBjbGVhcmVkIGJ5IGdhcmJhZ2UgY29sbGVjdGlvbi4KKyAgICAgICAgICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICAgICAgICAgIiVzOiBTdWJzY3JpYmluZyB0byBmaWxlIGZhaWxlZCBmb3IgZ3JvdXA6ICVzIiwKKyAgICAgICAgICAgICAgICAgIFRBRywgZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUoZmFsc2UpOworICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgcmV0dXJuIHN1YnNjcmliZUdyb3VwKGRhdGFGaWxlR3JvdXAsIGluZGV4ICsgMSwgZmlsZUNvdW50KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9KTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZSh0cnVlKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gaXNBZGRlZEdyb3VwRHVwbGljYXRlKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwKSB7CisgICAgLy8gU2VhcmNoIGZvciBhIG5vbi1kb3dubG9hZGVkIHZlcnNpb24gb2YgdGhpcyBncm91cC4KKyAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXkgPSBncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKHBlbmRpbmdHcm91cEtleSksCisgICAgICAgIHBlbmRpbmdHcm91cCAtPiB7CisgICAgICAgICAgaWYgKHBlbmRpbmdHcm91cCAhPSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRnV0dXJlKGFyZVNhbWVHcm91cChkYXRhRmlsZUdyb3VwLCBwZW5kaW5nR3JvdXApKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICAvLyBTZWFyY2ggZm9yIGEgZG93bmxvYWRlZCB2ZXJzaW9uIG9mIHRoaXMgZ3JvdXAuCisgICAgICAgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5ID0gZ3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZCh0cnVlKS5idWlsZCgpOworICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGRvd25sb2FkZWRHcm91cEtleSksCisgICAgICAgICAgICAgIGRvd25sb2FkZWRHcm91cCAtPiB7CisgICAgICAgICAgICAgICAgYm9vbGVhbiByZXN1bHQgPQorICAgICAgICAgICAgICAgICAgICAoZG93bmxvYWRlZEdyb3VwID09IG51bGwpCisgICAgICAgICAgICAgICAgICAgICAgICA/IGZhbHNlCisgICAgICAgICAgICAgICAgICAgICAgICA6IGFyZVNhbWVHcm91cChkYXRhRmlsZUdyb3VwLCBkb3dubG9hZGVkR3JvdXApOworICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUocmVzdWx0KTsKKyAgICAgICAgICAgICAgfSk7CisgICAgICAgIH0pOworICB9CisKKyAgLyoqCisgICAqIENoZWNrIGlmIHRoZSBuZXcgZ3JvdXAgaXMgc2FtZSBhcyBleGlzdGluZyB2ZXJzaW9uLiBUaGlzIGp1c3QgY2hlY2tzIHRoZSBmaWVsZHMgdGhhdCB3ZSBleHBlY3QKKyAgICogdG8gYmUgc2V0IHdoZW4gd2UgcmVjZWl2ZSBhIG5ldyBncm91cC4gT3RoZXIgZmllbGRzIGFyZSBpZ25vcmVkLgorICAgKgorICAgKiBAcGFyYW0gbmV3R3JvdXAgVGhlIG5ldyBjb25maWcgdGhhdCB3ZSByZWNlaXZlZCBmb3IgdGhlIGNsaWVudC4KKyAgICogQHBhcmFtIHByZXZHcm91cCBUaGUgb2xkIGNvbmZpZyB0aGF0IHdlIGFscmVhZHkgaGF2ZSBmb3IgdGhlIGNsaWVudC4KKyAgICogQHJldHVybiB0cnVlIGlmIHRoZSBuZXcgY29uZmlnIGNvbnRhaW5zIGFuIHVwZ3JhZGUgdG8gYW55IGZpbGUuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGFyZVNhbWVHcm91cCgKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBuZXdHcm91cCwgRGF0YUZpbGVHcm91cEludGVybmFsIHByZXZHcm91cCkgeworICAgIC8vIFdlIGRvIG5vdCBjb21wYXJlIHRoZSBwcm90b3MgZGlyZWN0bHkgYW5kIGNoZWNrIGluZGl2aWR1YWwgZmllbGRzIGJlY2F1c2UgcHJvdG8uZXF1YWxzCisgICAgLy8gYWxzbyBjb21wYXJlcyBleHRlbnNpb25zIChhbmQgdW5rbm93biBmaWVsZHMpLgorICAgIC8vIFRPRE86IENvbnNpZGVyIGNsZWFyaW5nIGV4dGVuc2lvbnMgYW5kIHRoZW4gY29tcGFyaW5nIHByb3Rvcy4KKyAgICBpZiAocHJldkdyb3VwLmdldEJ1aWxkSWQoKSAhPSBuZXdHcm91cC5nZXRCdWlsZElkKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKCFwcmV2R3JvdXAuZ2V0VmFyaWFudElkKCkuZXF1YWxzKG5ld0dyb3VwLmdldFZhcmlhbnRJZCgpKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAocHJldkdyb3VwLmdldEZpbGVHcm91cFZlcnNpb25OdW1iZXIoKSAhPSBuZXdHcm91cC5nZXRGaWxlR3JvdXBWZXJzaW9uTnVtYmVyKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKCFoYXNTYW1lRmlsZXMobmV3R3JvdXAsIHByZXZHcm91cCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKHByZXZHcm91cC5nZXRTdGFsZUxpZmV0aW1lU2VjcygpICE9IG5ld0dyb3VwLmdldFN0YWxlTGlmZXRpbWVTZWNzKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgaWYgKHByZXZHcm91cC5nZXRFeHBpcmF0aW9uRGF0ZVNlY3MoKSAhPSBuZXdHcm91cC5nZXRFeHBpcmF0aW9uRGF0ZVNlY3MoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpZiAoIXByZXZHcm91cC5nZXREb3dubG9hZENvbmRpdGlvbnMoKS5lcXVhbHMobmV3R3JvdXAuZ2V0RG93bmxvYWRDb25kaXRpb25zKCkpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmICghcHJldkdyb3VwLmdldEFsbG93ZWRSZWFkZXJzRW51bSgpLmVxdWFscyhuZXdHcm91cC5nZXRBbGxvd2VkUmVhZGVyc0VudW0oKSkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvKioKKyAgICogQ2hlY2sgaWYgdGhlIG5ldyBncm91cCBoYXMgdGhlIHNhbWUgc2V0IG9mIGZpbGVzIGFzIHByZXYgZ3JvdXBzLgorICAgKgorICAgKiBAcGFyYW0gbmV3R3JvdXAgVGhlIG5ldyBjb25maWcgdGhhdCB3ZSByZWNlaXZlZCBmb3IgdGhlIGNsaWVudC4KKyAgICogQHBhcmFtIHByZXZHcm91cCBUaGUgb2xkIGNvbmZpZyB0aGF0IHdlIGFscmVhZHkgaGF2ZSBmb3IgdGhlIGNsaWVudC4KKyAgICogQHJldHVybiB0cnVlIGlmZiAtIEFsbCB1cmxUb0Rvd25sb2FkcyBhcmUgdGhlIHNhbWUgLSBUaGVpciBjaGVja3N1bXMgYXJlIHRoZSBzYW1lIC0gVGhlaXIgc2l6ZXMKKyAgICogICAgIGFyZSB0aGUgc2FtZS4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaGFzU2FtZUZpbGVzKAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIG5ld0dyb3VwLCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcHJldkdyb3VwKSB7CisgICAgcmV0dXJuIG5ld0dyb3VwLmdldEZpbGVMaXN0KCkuZXF1YWxzKHByZXZHcm91cC5nZXRGaWxlTGlzdCgpKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IG1heWJlU2V0R3JvdXBOZXdGaWxlc1JlY2VpdmVkVGltZXN0YW1wKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbCByZWNlaXZlZEZpbGVHcm91cCkgeworICAgIC8vIFNlYXJjaCBmb3IgYSBub24tZG93bmxvYWRlZCB2ZXJzaW9uIG9mIHRoaXMgZ3JvdXAuCisgICAgR3JvdXBLZXkgcGVuZGluZ0dyb3VwS2V5ID0gZ3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKyAgICByZXR1cm4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChwZW5kaW5nR3JvdXBLZXkpLAorICAgICAgICBwZW5kaW5nR3JvdXAgLT4geworICAgICAgICAgIC8vIFdlIHdpbGwgb25seSBzZXQgdGhlIEdyb3VwTmV3RmlsZXNSZWNlaXZlZFRpbWVzdGFtcCB3aGVuIGVpdGhlciB0aGlzIGlzIHRoZSBmaXJzdCB0aW1lCisgICAgICAgICAgLy8gd2UgcmVjZWl2ZSB0aGlzIEZpbGUgR3JvdXAgb3IgdGhlIGZpbGVzIGFyZSBjaGFuZ2VkLiBJbiBvdGhlciBjYXNlcywgd2Ugd2lsbCBrZWVwIHRoZQorICAgICAgICAgIC8vIGV4aXN0aW5nIHRpbWVzdGFtcC4gVGhpcyB3aWxsIGF2b2lkIHJlc2V0IHRpbWVzdGFtcCB3aGVuIG1ldGFkYXRhIG9mIHRoZSBGaWxlIEdyb3VwCisgICAgICAgICAgLy8gY2hhbmdlcyBidXQgdGhlIGZpbGVzIHN0YXkgdGhlIHNhbWUuCisgICAgICAgICAgbG9uZyBncm91cE5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXA7CisgICAgICAgICAgaWYgKHBlbmRpbmdHcm91cCAhPSBudWxsICYmIGhhc1NhbWVGaWxlcyhyZWNlaXZlZEZpbGVHcm91cCwgcGVuZGluZ0dyb3VwKSkgeworICAgICAgICAgICAgLy8gVGhlIGZpbGVzIGFyZSBub3QgY2hhbmdlZCwgd2Ugd2lsbCBjb3B5IG92ZXIgdGhlIHRpbWVzdGFtcCBmcm9tIHRoZSBwZW5kaW5nIGdyb3VwLgorICAgICAgICAgICAgZ3JvdXBOZXdGaWxlc1JlY2VpdmVkVGltZXN0YW1wID0KKyAgICAgICAgICAgICAgICBwZW5kaW5nR3JvdXAuZ2V0Qm9va2tlZXBpbmcoKS5nZXRHcm91cE5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXAoKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLy8gRmlyc3QgdGltZSB3ZSByZWNlaXZlIHRoaXMgRmlsZUdyb3VwIG9yIHRoZSBmaWxlcyBhcmUgY2hhbmdlZCwgc2V0IHRoZSB0aW1lc3RhbXAgdG8KKyAgICAgICAgICAgIC8vIHRoZSBjdXJyZW50IHRpbWUuCisgICAgICAgICAgICBncm91cE5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXAgPSB0aW1lU291cmNlLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgICAgICAgICAgfQorICAgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCByZWNlaXZlZEZpbGVHcm91cFdpdGhUaW1lc3RhbXAgPQorICAgICAgICAgICAgICBGaWxlR3JvdXBVdGlsLnNldEdyb3VwTmV3RmlsZXNSZWNlaXZlZFRpbWVzdGFtcCgKKyAgICAgICAgICAgICAgICAgIHJlY2VpdmVkRmlsZUdyb3VwLCBncm91cE5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXApOworICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUocmVjZWl2ZWRGaWxlR3JvdXBXaXRoVGltZXN0YW1wKTsKKyAgICAgICAgfSk7CisgIH0KKworICBwcml2YXRlIGJvb2xlYW4gaXNBcHBJbnN0YWxsZWQoU3RyaW5nIHBhY2thZ2VOYW1lKSB7CisgICAgdHJ5IHsKKyAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU1hbmFnZXIoKS5nZXRBcHBsaWNhdGlvbkluZm8ocGFja2FnZU5hbWUsIDApOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfSBjYXRjaCAoTmFtZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIEltbXV0YWJsZVNldDxTdHJpbmc+IGdldFNlcmlhbGl6ZWRHb29nbGVBY2NvdW50cyhBY2NvdW50U291cmNlIGFjY291bnRTb3VyY2UpIHsKKyAgICBJbW11dGFibGVMaXN0PEFjY291bnQ+IGFjY291bnRzID0gYWNjb3VudFNvdXJjZS5nZXRBbGxBY2NvdW50cygpOworCisgICAgSW1tdXRhYmxlU2V0LkJ1aWxkZXI8U3RyaW5nPiBzZXJpYWxpemVkQWNjb3VudHMgPSBuZXcgSW1tdXRhYmxlU2V0LkJ1aWxkZXI8PigpOworICAgIGZvciAoQWNjb3VudCBhY2NvdW50IDogYWNjb3VudHMpIHsKKyAgICAgIGlmIChhY2NvdW50Lm5hbWUgIT0gbnVsbCAmJiBhY2NvdW50LnR5cGUgIT0gbnVsbCkgeworICAgICAgICBzZXJpYWxpemVkQWNjb3VudHMuYWRkKEFjY291bnRVdGlsLnNlcmlhbGl6ZShhY2NvdW50KSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBzZXJpYWxpemVkQWNjb3VudHMuYnVpbGQoKTsKKyAgfQorCisgIC8vIExvZ3MgYW5kIGRlbGV0ZXMgZmlsZSBncm91cHMgd2hlcmUgYSBmaWxlIGlzIG1pc3Npbmcgb3IgY29ycnVwdGVkLCBhbGxvd2luZyB0aGUgZ3JvdXAgYW5kIGl0cworICAvLyBmaWxlcyB0byBiZSBhZGRlZCBhZ2FpbiB2aWEgcGhlbm90eXBlLgorICAvLworICAvLyBGb3IgZGV0YWlsLCBzZWUgYi8xMTk1NTU3NTYuCisgIC8vIFRPRE8oYi8xMjQwNzI3NTQpOiBDaGFuZ2UgdG8gcGFja2FnZSBwcml2YXRlIG9uY2UgYWxsIGNvZGUgaXMgcmVmYWN0b3JlZC4KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gbG9nQW5kRGVsZXRlRm9yTWlzc2luZ1NoYXJlZEZpbGVzKCkgeworICAgIHJldHVybiBpdGVyYXRlT3ZlckFsbEZpbGVHcm91cHMoCisgICAgICAgIGdyb3VwS2V5QW5kR3JvdXAgLT4geworICAgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gZ3JvdXBLZXlBbmRHcm91cC5kYXRhRmlsZUdyb3VwKCk7CisKKyAgICAgICAgICBpZiAoZGF0YUZpbGVHcm91cCA9PSBudWxsKSB7CisgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgIH0KKworICAgICAgICAgIGZvciAoRGF0YUZpbGUgZGF0YUZpbGUgOiBkYXRhRmlsZUdyb3VwLmdldEZpbGVMaXN0KCkpIHsKKyAgICAgICAgICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgICAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoCisgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLCBkYXRhRmlsZUdyb3VwLmdldEFsbG93ZWRSZWFkZXJzRW51bSgpKTsKKyAgICAgICAgICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gdW51c2VkID0KKyAgICAgICAgICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy5jYXRjaGluZ0FzeW5jKAorICAgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlTWFuYWdlci5yZVZlcmlmeUZpbGUobmV3RmlsZUtleSwgZGF0YUZpbGUpLAorICAgICAgICAgICAgICAgICAgICBTaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICAgICAgICAgZSAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgTG9nVXRpbC5lKCIlczogTWlzc2luZyBmaWxlLiBMb2dnaW5nIGFuZCBkZWxldGluZyBmaWxlIGdyb3VwLiIsIFRBRyk7CisgICAgICAgICAgICAgICAgICAgICAgbG9nRXZlbnRXaXRoRGF0YUZpbGVHcm91cCgwLCBldmVudExvZ2dlciwgZGF0YUZpbGVHcm91cCk7CisKKyAgICAgICAgICAgICAgICAgICAgICBpZiAoZmxhZ3MuZGVsZXRlRmlsZUdyb3Vwc1dpdGhGaWxlc01pc3NpbmcoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlKGdyb3VwS2V5QW5kR3JvdXAuZ3JvdXBLZXkoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2sgLT4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgIH0pOworICB9CisKKyAgLyoqCisgICAqIFZlcmlmaWVzIHRoYXQgYW55IGlzb2xhdGVkIGZpbGVzIChzeW1saW5rcykgc3RpbGwgZXhpc3QgZm9yIGFsbCBmaWxlIGdyb3Vwcy4gSWYgYW55IGFyZQorICAgKiBtaXNzaW5nLCBpdCBhdHRlbXB0cyB0byByZWNyZWF0ZSB0aGVtLgorICAgKi8KKyAgQFRhcmdldEFwaShWRVJTSU9OX0NPREVTLkxPTExJUE9QKQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiB2ZXJpZnlBbmRBdHRlbXB0VG9SZXBhaXJJc29sYXRlZEZpbGVzKCkgeworICAgIC8vIE5vIHN5bWxpbmtzIGF2YWlsYWJsZSBvbiBwcmUtTG9sbGlwb3AgZGV2aWNlcworICAgIGlmIChWRVJTSU9OLlNES19JTlQgPCBWRVJTSU9OX0NPREVTLkxPTExJUE9QKSB7CisgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgIH0KKworICAgIHJldHVybiBpdGVyYXRlT3ZlckFsbEZpbGVHcm91cHMoCisgICAgICAgIGdyb3VwS2V5QW5kR3JvdXAgLT4geworICAgICAgICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gZ3JvdXBLZXlBbmRHcm91cC5ncm91cEtleSgpOworICAgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gZ3JvdXBLZXlBbmRHcm91cC5kYXRhRmlsZUdyb3VwKCk7CisKKyAgICAgICAgICBpZiAoZGF0YUZpbGVHcm91cCA9PSBudWxsCisgICAgICAgICAgICAgIHx8ICFncm91cEtleS5nZXREb3dubG9hZGVkKCkKKyAgICAgICAgICAgICAgfHwgIUZpbGVHcm91cFV0aWwuaXNJc29sYXRlZFN0cnVjdHVyZUFsbG93ZWQoZGF0YUZpbGVHcm91cCkpIHsKKyAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgfQorCisgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgbWF5YmVWZXJpZnlJc29sYXRlZFN0cnVjdHVyZShkYXRhRmlsZUdyb3VwLCAvKmlzRG93bmxvYWRlZD0qLyB0cnVlKSwKKyAgICAgICAgICAgICAgdmVyaWZpZWQgLT4geworICAgICAgICAgICAgICAgIGlmICghdmVyaWZpZWQpIHsKKyAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlLmZyb20oY3JlYXRlSXNvbGF0ZWRGaWxlUGF0aHMoZGF0YUZpbGVHcm91cCkpCisgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoaW5nQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBleGNlcHRpb24gLT4geworICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ1V0aWwudygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFVuYWJsZSB0byBjb3JyZWN0IGlzb2xhdGVkIHN0cnVjdHVyZSwgcmV0dXJuaW5nIG51bGwiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgaW5zdGVhZCBvZiBncm91cCAlcyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRBRywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgIH0pOworICAgICAgICB9KTsKKyAgfQorCisgIEBBdXRvVmFsdWUKKyAgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEdyb3VwS2V5QW5kR3JvdXAgeworICAgIHN0YXRpYyBHcm91cEtleUFuZEdyb3VwIGNyZWF0ZSgKKyAgICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksIEBOdWxsYWJsZSBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCkgeworICAgICAgcmV0dXJuIG5ldyBBdXRvVmFsdWVfRmlsZUdyb3VwTWFuYWdlcl9Hcm91cEtleUFuZEdyb3VwKGdyb3VwS2V5LCBkYXRhRmlsZUdyb3VwKTsKKyAgICB9CisKKyAgICBhYnN0cmFjdCBHcm91cEtleSBncm91cEtleSgpOworCisgICAgQE51bGxhYmxlCisgICAgYWJzdHJhY3QgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAoKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBpdGVyYXRlT3ZlckFsbEZpbGVHcm91cHMoCisgICAgICBBc3luY0Z1bmN0aW9uPEdyb3VwS2V5QW5kR3JvdXAsIFZvaWQ+IHByb2Nlc3NHcm91cCkgeworCisgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PiBhbGxHcm91cHNQcm9jZXNzZWQgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxHcm91cEtleXMoKSwKKyAgICAgICAgZ3JvdXBLZXlMaXN0IC0+IHsKKyAgICAgICAgICBmb3IgKEdyb3VwS2V5IGdyb3VwS2V5IDogZ3JvdXBLZXlMaXN0KSB7CisgICAgICAgICAgICBhbGxHcm91cHNQcm9jZXNzZWQuYWRkKAorICAgICAgICAgICAgICAgIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZ3JvdXBLZXkpLAorICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwIC0+CisgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzR3JvdXAuYXBwbHkoR3JvdXBLZXlBbmRHcm91cC5jcmVhdGUoZ3JvdXBLZXksIGRhdGFGaWxlR3JvdXApKSkpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMud2hlbkFsbENvbXBsZXRlKGFsbEdyb3Vwc1Byb2Nlc3NlZCkKKyAgICAgICAgICAgICAgLmNhbGwoKCkgLT4gbnVsbCwgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgIH0pOworICB9CisKKyAgLyoqIER1bXBzIHRoZSBjdXJyZW50IGludGVybmFsIHN0YXRlIG9mIHRoZSBGaWxlR3JvdXBNYW5hZ2VyLiAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkdW1wKGZpbmFsIFByaW50V3JpdGVyIHdyaXRlcikgeworICAgIHdyaXRlci5wcmludGxuKCI9PT09IE1ERF9GSUxFX0dST1VQX01BTkFHRVIgPT09PSIpOworICAgIHdyaXRlci5wcmludGxuKCJNRERfRlJFU0hfRklMRV9HUk9VUFM6Iik7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiB3cml0ZURhdGFGaWxlR3JvdXBzRnV0dXJlID0KKyAgICAgICAgdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCksCisgICAgICAgICAgICBkYXRhRmlsZUdyb3VwcyAtPiB7CisgICAgICAgICAgICAgIEFycmF5TGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBzb3J0ZWRGaWxlR3JvdXBzID0KKyAgICAgICAgICAgICAgICAgIG5ldyBBcnJheUxpc3Q8PihkYXRhRmlsZUdyb3Vwcyk7CisgICAgICAgICAgICAgIENvbGxlY3Rpb25zLnNvcnQoCisgICAgICAgICAgICAgICAgICBzb3J0ZWRGaWxlR3JvdXBzLAorICAgICAgICAgICAgICAgICAgKHBhaXJBLCBwYWlyQikgLT4KKyAgICAgICAgICAgICAgICAgICAgICBDb21wYXJpc29uQ2hhaW4uc3RhcnQoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAuY29tcGFyZShwYWlyQS5maXJzdC5nZXRHcm91cE5hbWUoKSwgcGFpckIuZmlyc3QuZ2V0R3JvdXBOYW1lKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb21wYXJlKHBhaXJBLmZpcnN0LmdldEFjY291bnQoKSwgcGFpckIuZmlyc3QuZ2V0QWNjb3VudCgpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAucmVzdWx0KCkpOworICAgICAgICAgICAgICBmb3IgKFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZGF0YUZpbGVHcm91cFBhaXIgOiBzb3J0ZWRGaWxlR3JvdXBzKSB7CisgICAgICAgICAgICAgICAgLy8gVE9ETyhiLzEzMTE2NjkyNSk6IE1ERCBkdW1wIHNob3VsZCBub3QgdXNlIGxpdGUgcHJvdG8gdG9TdHJpbmcuCisgICAgICAgICAgICAgICAgd3JpdGVyLmZvcm1hdCgKKyAgICAgICAgICAgICAgICAgICAgIkdyb3VwTmFtZTogJXNcbkFjY291bnQ6ICVzXG5EYXRhRmlsZUdyb3VwOlxuICVzXG5cbiIsCisgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXBQYWlyLmZpcnN0LmdldEdyb3VwTmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwUGFpci5maXJzdC5nZXRBY2NvdW50KCksCisgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXBQYWlyLnNlY29uZC50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgfSk7CisgICAgcmV0dXJuIHRyYW5zZm9ybVNlcXVlbnRpYWxBc3luYygKKyAgICAgICAgd3JpdGVEYXRhRmlsZUdyb3Vwc0Z1dHVyZSwKKyAgICAgICAgdm9pZFBhcmFtIC0+IHsKKyAgICAgICAgICB3cml0ZXIucHJpbnRsbigiTUREX1NUQUxFX0ZJTEVfR1JPVVBTOiIpOworICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1TZXF1ZW50aWFsQXN5bmMoCisgICAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxTdGFsZUdyb3VwcygpLAorICAgICAgICAgICAgICBzdGFsZUdyb3VwcyAtPiB7CisgICAgICAgICAgICAgICAgZm9yIChEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwIDogc3RhbGVHcm91cHMpIHsKKyAgICAgICAgICAgICAgICAgIC8vIFRPRE8oYi8xMzExNjY5MjUpOiBNREQgZHVtcCBzaG91bGQgbm90IHVzZSBsaXRlIHByb3RvIHRvU3RyaW5nLgorICAgICAgICAgICAgICAgICAgd3JpdGVyLmZvcm1hdCgKKyAgICAgICAgICAgICAgICAgICAgICAiR3JvdXBOYW1lOiAlc1xuRGF0YUZpbGVHcm91cDpcbiVzXG4iLAorICAgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSwgZmlsZUdyb3VwLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICB9KTsKKyAgICAgICAgfSk7CisgIH0KKworICAvKioKKyAgICogVHJpZ2dlclN5bmMgZm9yIGFsbCBwZW5kaW5nIGdyb3Vwcy4gVGhpcyBpcyBhIGNhdGNoLWFsbCBlZmZvcnQgaW4gY2FzZSB0cmlnZ2VyU3luYyB3YXMgbm90CisgICAqIHRyaWdnZXJlZCBiZWZvcmUuCisgICAqLworICAvLyBUT0RPKGIvMTYwNzcwNzkyKTogQ2hhbmdlIHRvIHBhY2thZ2UgcHJpdmF0ZSBvbmNlIGFsbCBjb2RlIGlzIHJlZmFjdG9yZWQuCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHRyaWdnZXJTeW5jQWxsUGVuZGluZ0dyb3VwcygpIHsKKyAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2dNZGRBbmRyb2lkU2hhcmluZ0xvZygKKyAgICAgIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyLCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwLCBEYXRhRmlsZSBkYXRhRmlsZSwgaW50IGNvZGUpIHsKKyAgICBWb2lkIGFuZHJvaWRTaGFyaW5nRXZlbnQgPSBudWxsOworICAgIGV2ZW50TG9nZ2VyLmxvZ01kZEFuZHJvaWRTaGFyaW5nTG9nKGFuZHJvaWRTaGFyaW5nRXZlbnQpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2dNZGRBbmRyb2lkU2hhcmluZ0xvZygKKyAgICAgIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyLAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCwKKyAgICAgIERhdGFGaWxlIGRhdGFGaWxlLAorICAgICAgaW50IGNvZGUsCisgICAgICBib29sZWFuIGxlYXNlQWNxdWlyZWQsCisgICAgICBsb25nIGV4cGlyeURhdGUpIHsKKyAgICBWb2lkIGFuZHJvaWRTaGFyaW5nRXZlbnQgPSBudWxsOworICAgIGV2ZW50TG9nZ2VyLmxvZ01kZEFuZHJvaWRTaGFyaW5nTG9nKGFuZHJvaWRTaGFyaW5nRXZlbnQpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBsb2dFdmVudFdpdGhEYXRhRmlsZUdyb3VwKAorICAgICAgaW50IGNvZGUsIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyLCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwKSB7CisgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKAorICAgICAgICBjb2RlLAorICAgICAgICBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCksCisgICAgICAgIGZpbGVHcm91cC5nZXRGaWxlR3JvdXBWZXJzaW9uTnVtYmVyKCksCisgICAgICAgIGZpbGVHcm91cC5nZXRCdWlsZElkKCksCisgICAgICAgIGZpbGVHcm91cC5nZXRWYXJpYW50SWQoKSk7CisgIH0KKworICBwcml2YXRlIDxJLCBPPiBMaXN0ZW5hYmxlRnV0dXJlPE8+IHRyYW5zZm9ybVNlcXVlbnRpYWwoCisgICAgICBMaXN0ZW5hYmxlRnV0dXJlPEk+IGlucHV0LCBGdW5jdGlvbjw/IHN1cGVyIEksID8gZXh0ZW5kcyBPPiBmdW5jdGlvbikgeworICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm0oaW5wdXQsIGZ1bmN0aW9uLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgPEksIE8+IExpc3RlbmFibGVGdXR1cmU8Tz4gdHJhbnNmb3JtU2VxdWVudGlhbEFzeW5jKAorICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxJPiBpbnB1dCwgQXN5bmNGdW5jdGlvbjw/IHN1cGVyIEksID8gZXh0ZW5kcyBPPiBmdW5jdGlvbikgeworICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm1Bc3luYyhpbnB1dCwgZnVuY3Rpb24sIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0ZpbGVHcm91cHNNZXRhZGF0YS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9GaWxlR3JvdXBzTWV0YWRhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZjU1NWIwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9GaWxlR3JvdXBzTWV0YWRhdGEuamF2YQpAQCAtMCwwICsxLDExOCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWw7CisKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkdyb3VwS2V5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uR3JvdXBLZXlQcm9wZXJ0aWVzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IG9yZy5jaGVja2VyZnJhbWV3b3JrLmNoZWNrZXIubnVsbG5lc3MuY29tcGF0cXVhbC5OdWxsYWJsZVR5cGU7CisKKy8qKiBTdG9yZXMgYW5kIHByb3ZpZGVzIGFjY2VzcyB0byBmaWxlIGdyb3VwIG1ldGFkYXRhLiAqLworcHVibGljIGludGVyZmFjZSBGaWxlR3JvdXBzTWV0YWRhdGEgeworCisgIC8qKgorICAgKiBNYWtlcyBhbnkgY2hhbmdlcyB0aGF0IHNob3VsZCBiZSBtYWRlIGJlZm9yZSBhY2Nlc3NpbmcgdGhlIGludGVybmFsIHN0YXRlIG9mIHRoaXMgc3RvcmUuCisgICAqCisgICAqIDxwPk90aGVyIG1ldGhvZHMgaW4gdGhpcyBjbGFzcyBkbyBub3QgY2FsbCBvciBjaGVjayBpZiB0aGlzIG1ldGhvZCB3YXMgYWxyZWFkeSBjYWxsZWQgYmVmb3JlCisgICAqIHRyeWluZyB0byBhY2Nlc3MgaW50ZXJuYWwgc3RhdGUuIEl0IGlzIGV4cGVjdGVkIGZyb20gdGhlIGNhbGxlciB0byBjYWxsIHRoaXMgYmVmb3JlIGFueXRoaW5nCisgICAqIGVsc2UuCisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGluaXQoKTsKKworICAvKiogUmV0dXJucyBhIGZ1dHVyZSByZXNvbHZpbmcgdG8gdGhlIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBhc3NvY2lhdGVkIHdpdGgga2V5ICJncm91cEtleSIuICovCisgIExpc3RlbmFibGVGdXR1cmU8QE51bGxhYmxlVHlwZSBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IHJlYWQoR3JvdXBLZXkgZ3JvdXBLZXkpOworCisgIC8qKgorICAgKiBNYXBzIHRoZSBrZXkgImdyb3VwS2V5IiB0byB0aGUgdmFsdWUgImZpbGVHcm91cCIgaW4gdGhlIHN0b3JlLiBSZXR1cm5zIGZ1dHVyZSByZXNvbHZpbmcgdG8gdHJ1ZQorICAgKiBpZiB0aGUgb3BlcmF0aW9uIHN1Y2NlZWRzLCBhbmQgZmFsc2UgaWYgbm90LgorICAgKi8KKyAgLy8gVE9ETyhiLzE1OTgyODE5OSk6IFRoaXMgbWV0aG9kIHNob3VsZCByZXR1cm4gYSBWb2lkIGZ1dHVyZSBhbmQgc2lnbmFsIGZhaWx1cmUgdXNpbmcgZXhjZXB0aW9ucworICAvLyBpbnN0ZWFkIG9mIGEgQm9vbGVhbi4KKyAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiB3cml0ZShHcm91cEtleSBncm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCk7CisKKyAgLyoqCisgICAqIFJlbW92ZXMgdGhlIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBhc3NvY2lhdGVkIHdpdGggdGhlIGtleSAiZ3JvdXBLZXkiIGluIHRoZSBzdG9yZS4gUmV0dXJucworICAgKiBmdXR1cmUgcmVzb2x2aW5nIHRvIHRydWUgaWYgdGhlIG9wZXJhdGlvbiBzdWNjZWVkcywgYW5kIGZhbHNlIGlmIG5vdC4KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gcmVtb3ZlKEdyb3VwS2V5IGdyb3VwS2V5KTsKKworICAvKiogUmV0dXJucyBhIGZ1dHVyZSByZXNvbHZpbmcgdG8gdGhlIEdyb3VwS2V5UHJvcGVydGllcyBhc3NvY2lhdGVkIHdpdGggdGhlIGtleSAiZ3JvdXBLZXkiLiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPEBOdWxsYWJsZVR5cGUgR3JvdXBLZXlQcm9wZXJ0aWVzPiByZWFkR3JvdXBLZXlQcm9wZXJ0aWVzKEdyb3VwS2V5IGdyb3VwS2V5KTsKKworICAvKioKKyAgICogTWFwcyB0aGUga2V5ICJncm91cEtleSIgdG8gdGhlIHZhbHVlICJncm91cEtleVByb3BlcnRpZXMiIGluIHRoZSBzdG9yZS4gUmV0dXJucyBmdXR1cmUKKyAgICogcmVzb2x2aW5nIHRvIHRydWUgaWYgdGhlIG9wZXJhdGlvbiBzdWNjZWVkcywgYW5kIGZhbHNlIGlmIG5vdC4KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gd3JpdGVHcm91cEtleVByb3BlcnRpZXMoCisgICAgICBHcm91cEtleSBncm91cEtleSwgR3JvdXBLZXlQcm9wZXJ0aWVzIGdyb3VwS2V5UHJvcGVydGllcyk7CisKKyAgLyoqIFJldHVybnMgYWxsIGtleXMgaW4gdGhlIHN0b3JlLiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPExpc3Q8R3JvdXBLZXk+PiBnZXRBbGxHcm91cEtleXMoKTsKKworICAvKioKKyAgICogUmV0cmlldmVzIGFsbCBncm91cHMgaW4gbWV0YWRhdGEuIFdpbGwgaWdub3JlIGdyb3VwcyB0aGF0IGFyZSB1bmFibGUgdG8gcGFyc2UuCisgICAqCisgICAqIEByZXR1cm4gQSBmdXR1cmUgcmVzb2x2aW5nIHRvIGEgbGlzdCBjb250YWluaW5nIHBhaXJzIG9mIHNlcmlhbGl6ZWQgR3JvdXBLZXlzIGFuZCB0aGUKKyAgICogICAgIGNvcnJlc3BvbmRpbmcgRGF0YUZpbGVHcm91cHMuCisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPExpc3Q8UGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPj4+IGdldEFsbEZyZXNoR3JvdXBzKCk7CisKKyAgLyoqCisgICAqIFJlbW92ZXMgYWxsIGVudHJpZXMgd2l0aCBhIGtleSBpbiBrZXlzIGZyb20gdGhlIFNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhJ3Mgc3RvcmFnZS4KKyAgICogVGhpcyBtZXRob2QgZG9lc24ndCB0YWtlIGNhcmUgb2YgZ2FyYmFnZSBjb2xsZWN0aW5nIGFueSBmaWxlcyB1c2VkIGJ5IHRoaXMgZ3JvdXAsIGFuZCB0aGF0IGlzCisgICAqIGxlZnQgZm9yIHRoZSBjYWxsZXIgdG8gZG8uCisgICAqCisgICAqIEBwYXJhbSBrZXlzIC0gdGhlIGxpc3Qgb2Yga2V5cyB0byByZW1vdmUgZW50cmllcyBmb3IKKyAgICogQHJldHVybiAtIHRydWUgaWYgdGhlIHJlbW92YWxzIHdlcmUgc3VjY2Vzc2Z1bGx5IHBlcnNpc3RlZCB0byBkaXNrLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiByZW1vdmVBbGxHcm91cHNXaXRoS2V5cyhMaXN0PEdyb3VwS2V5PiBrZXlzKTsKKworICAvKioKKyAgICogUmV0cmlldmVzIGFsbCBmaWxlIGdyb3VwcyBvbiBkZXZpY2UgdGhhdCBhcmUgbWFya2VkIGFzIHN0YWxlLgorICAgKgorICAgKiBAcmV0dXJuIEZ1dHVyZSByZXNvbHZpbmcgdG8gYSBsaXN0IG9mIERhdGFGaWxlR3JvdXBJbnRlcm5hbCdzIHN0b3JlZCBpbiB0aGUgZ2FyYmFnZSBjb2xsZWN0aW9uCisgICAqICAgICBmaWxlIG9yIGFuIGVtcHR5IGxpc3QgaWYgYW4gSU8gZXJyb3Igb2NjdXJzIG9yIGlmIHRoZSBmaWxlIGRvZXNuJ3QgZXhpc3QgKGJlY2F1c2UgYWxsCisgICAqICAgICBwcmV2aW91cyBncm91cHMgaGFkIGJlZW4gZGVsZXRlZCBhbmQgbm8gbmV3IGdyb3VwcyBoYWQgYmVlbiBhZGRlZCkuCisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPExpc3Q8RGF0YUZpbGVHcm91cEludGVybmFsPj4gZ2V0QWxsU3RhbGVHcm91cHMoKTsKKworICAvKioKKyAgICogQWRkcyBmaWxlIGdyb3VwIHRvIGxpc3Qgb2YgZmlsZSBncm91cHMgdG8gdW5zdWJzY3JpYmUgZnJvbSB3aGVuIHRoZWlyIFRUTHMgZXhwaXJlLiBUaGlzIG1ldGhvZAorICAgKiB3aWxsIHNldCB0aGUgc3RhbGVFeHBpcmF0aW9uRGF0ZSBmaWVsZCBvbiB0aGUgZmlsZSBncm91cC4KKyAgICoKKyAgICogQHBhcmFtIGZpbGVHcm91cCAtIGEgZmlsZSBncm91cCB0aGF0IGlzIG5vIGxvbmdlciBuZWVkZWQgKGFuZCBzaG91bGQgcmVsZWFzZSBhbGwgb2YgaXRzIGZpbGVzCisgICAqICAgICBvbmNlIGl0cyBUVEwgZXhwaXJlcykuIFRoZSBzdGFsZUxpZmV0aW1lU2VjcyBmaWVsZCBtdXN0IGJlIHNldC4KKyAgICogQHJldHVybiBmdXR1cmUgcmVzb2x2aW5nIHRvIGZhbHNlIGlmIGFuIElPIGVycm9yIG9jY3VycworICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiBhZGRTdGFsZUdyb3VwKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXApOworCisgIC8qKgorICAgKiBXcml0ZSBhbiBhcnJheSBvZiBzdGFsZSBmaWxlIGdyb3VwcyBpbnRvIGdhcmJhZ2UgY29sbGVjdG9yIGZpbGUuCisgICAqCisgICAqIEBwYXJhbSBmaWxlR3JvdXBzIC0gYW4gYXJyYXkgb2YgZmlsZSBncm91cHMgdG8gd3JpdGUgdG8gZ2FyYmFnZSBjb2xsZWN0aW9uIGZpbGUKKyAgICogQHJldHVybiBmdXR1cmUgcmVzb2x2aW5nIHRvIGZhbHNlIGlmIGFuIElPIGVycm9yIG9jY3VycworICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiB3cml0ZVN0YWxlR3JvdXBzKExpc3Q8RGF0YUZpbGVHcm91cEludGVybmFsPiBmaWxlR3JvdXBzKTsKKworICAvKiogRGVsZXRlcyBhbGwgc3RvcmFnZSBmb3Igc3RhbGUgZmlsZSBncm91cHMuICovCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKworICAvKiogQ2xlYXJzIGFsbCBzdG9yYWdlIHVzZWQgYnkgdGhlIFNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhIGNsYXNzLiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNsZWFyKCk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL01kZENvbnN0YW50cy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9NZGRDb25zdGFudHMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYWU4NGIyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9NZGRDb25zdGFudHMuamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbDsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworCisvKiogQ29tbW9uIE1ERCBDb25zdGFudHMgKi8KK3B1YmxpYyBjbGFzcyBNZGRDb25zdGFudHMgeworCisgIC8vIFRoZSBnbXMgYXBwIHBhY2thZ2UgbmFtZS4KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgR01TX1BBQ0tBR0UgPSAiY29tLmdvb2dsZS5hbmRyb2lkLmdtcyI7CisKKyAgLy8gTUREIFBoZW5vdHlwZSBiYXNlIHBhY2thZ2UgbmFtZS4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEJBU0VfQ09ORklHX1BBQ0tBR0VfTkFNRSA9ICJjb20uZ29vZ2xlLmFuZHJvaWQuZ21zLmljaW5nLm1kZCI7CisKKyAgLy8gVGhlIG1kZCBwYWNrYWdlIG5hbWUuIFRoaXMgaXMgYWxzbyB0aGUgbWRkIHBoZW5vdHlwZSBwYWNrYWdlIG5hbWUuCisgIC8vIFRPRE86IFJlcGxhY2UgdXNhZ2Ugd2l0aCBnZXRQaGVub3R5cGVDb25maWdQYWNrYWdlTmFtZS4KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09ORklHX1BBQ0tBR0VfTkFNRSA9ICJjb20uZ29vZ2xlLmFuZHJvaWQuZ21zLmljaW5nLm1kZCI7CisKKyAgLyoqIFJldHVybnMgdGhlIHBoIHBhY2thZ2UgbmFtZSB0aGF0IHRoZSBob3N0IGFwcCBzaG91bGQgcmVnaXN0ZXIgd2l0aCBvbiBiZWhhbGYgb2YgTURELiAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRQaGVub3R5cGVDb25maWdQYWNrYWdlTmFtZShDb250ZXh0IGNvbnRleHQpIHsKKyAgICBpZiAoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLmVxdWFscyhHTVNfUEFDS0FHRSkpIHsKKyAgICAgIHJldHVybiBCQVNFX0NPTkZJR19QQUNLQUdFX05BTUU7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBCQVNFX0NPTkZJR19QQUNLQUdFX05BTUUgKyAiIyIgKyBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCk7CisgICAgfQorICB9CisKKyAgLyoqIEljaW5nLXNwZWNpZmljIGNvbnN0YW50cy4gU291cmNlIG9mIHRydXRoIGlzIHRoZSBjb3JyZXNwb25kaW5nIEljaW5nIGZpbGVzLiAqICovCisgIC8vIFRoZSBJY2luZyBsb2cgc291cmNlIG5hbWUgZnJvbSBoZXJlOgorICAvLyA8aW50ZXJuYWw+CisgIC8vIExJTlQuSWZDaGFuZ2UKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSUNJTkdfTE9HX1NPVVJDRV9OQU1FID0gIklDSU5HIjsKKyAgLy8gTElOVC5UaGVuQ2hhbmdlKDxpbnRlcm5hbD4pCisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUREX0dDTV9UQVNLX1NFUlZJQ0VfUFJPWFlfQ0xBU1NfTkFNRSA9CisgICAgICAiY29tLmdvb2dsZS5hbmRyb2lkLmdtcy5tZGkuZG93bmxvYWQuc2VydmljZS5NZGRHY21UYXNrU2VydmljZSI7CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1BMSVRfQ0hBUiA9ICJ8IjsKKworICAvKiogVGhlIGN1c3RvbSBVUkwgc2NoZW1lIHVzZWQgYnkgTUREIHRvIGlkZW50aWZ5IGlubGluZSBmaWxlcy4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5MSU5FX0ZJTEVfVVJMX1NDSEVNRSA9ICJpbmxpbmVmaWxlIjsKKworICAvKiogVVJMIHNjaGVtZXMgdXNlZCBmb3Igc2lkZWxvYWRlZCBmaWxlcy4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU0lERUxPQURfRklMRV9VUkxfU0NIRU1FID0gImZpbGUiOworCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVNQkVEREVEX0FTU0VUX1VSTF9TQ0hFTUUgPSAiYXNzZXQiOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9NaWdyYXRpb25zLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL01pZ3JhdGlvbnMuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzFjOTI1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9NaWdyYXRpb25zLmphdmEKQEAgLTAsMCArMSwxMDggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LlNoYXJlZFByZWZlcmVuY2VzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlNpbGVudEZlZWRiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKKworLyoqIFRoaXMgY2xhc3MgaG9sZHMgdGhlIG1pZ3JhdGlvbnMgc3RhdHVzIG9mIGFueSBtaWdyYXRpb25zIGN1cnJlbnRseSBnb2luZyBvbiBpbiBNREQuICovCitwdWJsaWMgY2xhc3MgTWlncmF0aW9ucyB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJNaWdyYXRpb25zIjsKKworICBzdGF0aWMgZmluYWwgU3RyaW5nIE1ERF9NSUdSQVRJT05TID0gImdtc19pY2luZ19tZGRfbWlncmF0aW9ucyI7CisKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBQUkVGU19LRVlfTUlHUkFURURfVE9fTkVXX0ZJTEVfS0VZID0gIm1pZ3JhdGVkX3RvX25ld19maWxlX2tleSI7CisKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfRklMRV9LRVlfVkVSU0lPTiA9ICJtZGRfZmlsZV9rZXlfdmVyc2lvbiI7CisKKyAgc3RhdGljIGJvb2xlYW4gaXNNaWdyYXRlZFRvTmV3RmlsZUtleShDb250ZXh0IGNvbnRleHQpIHsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBtaWdyYXRpb25QcmVmcyA9CisgICAgICAgIGNvbnRleHQuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoTUREX01JR1JBVElPTlMsIENvbnRleHQuTU9ERV9QUklWQVRFKTsKKyAgICByZXR1cm4gbWlncmF0aW9uUHJlZnMuZ2V0Qm9vbGVhbihQUkVGU19LRVlfTUlHUkFURURfVE9fTkVXX0ZJTEVfS0VZLCBmYWxzZSk7CisgIH0KKworICAvLyBUT0RPKGIvMTI0MDcyNzU0KTogQ2hhbmdlIHRvIHBhY2thZ2UgcHJpdmF0ZSBvbmNlIGFsbCBjb2RlIGlzIHJlZmFjdG9yZWQuCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBzZXRNaWdyYXRlZFRvTmV3RmlsZUtleShDb250ZXh0IGNvbnRleHQsIGJvb2xlYW4gdmFsdWUpIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBTZXR0aW5nIG1pZ3JhdGlvbiB0byBuZXcgZmlsZSBrZXkgdG8gJXMiLCBUQUcsIHZhbHVlKTsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBtaWdyYXRpb25QcmVmcyA9CisgICAgICAgIGNvbnRleHQuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoTUREX01JR1JBVElPTlMsIENvbnRleHQuTU9ERV9QUklWQVRFKTsKKyAgICBtaWdyYXRpb25QcmVmcy5lZGl0KCkucHV0Qm9vbGVhbihQUkVGU19LRVlfTUlHUkFURURfVE9fTkVXX0ZJTEVfS0VZLCB2YWx1ZSkuY29tbWl0KCk7CisgIH0KKworICAvKiogRW51bSBmb3IgRmlsZUtleSBNaWdyYXRpb24sIE5FV19GSUxFX0tFWSBpcyB0aGUgYmFzZSB2ZXJzaW9uLiAqLworICBwdWJsaWMgZW51bSBGaWxlS2V5VmVyc2lvbiB7CisgICAgTkVXX0ZJTEVfS0VZKDApLAorICAgIEFERF9ET1dOTE9BRF9UUkFOU0ZPUk0oMSksCisKKyAgICAvLyBSZW1vdmUgYnl0ZSBzaXplIGFuZCB1cmwgZnJvbSB0aGUga2V5LCBhbmQgb25seSBkZS1kdXAgZmlsZXMgb24gY2hlY2tzdW0gb2YgdGhlIGZpbGUuCisgICAgVVNFX0NIRUNLU1VNX09OTFkoMik7CisKKyAgICBwdWJsaWMgZmluYWwgaW50IHZhbHVlOworCisgICAgRmlsZUtleVZlcnNpb24oaW50IHZhbHVlKSB7CisgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CisgICAgfQorCisgICAgc3RhdGljIEZpbGVLZXlWZXJzaW9uIGdldFZlcnNpb24oaW50IHZlcikgeworICAgICAgc3dpdGNoICh2ZXIpIHsKKyAgICAgICAgY2FzZSAwOgorICAgICAgICAgIHJldHVybiBORVdfRklMRV9LRVk7CisgICAgICAgIGNhc2UgMToKKyAgICAgICAgICByZXR1cm4gQUREX0RPV05MT0FEX1RSQU5TRk9STTsKKyAgICAgICAgY2FzZSAyOgorICAgICAgICAgIHJldHVybiBVU0VfQ0hFQ0tTVU1fT05MWTsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbmtub3duIE1ERCBGaWxlS2V5IHZlcnNpb246IiArIHZlcik7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gVE9ETyhiLzEyNDA3Mjc1NCk6IENoYW5nZSB0byBwYWNrYWdlIHByaXZhdGUgb25jZSBhbGwgY29kZSBpcyByZWZhY3RvcmVkLgorICBwdWJsaWMgc3RhdGljIEZpbGVLZXlWZXJzaW9uIGdldEN1cnJlbnRWZXJzaW9uKENvbnRleHQgY29udGV4dCwgU2lsZW50RmVlZGJhY2sgc2lsZW50RmVlZGJhY2spIHsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBtaWdyYXRpb25QcmVmcyA9CisgICAgICAgIGNvbnRleHQuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoTUREX01JR1JBVElPTlMsIENvbnRleHQuTU9ERV9QUklWQVRFKTsKKyAgICAvLyBNYWtlIE5FV19GSUxFX0tFWSB0aGUgZGVmYXVsdCwgaXQgaXMgdGhlIGJhc2UgdmVyc2lvbi4gIFdpdGhvdXQgTkVXX0ZJTEVfS0VZIG1pZ3JhdGlvbiwgdGhlCisgICAgLy8gdmVyc2lvbiBtaWdyYXRpb24gd29uJ3QgaGFwcGVuCisgICAgaW50IGZpbGVLZXlWZXJzaW9uID0KKyAgICAgICAgbWlncmF0aW9uUHJlZnMuZ2V0SW50KE1ERF9GSUxFX0tFWV9WRVJTSU9OLCBGaWxlS2V5VmVyc2lvbi5ORVdfRklMRV9LRVkudmFsdWUpOworICAgIHRyeSB7CisgICAgICByZXR1cm4gRmlsZUtleVZlcnNpb24uZ2V0VmVyc2lvbihmaWxlS2V5VmVyc2lvbik7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICAvLyBDbGVhciB0aGUgY29ycnVwdGVkIGZpbGUga2V5IG1ldGFkYXRhLCByZXR1cm4gdGhlIGRlZmF1bHQgZmlsZSBrZXkgdmVyc2lvbi4KKyAgICAgIHNpbGVudEZlZWRiYWNrLnNlbmQoCisgICAgICAgICAgZXgsICJGaWxlS2V5IHZlcnNpb24gbWV0YWRhdGEgY29ycnVwdGVkIHdpdGggdW5rbm93biB2ZXJzaW9uOiAlZCIsIGZpbGVLZXlWZXJzaW9uKTsKKyAgICAgIGNsZWFyKGNvbnRleHQpOworICAgICAgcmV0dXJuIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBzZXRDdXJyZW50VmVyc2lvbihDb250ZXh0IGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uIG5ld1ZlcnNpb24pIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBTZXR0aW5nIEZpbGVLZXlWZXJzaW9uIHRvICVzIiwgVEFHLCBuZXdWZXJzaW9uLm5hbWUoKSk7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMgbWlncmF0aW9uUHJlZnMgPQorICAgICAgICBjb250ZXh0LmdldFNoYXJlZFByZWZlcmVuY2VzKE1ERF9NSUdSQVRJT05TLCBDb250ZXh0Lk1PREVfUFJJVkFURSk7CisgICAgcmV0dXJuIG1pZ3JhdGlvblByZWZzLmVkaXQoKS5wdXRJbnQoTUREX0ZJTEVfS0VZX1ZFUlNJT04sIG5ld1ZlcnNpb24udmFsdWUpLmNvbW1pdCgpOworICB9CisKKyAgLy8gVE9ETyhiLzEyNDA3Mjc1NCk6IENoYW5nZSB0byBwYWNrYWdlIHByaXZhdGUgb25jZSBhbGwgY29kZSBpcyByZWZhY3RvcmVkLgorICBwdWJsaWMgc3RhdGljIHZvaWQgY2xlYXIoQ29udGV4dCBjb250ZXh0KSB7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMgbWlncmF0aW9uUHJlZnMgPQorICAgICAgICBjb250ZXh0LmdldFNoYXJlZFByZWZlcmVuY2VzKE1ERF9NSUdSQVRJT05TLCBDb250ZXh0Lk1PREVfUFJJVkFURSk7CisgICAgbWlncmF0aW9uUHJlZnMuZWRpdCgpLmNsZWFyKCkuY29tbWl0KCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9Nb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzI4NWViZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsNzk5IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LlNoYXJlZFByZWZlcmVuY2VzOworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkLlZFUlNJT047CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZC5WRVJTSU9OX0NPREVTOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGFuZHJvaWR4LmFubm90YXRpb24uVmlzaWJsZUZvclRlc3Rpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmlsZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GbGFnczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5TaWxlbnRGZWVkYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5hbm5vdGF0aW9ucy5JbnN0YW5jZUlkOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5UcmFuc2Zvcm1Qcm90b3M7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuRmlsZUdyb3VwTWFuYWdlci5Hcm91cERvd25sb2FkU3RhdHVzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmFubm90YXRpb25zLlNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZG93bmxvYWRlci5GaWxlVmFsaWRhdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmV4cGVyaW1lbnRhdGlvbi5Eb3dubG9hZFN0YWdlTWFuYWdlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkV2ZW50TG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuRmlsZUdyb3VwU3RhdHNMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nZ2luZ1N0YXRlU3RvcmU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5OZXR3b3JrTG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuU3RvcmFnZUxvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLkZpbGVHcm91cFV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5TaGFyZWRQcmVmZXJlbmNlc1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5Qcm9wYWdhdGVkRmx1ZW50RnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRyYWNpbmcuUHJvcGFnYXRlZEZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVNYXA7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFzeW5jRnVuY3Rpb247CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZsdWVudEZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmVycm9ycHJvbmUuYW5ub3RhdGlvbnMuQ2hlY2tSZXR1cm5WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm1zOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZS5DaGVja3N1bVR5cGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwSW50ZXJuYWw7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Eb3dubG9hZENvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLmNvbmN1cnJlbnQuTm90VGhyZWFkU2FmZTsKK2ltcG9ydCBqYXZheC5pbmplY3QuSW5qZWN0OworaW1wb3J0IG9yZy5jaGVja2VyZnJhbWV3b3JrLmNoZWNrZXIubnVsbG5lc3MuY29tcGF0cXVhbC5OdWxsYWJsZVR5cGU7CisKKy8qKgorICogTW9iaWxlIERhdGEgRG93bmxvYWQgTWFuYWdlciBpcyBhIHdyYXBwZXIgb3ZlciBhbGwgTUREIGZ1bmN0aW9ucyBhbmQgcHJvdmlkZXMgbWV0aG9kcyBmb3IgdGhlCisgKiBwdWJsaWMgQVBJIG9mIE1ERCBhcyB3ZWxsIGFzIGludGVybmFsIHBlcmlvZGljIHRhc2tzIHRoYXQgaGFuZGxlIHRoaW5ncyBsaWtlIGRvd25sb2FkaW5nIGFuZAorICogZ2FyYmFnZSBjb2xsZWN0aW9uIG9mIGRhdGEuCisgKgorICogPHA+VGhpcyBjbGFzcyBpcyBub3QgdGhyZWFkIHNhZmUsIGFuZCBhbGwgY2FsbHMgdG8gaXQgYXJlIGN1cnJlbnRseSBjaGFubmVsZWQgdGhyb3VnaCB7QGxpbmsKKyAqIGNvbS5nb29nbGUuYW5kcm9pZC5nbXMubWRpLmRvd25sb2FkLnNlcnZpY2UuRGF0YURvd25sb2FkQ2hpbWVyYVNlcnZpY2V9LCBydW5uaW5nIG9wZXJhdGlvbnMgaW4gYQorICogc2luZ2xlIHRocmVhZC4KKyAqLworQE5vdFRocmVhZFNhZmUKK0BDaGVja1JldHVyblZhbHVlCitwdWJsaWMgY2xhc3MgTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJNRERNYW5hZ2VyIjsKKworICBAVmlzaWJsZUZvclRlc3Rpbmcgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfTUFOQUdFUl9NRVRBREFUQSA9ICJnbXNfaWNpbmdfbWRkX21hbmFnZXJfbWV0YWRhdGEiOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfUEhfQ09ORklHX1ZFUlNJT04gPSAiZ21zX2ljaW5nX21kZF9tYW5hZ2VyX3BoX2NvbmZpZ192ZXJzaW9uIjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUREX1BIX0NPTkZJR19WRVJTSU9OX1RTID0KKyAgICAgICJnbXNfaWNpbmdfbWRkX21hbmFnZXJfcGhfY29uZmlnX3ZlcnNpb25fdGltZXN0YW1wIjsKKworICBAVmlzaWJsZUZvclRlc3Rpbmcgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfTUlHUkFURURfVE9fT0ZGUk9BRCA9ICJtZGRfbWlncmF0ZWRfdG9fb2Zmcm9hZCI7CisKKyAgQFZpc2libGVGb3JUZXN0aW5nIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTRVRfVFJJR0dFUiA9ICJnbXNfaWNpbmdfbWRkX3Jlc2V0X3RyaWdnZXIiOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0RBWVNfU0lOQ0VfTEFTVF9NQUlOVEVOQU5DRSA9IC0xOworCisgIHByaXZhdGUgc3RhdGljIHZvbGF0aWxlIGJvb2xlYW4gaXNJbml0aWFsaXplZCA9IGZhbHNlOworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIGZpbmFsIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyOworICBwcml2YXRlIGZpbmFsIEZpbGVHcm91cE1hbmFnZXIgZmlsZUdyb3VwTWFuYWdlcjsKKyAgcHJpdmF0ZSBmaW5hbCBGaWxlR3JvdXBzTWV0YWRhdGEgZmlsZUdyb3Vwc01ldGFkYXRhOworICBwcml2YXRlIGZpbmFsIFNoYXJlZEZpbGVNYW5hZ2VyIHNoYXJlZEZpbGVNYW5hZ2VyOworICBwcml2YXRlIGZpbmFsIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YTsKKyAgcHJpdmF0ZSBmaW5hbCBFeHBpcmF0aW9uSGFuZGxlciBleHBpcmF0aW9uSGFuZGxlcjsKKyAgcHJpdmF0ZSBmaW5hbCBTaWxlbnRGZWVkYmFjayBzaWxlbnRGZWVkYmFjazsKKyAgcHJpdmF0ZSBmaW5hbCBTdG9yYWdlTG9nZ2VyIHN0b3JhZ2VMb2dnZXI7CisgIHByaXZhdGUgZmluYWwgRmlsZUdyb3VwU3RhdHNMb2dnZXIgZmlsZUdyb3VwU3RhdHNMb2dnZXI7CisgIHByaXZhdGUgZmluYWwgTmV0d29ya0xvZ2dlciBuZXR3b3JrTG9nZ2VyOworICBwcml2YXRlIGZpbmFsIE9wdGlvbmFsPFN0cmluZz4gaW5zdGFuY2VJZDsKKyAgcHJpdmF0ZSBmaW5hbCBFeGVjdXRvciBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworICBwcml2YXRlIGZpbmFsIEZsYWdzIGZsYWdzOworICBwcml2YXRlIGZpbmFsIExvZ2dpbmdTdGF0ZVN0b3JlIGxvZ2dpbmdTdGF0ZVN0b3JlOworICBwcml2YXRlIGZpbmFsIERvd25sb2FkU3RhZ2VNYW5hZ2VyIGRvd25sb2FkU3RhZ2VNYW5hZ2VyOworCisgIEBJbmplY3QKKyAgLy8gVE9ETzogQ3JlYXRlIGEgZGVsZWdhdGVMb2dnZXIgZm9yIGFsbCBsb2dnaW5nIGluc3RlYWQgb2YgYWRkaW5nIHNlcGFyYXRlIGxvZ2dlciBmb3IKKyAgLy8gZWFjaCB0eXBlLgorICBwdWJsaWMgTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcigKKyAgICAgIEBBcHBsaWNhdGlvbkNvbnRleHQgQ29udGV4dCBjb250ZXh0LAorICAgICAgRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXIsCisgICAgICBTaGFyZWRGaWxlTWFuYWdlciBzaGFyZWRGaWxlTWFuYWdlciwKKyAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgIEZpbGVHcm91cE1hbmFnZXIgZmlsZUdyb3VwTWFuYWdlciwKKyAgICAgIEZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGEsCisgICAgICBFeHBpcmF0aW9uSGFuZGxlciBleHBpcmF0aW9uSGFuZGxlciwKKyAgICAgIFNpbGVudEZlZWRiYWNrIHNpbGVudEZlZWRiYWNrLAorICAgICAgU3RvcmFnZUxvZ2dlciBzdG9yYWdlTG9nZ2VyLAorICAgICAgRmlsZUdyb3VwU3RhdHNMb2dnZXIgZmlsZUdyb3VwU3RhdHNMb2dnZXIsCisgICAgICBOZXR3b3JrTG9nZ2VyIG5ldHdvcmtMb2dnZXIsCisgICAgICBASW5zdGFuY2VJZCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQsCisgICAgICBAU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciBFeGVjdXRvciBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLAorICAgICAgRmxhZ3MgZmxhZ3MsCisgICAgICBMb2dnaW5nU3RhdGVTdG9yZSBsb2dnaW5nU3RhdGVTdG9yZSwKKyAgICAgIERvd25sb2FkU3RhZ2VNYW5hZ2VyIGRvd25sb2FkU3RhZ2VNYW5hZ2VyKSB7CisgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsKKyAgICB0aGlzLmV2ZW50TG9nZ2VyID0gZXZlbnRMb2dnZXI7CisgICAgdGhpcy5zaGFyZWRGaWxlTWFuYWdlciA9IHNoYXJlZEZpbGVNYW5hZ2VyOworICAgIHRoaXMuc2hhcmVkRmlsZXNNZXRhZGF0YSA9IHNoYXJlZEZpbGVzTWV0YWRhdGE7CisgICAgdGhpcy5maWxlR3JvdXBNYW5hZ2VyID0gZmlsZUdyb3VwTWFuYWdlcjsKKyAgICB0aGlzLmZpbGVHcm91cHNNZXRhZGF0YSA9IGZpbGVHcm91cHNNZXRhZGF0YTsKKyAgICB0aGlzLmV4cGlyYXRpb25IYW5kbGVyID0gZXhwaXJhdGlvbkhhbmRsZXI7CisgICAgdGhpcy5zaWxlbnRGZWVkYmFjayA9IHNpbGVudEZlZWRiYWNrOworICAgIHRoaXMuc3RvcmFnZUxvZ2dlciA9IHN0b3JhZ2VMb2dnZXI7CisgICAgdGhpcy5maWxlR3JvdXBTdGF0c0xvZ2dlciA9IGZpbGVHcm91cFN0YXRzTG9nZ2VyOworICAgIHRoaXMubmV0d29ya0xvZ2dlciA9IG5ldHdvcmtMb2dnZXI7CisgICAgdGhpcy5pbnN0YW5jZUlkID0gaW5zdGFuY2VJZDsKKyAgICB0aGlzLnNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgPSBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKKyAgICB0aGlzLmxvZ2dpbmdTdGF0ZVN0b3JlID0gbG9nZ2luZ1N0YXRlU3RvcmU7CisgICAgdGhpcy5kb3dubG9hZFN0YWdlTWFuYWdlciA9IGRvd25sb2FkU3RhZ2VNYW5hZ2VyOworICB9CisKKyAgLyoqCisgICAqIE1ha2VzIHRoZSBNRERNYW5hZ2VyIHJlYWR5IGZvciB1c2UgYnkgcGVyZm9ybWluZyBhbnkgdXBncmFkZXMgdGhhdCBzaG91bGQgYmUgZG9uZSBiZWZvcmUgdXNpbmcKKyAgICogTURETWFuYWdlci4gSXQgaXMgYWxzbyByZXNwb25zaWJsZSBmb3IgaW5pdGlhbGl6aW5nIGFsbCBjbGFzc2VzIHVuZGVybmVhdGgsIGFuZCBjbGVhcnMgTURECisgICAqIGludGVybmFsIHN0b3JhZ2UgaWYgYW55IGNsYXNzIGluaXQgZmFpbHMuCisgICAqCisgICAqIDxwPlRoaXMgc2hvdWxkIGJlIHRoZSBmaXJzdCBjYWxsIGluIGFueSBwdWJsaWMgbWV0aG9kIGluIHRoaXMgY2xhc3MsIG90aGVyIHRoYW4ge0BsaW5rCisgICAqICNjbGVhcigpfS4KKyAgICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJudWxsbmVzcyIpCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGluaXQoKSB7CisgICAgaWYgKGlzSW5pdGlhbGl6ZWQpIHsKKyAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgfQorICAgIFNoYXJlZFByZWZlcmVuY2VzIHByZWZzID0KKyAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKGNvbnRleHQsIE1ERF9NQU5BR0VSX01FVEFEQVRBLCBpbnN0YW5jZUlkKTsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKQorICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICB2b2lkQXJnIC0+IHsKKyAgICAgICAgICAgICAgLy8gT2Zmcm9hZCBkb3dubG9hZGVyIG1pZ3JhdGlvbi4gU2luY2UgdGhlIG1pZ3JhdGlvbiBoYXMgYmVlbiBlbmFibGVkIGluIGdtcworICAgICAgICAgICAgICAvLyB2MTgsIG1vc3QgZGV2aWNlcyBoYXZlIG1pZ3JhdGVkLiBGb3IgdGhlIHJlbWFpbmluZywgd2Ugd2lsbCBjbGVhciBNREQKKyAgICAgICAgICAgICAgLy8gc3RvcmFnZS4KKyAgICAgICAgICAgICAgaWYgKCFwcmVmcy5nZXRCb29sZWFuKE1ERF9NSUdSQVRFRF9UT19PRkZST0FELCBmYWxzZSkpIHsKKyAgICAgICAgICAgICAgICBMb2dVdGlsLmQoIiVzIENsZWFyaW5nIE1ERCBhcyBkZXZpY2UgaXNuJ3QgbWlncmF0ZWQgdG8gb2Zmcm9hZC4iLCBUQUcpOworICAgICAgICAgICAgICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgIGNsZWFyRm9ySW5pdCgpLAorICAgICAgICAgICAgICAgICAgICB2b2lkQXJnMSAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgcHJlZnMuZWRpdCgpLnB1dEJvb2xlYW4oTUREX01JR1JBVEVEX1RPX09GRlJPQUQsIHRydWUpLmNvbW1pdCgpOworICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOworICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgdm9pZEFyZyAtPgorICAgICAgICAgICAgICAgIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlTWFuYWdlci5pbml0KCksCisgICAgICAgICAgICAgICAgICAgIGluaXRTdWNjZXNzIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICBpZiAoIWluaXRTdWNjZXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHNob3VsZCBiZSBpbml0IGJlZm9yZSB0aGUgc2hhcmVkIGZpbGUgbWV0YWRhdGEuCisgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLncoIiVzIEZhaWxlZCB0byBpbml0IHNoYXJlZCBmaWxlIG1hbmFnZXIuIiwgVEFHKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGVhckZvckluaXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIHZvaWRBcmcgLT4KKyAgICAgICAgICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS5pbml0KCksCisgICAgICAgICAgICAgICAgICAgIGluaXRTdWNjZXNzIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICBpZiAoIWluaXRTdWNjZXNzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLncoIiVzIEZhaWxlZCB0byBpbml0IHNoYXJlZCBmaWxlIG1ldGFkYXRhLiIsIFRBRyk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2xlYXJGb3JJbml0KCk7CisgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciksCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAudHJhbnNmb3JtQXN5bmModm9pZEFyZyAtPiBmaWxlR3JvdXBzTWV0YWRhdGEuaW5pdCgpLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAudHJhbnNmb3JtKAorICAgICAgICAgICAgdm9pZEFyZyAtPiB7CisgICAgICAgICAgICAgIGlzSW5pdGlhbGl6ZWQgPSB0cnVlOworICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgIH0sCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIC8qKgorICAgKiBBZGRzIHRoZSBnaXZlbiBkYXRhIGZpbGUgZ3JvdXAgZm9yIGRvd25sb2FkLCBhZnRlciBkb2luZyBzb21lIHNhbml0eSB0ZXN0aW5nIG9uIHRoZSBncm91cC4KKyAgICoKKyAgICogPHA+VGhpcyBkb2Vzbid0IHN0YXJ0IHRoZSBkb3dubG9hZCByaWdodCBhd2F5LiBUaGUgZGF0YSBpcyBkb3dubG9hZGVkIGxhdGVyIHdoZW4gdGhlIGRldmljZSBoYXMKKyAgICogd2lmaSBhdmFpbGFibGUsIGJ5IGNhbGxpbmcge0BsaW5rICNkb3dubG9hZEFsbFBlbmRpbmdHcm91cHN9LgorICAgKgorICAgKiA8cD5DYWxsaW5nIHRoaXMgYXBpIHdpdGggdGhlIGV4YWN0IHNhbWUgZmlsZSBncm91cCBtdWx0aXBsZSB0aW1lcyBpcyBhIG5vIG9wLgorICAgKgorICAgKiBAcGFyYW0gZ3JvdXBLZXkgVGhlIGtleSBmb3IgdGhlIGRhdGEgdG8gYmUgcmV0dXJuZWQuIFRoaXMgaXMgYSBjb21iaW5hdGlvbiBvZiBtYW55IHBhcmFtZXRlcnMKKyAgICogICAgIGxpa2UgZ3JvdXAgbmFtZSwgdXNlciBhY2NvdW50LgorICAgKiBAcGFyYW0gZGF0YUZpbGVHcm91cCBUaGUgRmlsZSBncm91cCB0aGF0IG5lZWRzIHRvIGJlIGRvd25sb2FkZWQuCisgICAqIEByZXR1cm4gQSBmdXR1cmUgdGhhdCByZXNvbHZlcyB0byB0cnVlIGlmIHRoZSBncm91cCB3YXMgc3VjY2Vzc2Z1bGx5IGFkZGVkIGZvciBkb3dubG9hZCwgb3IgdGhlCisgICAqICAgICBleGFjdCBncm91cCB3YXMgYWxyZWFkeSBhZGRlZCBlYXJsaWVyOyBmYWxzZSBpZiB0aGUgZ3JvdXAgYmVpbmcgYWRkZWQgd2FzIGludmFsaWQgb3IgYW4gSS9PCisgICAqICAgICBlcnJvciBvY2N1cnMuCisgICAqLworICAvLyBUT0RPKGIvMTQzNTcyNDA5KTogYWRkR3JvdXBGb3JEb3dubG9hZCgpIGNhbGwtY2hhaW4gc2hvdWxkIHJldHVybiB2b2lkIGFuZCB1c2UgZXhjZXB0aW9ucworICAvLyBpbnN0ZWFkIG9mIGJvb2xlYW4gZm9yIGZhaWx1cmUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gYWRkR3JvdXBGb3JEb3dubG9hZCgKKyAgICAgIEdyb3VwS2V5IGdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCkgeworICAgIHJldHVybiBhZGRHcm91cEZvckRvd25sb2FkSW50ZXJuYWwoCisgICAgICAgIGdyb3VwS2V5LCBkYXRhRmlsZUdyb3VwLCB1bnVzZWQgLT4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSkpOworICB9CisKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gYWRkR3JvdXBGb3JEb3dubG9hZEludGVybmFsKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCwKKyAgICAgIEFzeW5jRnVuY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsLCBCb29sZWFuPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpIHsKKyAgICBMb2dVdGlsLmQoIiVzIGFkZEdyb3VwRm9yRG93bmxvYWQgJXMiLCBUQUcsIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpKTsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIGluaXQoKSwKKyAgICAgICAgdm9pZEFyZyAtPiB7CisgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGdyb3VwIHdlIHJlY2VpdmVkIGlzIGEgdmFsaWQgZ3JvdXAuCisgICAgICAgICAgaWYgKCFEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLCBjb250ZXh0LCBmbGFncykpIHsKKyAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCksCisgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRGaWxlR3JvdXBWZXJzaW9uTnVtYmVyKCksCisgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRCdWlsZElkKCksCisgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRWYXJpYW50SWQoKSk7CisgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmFsc2UpOworICAgICAgICAgIH0KKworICAgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwb3B1bGF0ZWREYXRhRmlsZUdyb3VwID0gbWF5UG9wdWxhdGVDaGVja3N1bShkYXRhRmlsZUdyb3VwKTsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChncm91cEtleSwgcG9wdWxhdGVkRGF0YUZpbGVHcm91cCksCisgICAgICAgICAgICAgICAgYWRkR3JvdXBGb3JEb3dubG9hZFJlc3VsdCAtPiB7CisgICAgICAgICAgICAgICAgICBpZiAoYWRkR3JvdXBGb3JEb3dubG9hZFJlc3VsdCkgeworICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlci52ZXJpZnlQZW5kaW5nR3JvdXBEb3dubG9hZGVkKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LCBwb3B1bGF0ZWREYXRhRmlsZUdyb3VwLCBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpLAorICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5UGVuZGluZ0dyb3VwRG93bmxvYWRlZFJlc3VsdCAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ZXJpZnlQZW5kaW5nR3JvdXBEb3dubG9hZGVkUmVzdWx0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PSBHcm91cERvd25sb2FkU3RhdHVzLkRPV05MT0FERUQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudExvZ2dlci5sb2dFdmVudFNhbXBsZWQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcHVsYXRlZERhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcHVsYXRlZERhdGFGaWxlR3JvdXAuZ2V0RmlsZUdyb3VwVmVyc2lvbk51bWJlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3B1bGF0ZWREYXRhRmlsZUdyb3VwLmdldEJ1aWxkSWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wdWxhdGVkRGF0YUZpbGVHcm91cC5nZXRWYXJpYW50SWQoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSk7CisgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgICB9IGNhdGNoIChFeHBpcmVkRmlsZUdyb3VwRXhjZXB0aW9uCisgICAgICAgICAgICAgIHwgVW5pbnN0YWxsZWRBcHBFeGNlcHRpb24KKyAgICAgICAgICAgICAgfCBBY3RpdmF0aW9uUmVxdWlyZWRGb3JHcm91cEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICBMb2dVdGlsLncoIiVzICVzIiwgVEFHLCBlLmdldENsYXNzKCkpOworICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGUpOworICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIExvZ1V0aWwuZSgiJXMgJXMiLCBUQUcsIGUuZ2V0Q2xhc3MoKSk7CisgICAgICAgICAgICBzaWxlbnRGZWVkYmFjay5zZW5kKGUsICJGYWlsZWQgdG8gYWRkIGdyb3VwIHRvIE1ERCIpOworICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGUpOworICAgICAgICAgIH0KKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKioKKyAgICogUmVtb3ZlcyB0aGUgZmlsZSBncm91cCBmcm9tIE1ERCB3aXRoIHRoZSBnaXZlbiBncm91cCBrZXkuIFRoaXMgd2lsbCBjYW5jZWwgYW55IG9uZ29pbmcgZG93bmxvYWQKKyAgICogb2YgdGhlIGZpbGUgZ3JvdXAuCisgICAqCisgICAqIEBwYXJhbSBncm91cEtleSBUaGUga2V5IGZvciB0aGUgZmlsZSBncm91cCB0byBiZSByZW1vdmVkIGZyb20gTURELiBUaGlzIGlzIGEgY29tYmluYXRpb24gb2YKKyAgICogICAgIG1hbnkgcGFyYW1ldGVycyBsaWtlIGdyb3VwIG5hbWUsIHVzZXIgYWNjb3VudC4KKyAgICogQHBhcmFtIHBlbmRpbmdPbmx5IFdoZW4gdHJ1ZSwgb25seSByZW1vdmUgdGhlIHBlbmRpbmcgdmVyc2lvbiBvZiB0aGlzIGZpbGUgZ3JvdXAuCisgICAqIEByZXR1cm4gTGlzdGVuYWJsZUZ1dHVyZSB0aGF0IG1heSB0aHJvdyBhbiBJT0V4Y2VwdGlvbiBpZiBzb21lIGVycm9yIGlzIGVuY291bnRlcmVkIHdoZW4KKyAgICogICAgIHJlbW92aW5nIGZyb20gbWV0YWRhdGEgb3IgYSBTaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbiBpZiBzb21lIG9mIHRoZSBzaGFyZWQgZmlsZSBtZXRhZGF0YQorICAgKiAgICAgaXMgbWlzc2luZy4KKyAgICovCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlbW92ZUZpbGVHcm91cChHcm91cEtleSBncm91cEtleSwgYm9vbGVhbiBwZW5kaW5nT25seSkKKyAgICAgIHRocm93cyBTaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24geworICAgIExvZ1V0aWwuZCgiJXMgcmVtb3ZlRmlsZUdyb3VwICVzIiwgVEFHLCBncm91cEtleS5nZXRHcm91cE5hbWUoKSk7CisKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgaW5pdCgpLAorICAgICAgICB2b2lkQXJnIC0+IGZpbGVHcm91cE1hbmFnZXIucmVtb3ZlRmlsZUdyb3VwKGdyb3VwS2V5LCBwZW5kaW5nT25seSksCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIFJlbW92ZXMgdGhlIGZpbGUgZ3JvdXBzIGZyb20gTUREIHdpdGggdGhlIGdpdmVuIGdyb3VwIGtleXMuCisgICAqCisgICAqIDxwPlRoaXMgd2lsbCBjYW5jZWwgYW55IG9uZ29pbmcgZG93bmxvYWRzIG9mIGZpbGUgZ3JvdXBzIHRoYXQgc2hvdWxkIGJlIHJlbW92ZWQuCisgICAqCisgICAqIEBwYXJhbSBncm91cEtleXMgVGhlIGtleXMgb2YgZmlsZSBncm91cHMgdGhhdCBzaG91bGQgYmUgcmVtb3ZlZCBmcm9tIE1ERC4KKyAgICogQHJldHVybiBMaXN0ZW5hYmxlRnV0dXJlIHRoYXQgcmVzb2x2ZXMgd2hlbiBmaWxlIGdyb3VwcyBoYXZlIGJlZW4gZGVsZXRlZCwgb3IgZmFpbHMgaWYgc29tZQorICAgKiAgICAgZXJyb3IgaXMgZW5jb3VudGVyZWQgd2hlbiByZW1vdmluZyBtZXRhZGF0YS4KKyAgICovCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlbW92ZUZpbGVHcm91cHMoTGlzdDxHcm91cEtleT4gZ3JvdXBLZXlzKSB7CisgICAgTG9nVXRpbC5kKCIlcyByZW1vdmVGaWxlR3JvdXBzIGZvciAlZCBncm91cHMiLCBUQUcsIGdyb3VwS2V5cy5zaXplKCkpOworCisgICAgcmV0dXJuIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIGluaXQoKSwgdm9pZEFyZyAtPiBmaWxlR3JvdXBNYW5hZ2VyLnJlbW92ZUZpbGVHcm91cHMoZ3JvdXBLZXlzKSwgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB0aGUgbGF0ZXN0IGRhdGEgdGhhdCB3ZSBoYXZlIGZvciB0aGUgZ2l2ZW4gY2xpZW50IGtleS4KKyAgICoKKyAgICogQHBhcmFtIGdyb3VwS2V5IFRoZSBrZXkgZm9yIHRoZSBkYXRhIHRvIGJlIHJldHVybmVkLiBUaGlzIGlzIGEgY29tYmluYXRpb24gb2YgbWFueSBwYXJhbWV0ZXJzCisgICAqICAgICBsaWtlIGdyb3VwIG5hbWUsIHVzZXIgYWNjb3VudC4KKyAgICogQHBhcmFtIGRvd25sb2FkZWQgV2hldGhlciB0byByZXR1cm4gYSBkb3dubG9hZGVkIHZlcnNpb24gb3IgYSBwZW5kaW5nIHZlcnNpb24gb2YgdGhlIGdyb3VwLgorICAgKiBAcmV0dXJuIEEgTGlzdGVuYWJsZUZ1dHVyZSB0aGF0IHJlc29sdmVzIHRvIHRoZSByZXF1ZXN0ZWQgZGF0YSBmaWxlIGdyb3VwIGZvciB0aGUgZ2l2ZW4gZ3JvdXAKKyAgICogICAgIG5hbWUsIGlmIGl0IGV4aXN0cywgbnVsbCBvdGhlcndpc2UuCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxATnVsbGFibGVUeXBlIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZ2V0RmlsZUdyb3VwKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksIGJvb2xlYW4gZG93bmxvYWRlZCkgeworICAgIExvZ1V0aWwuZCgiJXMgZ2V0RmlsZUdyb3VwICVzICVzIiwgVEFHLCBncm91cEtleS5nZXRHcm91cE5hbWUoKSwgZ3JvdXBLZXkuZ2V0T3duZXJQYWNrYWdlKCkpOworCisgICAgcmV0dXJuIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIGluaXQoKSwKKyAgICAgICAgdm9pZEFyZyAtPiBmaWxlR3JvdXBNYW5hZ2VyLmdldEZpbGVHcm91cChncm91cEtleSwgZG93bmxvYWRlZCksCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqIFJldHVybnMgYSBmdXR1cmUgcmVzb2x2aW5nIHRvIGEgbGlzdCBvZiBhbGwgcGVuZGluZyBhbmQgZG93bmxvYWRlZCBncm91cHMgaW4gTURELiAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxMaXN0PFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4+PiBnZXRBbGxGcmVzaEdyb3VwcygpIHsKKyAgICBMb2dVdGlsLmQoIiVzIGdldEFsbEZyZXNoR3JvdXBzIiwgVEFHKTsKKworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBpbml0KCksIHZvaWRBcmcgLT4gZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCksIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgYSBmdXR1cmUgcmVzb2x2aW5nIHRvIHRoZSBVUkkgYXQgd2hpY2ggdGhlIGdpdmVuIGRhdGEgZmlsZSBpcyBsb2NhdGVkIG9uIHRoZSBkaXNjLgorICAgKiBSZXR1cm5zIG51bGwgaWYgdGhlcmUgd2FzIGVycm9yIGluIGdlbmVyYXRpbmcgdGhlIFVSSS4KKyAgICovCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPEBOdWxsYWJsZVR5cGUgVXJpPiBnZXREYXRhRmlsZVVyaSgKKyAgICAgIERhdGFGaWxlIGRhdGFGaWxlLCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCkgeworICAgIExvZ1V0aWwuZCgiJXMgZ2V0RGF0YUZpbGVVcmkgJXMgJXMiLCBUQUcsIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBkYXRhRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgaW5pdCgpLAorICAgICAgICB2b2lkQXJnIC0+IHsKKyAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPEBOdWxsYWJsZVR5cGUgVXJpPiBvbkRldmljZVVyaUZ1dHVyZSA9CisgICAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZGF0YUZpbGUsIGRhdGFGaWxlR3JvdXApOworICAgICAgICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgb25EZXZpY2VVcmlGdXR1cmUsCisgICAgICAgICAgICAgIG9uRGV2aWNlVXJpIC0+IHsKKyAgICAgICAgICAgICAgICBVcmkgZmluYWxPbkRldmljZVVyaSA9IG9uRGV2aWNlVXJpOworICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGZpbGUgZ3JvdXAgc2hvdWxkIHVzZSBpc29sYXRlZCB1cmkKKyAgICAgICAgICAgICAgICBpZiAoZmluYWxPbkRldmljZVVyaSAhPSBudWxsCisgICAgICAgICAgICAgICAgICAgICYmIEZpbGVHcm91cFV0aWwuaXNJc29sYXRlZFN0cnVjdHVyZUFsbG93ZWQoZGF0YUZpbGVHcm91cCkKKyAgICAgICAgICAgICAgICAgICAgJiYgVkVSU0lPTi5TREtfSU5UID49IFZFUlNJT05fQ09ERVMuTE9MTElQT1ApIHsKKyAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsT25EZXZpY2VVcmkgPQorICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlci5nZXRBbmRWZXJpZnlJc29sYXRlZEZpbGVVcmkoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxPbkRldmljZVVyaSwgZGF0YUZpbGUsIGRhdGFGaWxlR3JvdXApOworICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICAgICBlLAorICAgICAgICAgICAgICAgICAgICAgICAgIiVzIGdldERhdGFGaWxlVXJpICVzICVzIHVuYWJsZSB0byBnZXQgaXNvbGF0ZWQgZmlsZSB1cmkhIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIFRBRywKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgIGZpbmFsT25EZXZpY2VVcmkgPSBudWxsOworICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIGlmIChmaW5hbE9uRGV2aWNlVXJpICE9IG51bGwgJiYgZGF0YUZpbGUuaGFzUmVhZFRyYW5zZm9ybXMoKSkgeworICAgICAgICAgICAgICAgICAgZmluYWxPbkRldmljZVVyaSA9CisgICAgICAgICAgICAgICAgICAgICAgYXBwbHlUcmFuc2Zvcm1zVG9GaWxlVXJpKGZpbmFsT25EZXZpY2VVcmksIGRhdGFGaWxlLmdldFJlYWRUcmFuc2Zvcm1zKCkpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIHJldHVybiBmaW5hbE9uRGV2aWNlVXJpOworICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIFVyaSBhcHBseVRyYW5zZm9ybXNUb0ZpbGVVcmkoVXJpIGZpbGVVcmksIFRyYW5zZm9ybXMgdHJhbnNmb3JtcykgeworICAgIGlmICghZmxhZ3MuZW5hYmxlQ29tcHJlc3NlZEZpbGUoKSB8fCB0cmFuc2Zvcm1zLmdldFRyYW5zZm9ybUNvdW50KCkgPT0gMCkgeworICAgICAgcmV0dXJuIGZpbGVVcmk7CisgICAgfQorICAgIHJldHVybiBmaWxlVXJpCisgICAgICAgIC5idWlsZFVwb24oKQorICAgICAgICAuZW5jb2RlZEZyYWdtZW50KFRyYW5zZm9ybVByb3Rvcy50b0VuY29kZWRGcmFnbWVudCh0cmFuc2Zvcm1zKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgIH0KKworICAvKioKKyAgICogSW1wb3J0IGlubGluZSBmaWxlcyBpbnRvIGFuIGV4aXNpbmcgRGF0YUZpbGVHcm91cCBhbmQgdXBkYXRlIGl0cyBtZXRhZGF0YSBhY2NvcmRpbmdseS4KKyAgICoKKyAgICogQHBhcmFtIGdyb3VwS2V5IFRoZSBrZXkgb2YgZmlsZSBncm91cCB0byB1cGRhdGUKKyAgICogQHBhcmFtIGJ1aWxkSWQgYnVpbGQgaWQgdG8gaWRlbnRpZnkgdGhlIGZpbGUgZ3JvdXAgdG8gdXBkYXRlCisgICAqIEBwYXJhbSB2YXJpYW50SWQgdmFyaWFudCBpZCB0byBpZGVudGlmeSB0aGUgZmlsZSBncm91cCB0byB1cGRhdGUKKyAgICogQHBhcmFtIHVwZGF0ZWREYXRhRmlsZUxpc3QgbGlzdCBvZiBEYXRhRmlsZXMgdG8gaW1wb3J0IGludG8gdGhlIGZpbGUgZ3JvdXAKKyAgICogQHBhcmFtIGlubGluZUZpbGVNYXAgTWFwIG9mIGlubGluZSBmaWxlIHNvdXJjZXMgdG8gaW1wb3J0CisgICAqIEBwYXJhbSBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsIE9wdGlvbmFsIGN1c3RvbSBwcm9wZXJ0eSB1c2VkIHRvIGlkZW50aWZ5IHRoZSBmaWxlIGdyb3VwIHRvCisgICAqICAgICB1cGRhdGUKKyAgICogQHJldHVybiBBIExpc3RlbmFibGVGdXR1cmUgdGhhdCByZXNvbHZlcyB3aGVuIGlubGluZSBmaWxlcyBoYXZlIHN1Y2Nlc3NmdWxseSBpbXBvcnRlZAorICAgKi8KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gaW1wb3J0RmlsZXMoCisgICAgICBHcm91cEtleSBncm91cEtleSwKKyAgICAgIGxvbmcgYnVpbGRJZCwKKyAgICAgIFN0cmluZyB2YXJpYW50SWQsCisgICAgICBJbW11dGFibGVMaXN0PERhdGFGaWxlPiB1cGRhdGVkRGF0YUZpbGVMaXN0LAorICAgICAgSW1tdXRhYmxlTWFwPFN0cmluZywgRmlsZVNvdXJjZT4gaW5saW5lRmlsZU1hcCwKKyAgICAgIE9wdGlvbmFsPEFueT4gY3VzdG9tUHJvcGVydHlPcHRpb25hbCwKKyAgICAgIEFzeW5jRnVuY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsLCBCb29sZWFuPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBpbXBvcnRGaWxlcyAlcyAlcyIsIFRBRywgZ3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCksIGdyb3VwS2V5LmdldE93bmVyUGFja2FnZSgpKTsKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgaW5pdCgpLAorICAgICAgICB2b2lkQXJnIC0+CisgICAgICAgICAgICBmaWxlR3JvdXBNYW5hZ2VyLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICBncm91cEtleSwKKyAgICAgICAgICAgICAgICBidWlsZElkLAorICAgICAgICAgICAgICAgIHZhcmlhbnRJZCwKKyAgICAgICAgICAgICAgICBtYXlQb3B1bGF0ZUNoZWNrc3VtKHVwZGF0ZWREYXRhRmlsZUxpc3QpLAorICAgICAgICAgICAgICAgIGlubGluZUZpbGVNYXAsCisgICAgICAgICAgICAgICAgY3VzdG9tUHJvcGVydHlPcHRpb25hbCwKKyAgICAgICAgICAgICAgICBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpLAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIC8qKgorICAgKiBEb3dubG9hZCB0aGUgcGVuZGluZyBncm91cCB0aGF0IHdlIGhhdmUgZm9yIHRoZSBnaXZlbiBncm91cCBrZXkuCisgICAqCisgICAqIEBwYXJhbSBncm91cEtleSBUaGUga2V5IG9mIGZpbGUgZ3JvdXAgdG8gYmUgZG93bmxvYWRlZC4KKyAgICogQHBhcmFtIGRvd25sb2FkQ29uZGl0aW9uc09wdGlvbmFsIFRoZSBjb25kaXRpb25zIGZvciB0aGUgZG93bmxvYWQuIElmIGFic2VudCwgTUREIHdpbGwgdXNlIHRoZQorICAgKiAgICAgY29uZmlnIGZyb20gc2VydmVyLgorICAgKiBAcmV0dXJuIFRoZSBMaXN0ZW5hYmxlRnV0dXJlIHRoYXQgZG93bmxvYWQgdGhlIGZpbGUgZ3JvdXAuCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRvd25sb2FkRmlsZUdyb3VwKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksCisgICAgICBPcHRpb25hbDxEb3dubG9hZENvbmRpdGlvbnM+IGRvd25sb2FkQ29uZGl0aW9uc09wdGlvbmFsLAorICAgICAgQXN5bmNGdW5jdGlvbjxEYXRhRmlsZUdyb3VwSW50ZXJuYWwsIEJvb2xlYW4+IGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvcikgeworICAgIExvZ1V0aWwuZCgKKyAgICAgICAgIiVzIGRvd25sb2FkRmlsZUdyb3VwICVzICVzIiwgVEFHLCBncm91cEtleS5nZXRHcm91cE5hbWUoKSwgZ3JvdXBLZXkuZ2V0T3duZXJQYWNrYWdlKCkpOworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBpbml0KCksCisgICAgICAgIHZvaWRBcmcgLT4KKyAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgZ3JvdXBLZXksIGRvd25sb2FkQ29uZGl0aW9uc09wdGlvbmFsLm9yTnVsbCgpLCBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpLAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIC8qKgorICAgKiBTZXQgdGhlIGFjdGl2YXRpb24gc3RhdHVzIGZvciB0aGUgZ3JvdXAuCisgICAqCisgICAqIEBwYXJhbSBncm91cEtleSBUaGUga2V5IGZvciB3aGljaCB0aGUgYWN0aXZhdGlvbiBpcyB0byBiZSBzZXQuCisgICAqIEBwYXJhbSBhY3RpdmF0aW9uIFdoZXRoZXIgdGhlIGdyb3VwIHNob3VsZCBiZSBhY3RpdmF0ZWQgb3IgZGVhY3RpdmF0ZWQuCisgICAqIEByZXR1cm4gZnV0dXJlIHJlc29sdmluZyB0byB3aGV0aGVyIHRoZSBhY3RpdmF0aW9uIHdhcyBzdWNjZXNzZnVsLgorICAgKi8KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gc2V0R3JvdXBBY3RpdmF0aW9uKEdyb3VwS2V5IGdyb3VwS2V5LCBib29sZWFuIGFjdGl2YXRpb24pIHsKKyAgICBMb2dVdGlsLmQoCisgICAgICAgICIlcyBzZXRHcm91cEFjdGl2YXRpb24gJXMgJXMiLCBUQUcsIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpLCBncm91cEtleS5nZXRPd25lclBhY2thZ2UoKSk7CisgICAgcmV0dXJuIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIGluaXQoKSwKKyAgICAgICAgdm9pZEFyZyAtPiBmaWxlR3JvdXBNYW5hZ2VyLnNldEdyb3VwQWN0aXZhdGlvbihncm91cEtleSwgYWN0aXZhdGlvbiksCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIFRyaWVzIHRvIGRvd25sb2FkIGFsbCBwZW5kaW5nIGZpbGUgZ3JvdXBzLCB3aGljaCBjb250YWlucyBhdCBsZWFzdCBvbmUgZmlsZSB0aGF0IGlzbid0IHlldAorICAgKiBkb3dubG9hZGVkLgorICAgKgorICAgKiBAcGFyYW0gb25XaWZpIHdoZXRoZXIgdGhlIGRldmljZSBpcyBvbiB3aWZpIGF0IHRoZSBtb21lbnQuCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEFsbFBlbmRpbmdHcm91cHMoCisgICAgICBib29sZWFuIG9uV2lmaSwgQXN5bmNGdW5jdGlvbjxEYXRhRmlsZUdyb3VwSW50ZXJuYWwsIEJvb2xlYW4+IGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvcikgeworICAgIExvZ1V0aWwuZCgiJXMgZG93bmxvYWRBbGxQZW5kaW5nR3JvdXBzIG9uIHdpZmkgPSAlcyIsIFRBRywgb25XaWZpKTsKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgaW5pdCgpLAorICAgICAgICB2b2lkQXJnIC0+IHsKKyAgICAgICAgICBpZiAoZmxhZ3MubWRkRW5hYmxlRG93bmxvYWRQZW5kaW5nR3JvdXBzKCkpIHsKKyAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAgICAgICAgIHJldHVybiBmaWxlR3JvdXBNYW5hZ2VyLnNjaGVkdWxlQWxsUGVuZGluZ0dyb3Vwc0ZvckRvd25sb2FkKAorICAgICAgICAgICAgICAgIG9uV2lmaSwgY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKioKKyAgICogVHJpZXMgdG8gdmVyaWZ5IGFsbCBwZW5kaW5nIGZpbGUgZ3JvdXBzLCB3aGljaCBjb250YWlucyBhdCBsZWFzdCBvbmUgZmlsZSB0aGF0IGlzbid0IHlldAorICAgKiBkb3dubG9hZGVkLgorICAgKi8KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gdmVyaWZ5QWxsUGVuZGluZ0dyb3VwcygKKyAgICAgIEFzeW5jRnVuY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsLCBCb29sZWFuPiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IpIHsKKyAgICBMb2dVdGlsLmQoIiVzIHZlcmlmeUFsbFBlbmRpbmdHcm91cHMiLCBUQUcpOworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBpbml0KCksCisgICAgICAgIHZvaWRBcmcgLT4geworICAgICAgICAgIGlmIChmbGFncy5tZGRFbmFibGVWZXJpZnlQZW5kaW5nR3JvdXBzKCkpIHsKKyAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAgICAgICAgIHJldHVybiBmaWxlR3JvdXBNYW5hZ2VyLnZlcmlmeUFsbFBlbmRpbmdHcm91cHNEb3dubG9hZGVkKGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvcik7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIFBlcmZvcm1zIHBlcmlvZGljIG1haW50ZW5hbmNlLiBUaGlzIGluY2x1ZGVzOgorICAgKgorICAgKiA8b2w+CisgICAqICAgPGxpPkNoZWNrIGlmIGFueSBvZiB0aGUgcGVuZGluZyBncm91cHMgd2VyZSBkb3dubG9hZGVkLgorICAgKiAgIDxsaT5HYXJiYWdlIGNvbGxlY3QgYWxsIG9sZCBkYXRhIG1kZCBoYXMuCisgICAqIDwvb2w+CisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBtYWludGVuYW5jZSgpIHsKKyAgICBMb2dVdGlsLmQoIiVzIFJ1bm5pbmcgbWFpbnRlbmFuY2UiLCBUQUcpOworCisgICAgcmV0dXJuIEZsdWVudEZ1dHVyZS5mcm9tKGluaXQoKSkKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKHZvaWRBcmcgLT4gZ2V0QW5kUmVzZXREYXlzU2luY2VMYXN0TWFpbnRlbmFuY2UoKSwgZGlyZWN0RXhlY3V0b3IoKSkKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgZGF5c1NpbmNlTGFzdExvZyAtPiB7CisgICAgICAgICAgICAgIExpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4gbWFpbnRlbmFuY2VGdXR1cmVzID0gbmV3IEFycmF5TGlzdDw+KCk7CisKKyAgICAgICAgICAgICAgLy8gSXQncyBwb3NzaWJsZSB0aGF0IHdlIG1pc3NlZCB0aGUgZmxhZyBjaGFuZ2Ugbm90aWZpY2F0aW9uIGZvciBtZGQgcmVzZXQgYmVmb3JlLgorICAgICAgICAgICAgICAvLyBDaGVjayBub3cgdG8gYmUgc3VyZS4KKyAgICAgICAgICAgICAgbWFpbnRlbmFuY2VGdXR1cmVzLmFkZChjaGVja1Jlc2V0VHJpZ2dlcigpKTsKKworICAgICAgICAgICAgICBpZiAoZmxhZ3MubG9nRmlsZUdyb3Vwc1dpdGhGaWxlc01pc3NpbmcoKSkgeworICAgICAgICAgICAgICAgIG1haW50ZW5hbmNlRnV0dXJlcy5hZGQoZmlsZUdyb3VwTWFuYWdlci5sb2dBbmREZWxldGVGb3JNaXNzaW5nU2hhcmVkRmlsZXMoKSk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGdyb3VwcyBiZWxvbmdpbmcgdG8gYXBwcyB0aGF0IHdlcmUgdW5pbnN0YWxsZWQuCisgICAgICAgICAgICAgIGlmIChmbGFncy5tZGREZWxldGVVbmluc3RhbGxlZEFwcHMoKSkgeworICAgICAgICAgICAgICAgIG1haW50ZW5hbmNlRnV0dXJlcy5hZGQoZmlsZUdyb3VwTWFuYWdlci5kZWxldGVVbmluc3RhbGxlZEFwcEdyb3VwcygpKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgZ3JvdXBzIGJlbG9uZ2luZyB0byBhY2NvdW50cyB0aGF0IHdlcmUgcmVtb3ZlZC4KKyAgICAgICAgICAgICAgaWYgKGZsYWdzLm1kZERlbGV0ZUdyb3Vwc1JlbW92ZWRBY2NvdW50cygpKSB7CisgICAgICAgICAgICAgICAgbWFpbnRlbmFuY2VGdXR1cmVzLmFkZChmaWxlR3JvdXBNYW5hZ2VyLmRlbGV0ZVJlbW92ZWRBY2NvdW50R3JvdXBzKCkpOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgaWYgKGZsYWdzLmVuYWJsZUlzb2xhdGVkU3RydWN0dXJlVmVyaWZpY2F0aW9uKCkpIHsKKyAgICAgICAgICAgICAgICBtYWludGVuYW5jZUZ1dHVyZXMuYWRkKGZpbGVHcm91cE1hbmFnZXIudmVyaWZ5QW5kQXR0ZW1wdFRvUmVwYWlySXNvbGF0ZWRGaWxlcygpKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIGlmIChmbGFncy5tZGRFbmFibGVHYXJiYWdlQ29sbGVjdGlvbigpKSB7CisgICAgICAgICAgICAgICAgbWFpbnRlbmFuY2VGdXR1cmVzLmFkZChleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkpOworICAgICAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIC8vIExvZyBkYWlseSBmaWxlIGdyb3VwIHN0YXRzLgorICAgICAgICAgICAgICBtYWludGVuYW5jZUZ1dHVyZXMuYWRkKGZpbGVHcm91cFN0YXRzTG9nZ2VyLmxvZyhkYXlzU2luY2VMYXN0TG9nKSk7CisKKyAgICAgICAgICAgICAgLy8gTG9nIHN0b3JhZ2Ugc3RhdHMuCisgICAgICAgICAgICAgIG1haW50ZW5hbmNlRnV0dXJlcy5hZGQoc3RvcmFnZUxvZ2dlci5sb2dTdG9yYWdlU3RhdHMoZGF5c1NpbmNlTGFzdExvZykpOworCisgICAgICAgICAgICAgIC8vIExvZyBuZXR3b3JrIHVzYWdlIHN0YXRzLgorICAgICAgICAgICAgICBtYWludGVuYW5jZUZ1dHVyZXMuYWRkKG5ldHdvcmtMb2dnZXIubG9nKCkpOworCisgICAgICAgICAgICAgIC8vIENsZWFyIGNoZWNrUGhlbm90eXBlRnJlc2huZXNzIHNldHRpbmdzIGZyb20gU2hhcmVkIFByZWZzIGFzIHRoZSBmZWF0dXJlIHdhcworICAgICAgICAgICAgICAvLyBkZWxldGVkLgorICAgICAgICAgICAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgICAgICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoCisgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgTUREX01BTkFHRVJfTUVUQURBVEEsIGluc3RhbmNlSWQpOworICAgICAgICAgICAgICBwcmVmcy5lZGl0KCkucmVtb3ZlKE1ERF9QSF9DT05GSUdfVkVSU0lPTikucmVtb3ZlKE1ERF9QSF9DT05GSUdfVkVSU0lPTl9UUykuY29tbWl0KCk7CisKKyAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMud2hlbkFsbENvbXBsZXRlKG1haW50ZW5hbmNlRnV0dXJlcykKKyAgICAgICAgICAgICAgICAgIC5jYWxsKCgpIC0+IG51bGwsIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqIER1bXBzIHRoZSBjdXJyZW50IGludGVybmFsIHN0YXRlIG9mIHRoZSBNREQgbWFuYWdlci4gKi8KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZHVtcChmaW5hbCBQcmludFdyaXRlciB3cml0ZXIpIHsKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgaW5pdCgpLAorICAgICAgICB2b2lkQXJnIC0+CisgICAgICAgICAgICBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIuZHVtcCh3cml0ZXIpLAorICAgICAgICAgICAgICAgIHZvaWRQYXJhbSAtPiBzaGFyZWRGaWxlTWFuYWdlci5kdW1wKHdyaXRlciksCisgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciksCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqIENoZWNrcyB0byBzZWUgaWYgYSBmbGFnIGNoYW5nZSByZXF1aXJlcyBNREQgdG8gY2xlYXIgaXRzIGRhdGEuICovCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNoZWNrUmVzZXRUcmlnZ2VyKCkgeworICAgIExvZ1V0aWwuZCgiJXMgY2hlY2tSZXNldFRyaWdnZXIiLCBUQUcpOworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBpbml0KCksCisgICAgICAgIHZvaWRBcmcgLT4geworICAgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzIHByZWZzID0KKyAgICAgICAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKGNvbnRleHQsIE1ERF9NQU5BR0VSX01FVEFEQVRBLCBpbnN0YW5jZUlkKTsKKyAgICAgICAgICBpZiAoIXByZWZzLmNvbnRhaW5zKFJFU0VUX1RSSUdHRVIpKSB7CisgICAgICAgICAgICBwcmVmcy5lZGl0KCkucHV0SW50KFJFU0VUX1RSSUdHRVIsIGZsYWdzLm1kZFJlc2V0VHJpZ2dlcigpKS5jb21taXQoKTsKKyAgICAgICAgICB9CisgICAgICAgICAgaW50IHNhdmVkUmVzZXRWYWx1ZSA9IHByZWZzLmdldEludChSRVNFVF9UUklHR0VSLCAwKTsKKyAgICAgICAgICBpbnQgY3VycmVudFJlc2V0VmFsdWUgPSBmbGFncy5tZGRSZXNldFRyaWdnZXIoKTsKKyAgICAgICAgICAvLyBJZiB0aGUgZmxhZyBoYXMgY2hhbmdlZCBzaW5jZSB3ZSBsYXN0IHNhdyBpdCwgc2F2ZSB0aGUgbmV3IHZhbHVlIGluIHNoYXJlZCBwcmVmcyBhbmQKKyAgICAgICAgICAvLyBjbGVhci4KKyAgICAgICAgICBpZiAoc2F2ZWRSZXNldFZhbHVlIDwgY3VycmVudFJlc2V0VmFsdWUpIHsKKyAgICAgICAgICAgIHByZWZzLmVkaXQoKS5wdXRJbnQoUkVTRVRfVFJJR0dFUiwgY3VycmVudFJlc2V0VmFsdWUpLmNvbW1pdCgpOworICAgICAgICAgICAgTG9nVXRpbC5kKCIlcyBSZWNlaXZlZCByZXNldCB0cmlnZ2VyLiBDbGVhcmluZyBhbGwgTWRkIGRhdGEuIiwgVEFHKTsKKyAgICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAgICAgICAgIHJldHVybiBjbGVhckFsbEZpbGVzQW5kTWV0YWRhdGEoKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKiogQ2xlYXJzIHRoZSBpbnRlcm5hbCBzdGF0ZSBvZiBNREQgYW5kIGRlbGV0ZXMgYWxsIGRvd25sb2FkZWQgZmlsZXMuICovCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJBcHBseVNoYXJlZFByZWYiKQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjbGVhcigpIHsKKyAgICBMb2dVdGlsLmQoIiVzIENsZWFyaW5nIE1ERCBpbnRlcm5hbCBzdG9yYWdlIiwgVEFHKTsKKworICAgIC8vIERlbGV0ZSBhbGwgb2YgdGhlIGJvb2trZWVwaW5nIGZpbGVzIHVzZWQgYnkgTUREIE1hbmFnZXIncyBpbnRlcm5hbCBjbGFzc2VzLgorICAgIC8vIENsZWFyIGRvd25sb2FkU3RhZ2VNYW5hZ2VyIGZpcnN0IHNpbmNlIGl0IG5lZWRzIHRvIGtub3cgd2hpY2ggYnVpbGRzIHRvIGRlbGV0ZSBmcm9tCisgICAgLy8gU2hhcmVkRmlsZXNNZXRhZGF0YS4KKyAgICByZXR1cm4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKGRvd25sb2FkU3RhZ2VNYW5hZ2VyLmNsZWFyQWxsKCkpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYyh2b2lkQXJnIC0+IGNsZWFyQWxsRmlsZXNBbmRNZXRhZGF0YSgpLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICB2b2lkQXJnIC0+IHsKKyAgICAgICAgICAgICAgLy8gQ2xlYXIgYWxsIG1pZ3JhdGlvbiBzdGF0dXMuCisgICAgICAgICAgICAgIE1pZ3JhdGlvbnMuY2xlYXIoY29udGV4dCk7CisgICAgICAgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcyhjb250ZXh0LCBNRERfTUFOQUdFUl9NRVRBREFUQSwgaW5zdGFuY2VJZCkKKyAgICAgICAgICAgICAgICAgIC5lZGl0KCkKKyAgICAgICAgICAgICAgICAgIC5jbGVhcigpCisgICAgICAgICAgICAgICAgICAuY29tbWl0KCk7CisKKyAgICAgICAgICAgICAgaXNJbml0aWFsaXplZCA9IGZhbHNlOworICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYyh2b2lkQXJnIC0+IGxvZ2dpbmdTdGF0ZVN0b3JlLmNsZWFyKCksIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgQFZpc2libGVGb3JUZXN0aW5nCisgIHB1YmxpYyBzdGF0aWMgdm9pZCByZXNldEZvclRlc3QoKSB7CisgICAgaXNJbml0aWFsaXplZCA9IGZhbHNlOworICB9CisKKyAgLyoqIENsZWFyIGR1cmluZyBNREQgaW5pdCAqLworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gY2xlYXJGb3JJbml0KCkgeworICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgLy8gQ2xlYXIgb25seSwgbm8gbmVlZCB0byBjYW5jZWwgZG93bmxvYWQuCisgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyLmNsZWFyKCksCisgICAgICAgIHZvaWRBcmcwIC0+CisgICAgICAgICAgICAvLyBUaGUgbWV0YWRhdGEgZmlsZXMgc2hvdWxkIGJlIGNsZWFyZWQgYWZ0ZXIgdGhlIGNsYXNzZXMgaGF2ZSBiZWVuIGNsZWFyZWQuCisgICAgICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLmNsZWFyKCksCisgICAgICAgICAgICAgICAgdm9pZEFyZzEgLT4gZmlsZUdyb3Vwc01ldGFkYXRhLmNsZWFyKCksCisgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciksCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyogQ2xlYXIgYWxsIG1ldGFkYXRhIGFuZCBmaWxlcywgYWxzbyBjYW5jZWwgcGVuZGluZyBkb3dubG9hZC4gKi8KKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNsZWFyQWxsRmlsZXNBbmRNZXRhZGF0YSgpIHsKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgLy8gTmVlZCB0byBjYW5jZWwgZG93bmxvYWQgYWZ0ZXIgTUREIGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQuCisgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyLmNhbmNlbERvd25sb2FkQW5kQ2xlYXIoKSwKKyAgICAgICAgdm9pZEFyZzEgLT4KKyAgICAgICAgICAgIC8vIFRoZSBtZXRhZGF0YSBmaWxlcyBzaG91bGQgYmUgY2xlYXJlZCBhZnRlciB0aGUgY2xhc3NlcyBoYXZlIGJlZW4gY2xlYXJlZC4KKyAgICAgICAgICAgIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS5jbGVhcigpLAorICAgICAgICAgICAgICAgIHZvaWRBcmcyIC0+IGZpbGVHcm91cHNNZXRhZGF0YS5jbGVhcigpLAorICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpLAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIC8vIENvbnZlbmllbmNlIG1ldGhvZCB0byBwb3B1bGF0ZSBjaGVja3N1bXMgZm9yIGEgRGF0YUZpbGVHcm91cAorICBwcml2YXRlIHN0YXRpYyBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgbWF5UG9wdWxhdGVDaGVja3N1bShEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCkgeworICAgIExpc3Q8RGF0YUZpbGU+IGRhdGFGaWxlTGlzdCA9IGRhdGFGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKTsKKyAgICBJbW11dGFibGVMaXN0PERhdGFGaWxlPiB1cGRhdGVkRGF0YUZpbGVMaXN0ID0gbWF5UG9wdWxhdGVDaGVja3N1bShkYXRhRmlsZUxpc3QpOworICAgIHJldHVybiBkYXRhRmlsZUdyb3VwLnRvQnVpbGRlcigpLmNsZWFyRmlsZSgpLmFkZEFsbEZpbGUodXBkYXRlZERhdGFGaWxlTGlzdCkuYnVpbGQoKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIEltbXV0YWJsZUxpc3Q8RGF0YUZpbGU+IG1heVBvcHVsYXRlQ2hlY2tzdW0oTGlzdDxEYXRhRmlsZT4gZGF0YUZpbGVMaXN0KSB7CisgICAgYm9vbGVhbiBoYXNDaGVja3N1bVR5cGVOb25lID0gZmFsc2U7CisKKyAgICBmb3IgKERhdGFGaWxlIGRhdGFGaWxlIDogZGF0YUZpbGVMaXN0KSB7CisgICAgICBpZiAoZGF0YUZpbGUuZ2V0Q2hlY2tzdW1UeXBlKCkgPT0gQ2hlY2tzdW1UeXBlLk5PTkUpIHsKKyAgICAgICAgaGFzQ2hlY2tzdW1UeXBlTm9uZSA9IHRydWU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKworICAgIGlmICghaGFzQ2hlY2tzdW1UeXBlTm9uZSkgeworICAgICAgcmV0dXJuIEltbXV0YWJsZUxpc3QuY29weU9mKGRhdGFGaWxlTGlzdCk7CisgICAgfQorCisgICAgLy8gQ2hlY2sgaWYgYW55IGZpbGUgZG9lcyBub3QgaGF2ZSBjaGVja3N1bSwgcmVwbGFjZSB0aGUgY2hlY2tzdW0gd2l0aCB0aGUgY2hlY2tzdW0gb2YKKyAgICAvLyBkb3dubG9hZCB1cmwuCisgICAgSW1tdXRhYmxlTGlzdC5CdWlsZGVyPERhdGFGaWxlPiBkYXRhRmlsZUxpc3RCdWlsZGVyID0KKyAgICAgICAgSW1tdXRhYmxlTGlzdC5idWlsZGVyV2l0aEV4cGVjdGVkU2l6ZShkYXRhRmlsZUxpc3Quc2l6ZSgpKTsKKyAgICBmb3IgKERhdGFGaWxlIGRhdGFGaWxlIDogZGF0YUZpbGVMaXN0KSB7CisgICAgICBzd2l0Y2ggKGRhdGFGaWxlLmdldENoZWNrc3VtVHlwZSgpKSB7CisgICAgICAgICAgLy8gRGVmYXVsdCBzdGFuZHMgZm9yIFNIQTEuCisgICAgICAgIGNhc2UgREVGQVVMVDoKKyAgICAgICAgICBkYXRhRmlsZUxpc3RCdWlsZGVyLmFkZChkYXRhRmlsZSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgTk9ORToKKyAgICAgICAgICAvLyBTaW5jZSBpbnRlcm5hbGx5IHdlIHVzZSBjaGVja3N1bSBhcyBhIGtleSwgaXQgY2FuJ3QgYmUgZW1wdHkuIFdlIHdpbGwgZ2VuZXJhdGUgdGhlCisgICAgICAgICAgLy8gY2hlY2tzdW0gdXNpbmcgdGhlIHVybFRvRG93bmxvYWQgaWYgaXQncyBub3Qgc2V0LgorICAgICAgICAgIERhdGFGaWxlLkJ1aWxkZXIgZGF0YUZpbGVCdWlsZGVyID0gZGF0YUZpbGUudG9CdWlsZGVyKCk7CisgICAgICAgICAgU3RyaW5nIGNoZWNrc3VtID0gRmlsZVZhbGlkYXRvci5jb21wdXRlU2hhMURpZ2VzdChkYXRhRmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkpOworICAgICAgICAgIC8vIFdoZW4gYSBkYXRhIGZpbGUgaGFzIHppcCB0cmFuc2Zvcm1zLCBkb3dubG9hZGVkIGZpbGUgY2hlY2tzdW0gaXMgdXNlZCBmb3IgaWRlbnRpZnlpbmcKKyAgICAgICAgICAvLyB0aGUgZGF0YSBmaWxlOyBvdGhlcndpc2UsIGNoZWNrc3VtIGlzIHVzZWQuCisgICAgICAgICAgaWYgKEZpbGVHcm91cFV0aWwuaGFzWmlwRG93bmxvYWRUcmFuc2Zvcm0oZGF0YUZpbGUpKSB7CisgICAgICAgICAgICBkYXRhRmlsZUJ1aWxkZXIuc2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bShjaGVja3N1bSk7CisgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGRhdGFGaWxlQnVpbGRlci5zZXRDaGVja3N1bShjaGVja3N1bSk7CisgICAgICAgICAgfQorICAgICAgICAgIExvZ1V0aWwuZCgKKyAgICAgICAgICAgICAgIkZpbGVJZCAlcyBkb2VzIG5vdCBoYXZlIGNoZWNrc3VtLiBHZW5lcmF0ZWQgY2hlY2tzdW0gZnJvbSB1cmwgJXMiLAorICAgICAgICAgICAgICBkYXRhRmlsZUJ1aWxkZXIuZ2V0RmlsZUlkKCksIGRhdGFGaWxlQnVpbGRlci5nZXRDaGVja3N1bSgpKTsKKworICAgICAgICAgIGRhdGFGaWxlTGlzdEJ1aWxkZXIuYWRkKGRhdGFGaWxlQnVpbGRlci5idWlsZCgpKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgICAvLyBjb250aW51ZSBiZWxvdy4KKyAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gZGF0YUZpbGVMaXN0QnVpbGRlci5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIEdldHMgYW5kIHJlc2V0cyB0aGUgbnVtYmVyIG9mIGRheXMgc2luY2UgbGFzdCBtYWludGVuYW5jZSBmcm9tIHtAbGluayBsb2dnaW5nU3RhdGVTdG9yZX0uIElmCisgICAqIGxvZ2dpbmdTdGF0ZVN0b3JlIGZhaWxzIHRvIHByb3ZpZGUgYSB2YWx1ZSAoaWYgaXQgdGhyb3dzIGFuIGV4Y2VwdGlvbiBvciB0aGUgdmFsdWUgd2FzIG5vdCBzZXQpCisgICAqIHRoaXMgaGFuZGxlcyB0aGF0IGJ5IHJldHVybmluZyAtMS4gY2xlYXIKKyAgICoKKyAgICogPHA+SWYge0BsaW5rIEZsYWdzLmVuYWJsZURheXNTaW5jZUxhc3RNYWludGVuYW5jZVRyYWNraW5nfSBpcyBub3QgZW5hYmxlZCwgdGhpcyByZXR1cm5zIC0xLgorICAgKi8KKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPEludGVnZXI+IGdldEFuZFJlc2V0RGF5c1NpbmNlTGFzdE1haW50ZW5hbmNlKCkgeworICAgIGlmICghZmxhZ3MuZW5hYmxlRGF5c1NpbmNlTGFzdE1haW50ZW5hbmNlVHJhY2tpbmcoKSkgeworICAgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShERUZBVUxUX0RBWVNfU0lOQ0VfTEFTVF9NQUlOVEVOQU5DRSk7CisgICAgfQorCisgICAgcmV0dXJuIEZsdWVudEZ1dHVyZS5mcm9tKGxvZ2dpbmdTdGF0ZVN0b3JlLmdldEFuZFJlc2V0RGF5c1NpbmNlTGFzdE1haW50ZW5hbmNlKCkpCisgICAgICAgIC5jYXRjaGluZygKKyAgICAgICAgICAgIElPRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgZXhjZXB0aW9uIC0+IHsKKyAgICAgICAgICAgICAgTG9nVXRpbC5kKGV4Y2VwdGlvbiwgIkZhaWxlZCB0byB1cGRhdGUgZGF5cyBzaW5jZSBsYXN0IG1haW50ZW5hbmNlIik7CisgICAgICAgICAgICAgIC8vIElmIHdlIGZhaWxlZCB0byByZWFkIG9yIHVwZGF0ZSB0aGUgZGF5cyBzaW5jZSBsYXN0IG1haW50ZW5hbmNlLCBqdXN0IHNldCB0aGUgdmFsdWUKKyAgICAgICAgICAgICAgLy8gdG8gLTEuCisgICAgICAgICAgICAgIHJldHVybiBPcHRpb25hbC5vZihERUZBVUxUX0RBWVNfU0lOQ0VfTEFTVF9NQUlOVEVOQU5DRSk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgZGlyZWN0RXhlY3V0b3IoKSkKKyAgICAgICAgLnRyYW5zZm9ybSgKKyAgICAgICAgICAgIGRheXNTaW5jZUxhc3RNYWludGVuYW5jZU9wdGlvbmFsIC0+IHsKKyAgICAgICAgICAgICAgaWYgKCFkYXlzU2luY2VMYXN0TWFpbnRlbmFuY2VPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBERUZBVUxUX0RBWVNfU0lOQ0VfTEFTVF9NQUlOVEVOQU5DRTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBJbnRlZ2VyIGRheXNTaW5jZUxhc3RNYWludGVuYW5jZSA9IGRheXNTaW5jZUxhc3RNYWludGVuYW5jZU9wdGlvbmFsLmdldCgpOworICAgICAgICAgICAgICBpZiAoZGF5c1NpbmNlTGFzdE1haW50ZW5hbmNlIDwgMCkgeworICAgICAgICAgICAgICAgIHJldHVybiBERUZBVUxUX0RBWVNfU0lOQ0VfTEFTVF9NQUlOVEVOQU5DRTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAvLyBUT0RPKGIvMTkxMDQyOTAwKTogc2hvdWxkIHdlIGFkZCBhbiB1cHBlciBib3VuZCBoZXJlPworICAgICAgICAgICAgICByZXR1cm4gZGF5c1NpbmNlTGFzdE1haW50ZW5hbmNlOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIGRpcmVjdEV4ZWN1dG9yKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL1NoYXJlZEZpbGVNYW5hZ2VyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL1NoYXJlZEZpbGVNYW5hZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzA4MDRiNwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvU2hhcmVkRmlsZU1hbmFnZXIuamF2YQpAQCAtMCwwICsxLDEwMzYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmU7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuU2hhcmVkUHJlZmVyZW5jZXM7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQuVkVSU0lPTjsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkLlZFUlNJT05fQ09ERVM7CitpbXBvcnQgYW5kcm9pZHguYW5ub3RhdGlvbi5WaXNpYmxlRm9yVGVzdGluZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbi5Eb3dubG9hZFJlc3VsdENvZGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmlsZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GbGFnczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5TaWxlbnRGZWVkYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5hbm5vdGF0aW9ucy5JbnN0YW5jZUlkOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRlbHRhLkRlbHRhRGVjb2RlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NaWdyYXRpb25zLkZpbGVLZXlWZXJzaW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmFubm90YXRpb25zLlNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZG93bmxvYWRlci5EZWx0YUZpbGVEb3dubG9hZGVyQ2FsbGJhY2tJbXBsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmRvd25sb2FkZXIuRG93bmxvYWRlckNhbGxiYWNrSW1wbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kb3dubG9hZGVyLkZpbGVOYW1lVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kb3dubG9hZGVyLkZpbGVWYWxpZGF0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZG93bmxvYWRlci5NZGRGaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kb3dubG9hZGVyLk1kZEZpbGVEb3dubG9hZGVyLkRvd25sb2FkZXJDYWxsYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkV2ZW50TG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLkRpcmVjdG9yeVV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5TaGFyZWRQcmVmZXJlbmNlc1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubW9uaXRvci5Eb3dubG9hZFByb2dyZXNzTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GbHVlbnRGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5lcnJvcnByb25lLmFubm90YXRpb25zLkNoZWNrUmV0dXJuVmFsdWU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbC5BbGxvd2VkUmVhZGVyczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRlbHRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRlbHRhRmlsZS5EaWZmRGVjb2RlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkV4dHJhSHR0cEhlYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkZpbGVTdGF0dXM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLk5ld0ZpbGVLZXk7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5TaGFyZWRGaWxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CitpbXBvcnQgamF2YXguaW5qZWN0LkluamVjdDsKK2ltcG9ydCBvcmcuY2hlY2tlcmZyYW1ld29yay5jaGVja2VyLm51bGxuZXNzLmNvbXBhdHF1YWwuTnVsbGFibGVUeXBlOworCisvKioKKyAqIE1hbmFnZXMgdGhlIGxpZmUgY3ljbGUgb2YgZmlsZXMgdXNlZCBieSBNREQuIEZvciBlYWNoIGZpbGUgZ3JvdXAgaW4gTURELCB0aGUgZmlsZSBncm91cCB3aWxsCisgKiBzdWJzY3JpYmUgZm9yIHRoZSBmaWxlcyB0aGF0IGl0IG5lZWRzLiBUaGUgU2hhcmVkRmlsZU1hbmFnZXIgd2lsbCBtYWludGFpbiBhIHJlZmVyZW5jZSBjb3VudCB0bworICogZW5zdXJlIHRoYXQgaXQgb25seSByZXRhaW5zIGZpbGVzIHRoYXQgYXJlIGJlaW5nIHVzZWQgYnkgTUREIGFuZCB0aGF0IG11bHRpcGxlIGZpbGUgZ3JvdXBzIHdpbGwKKyAqIHNoYXJlIGEgc2luZ2xlIGNvbW1vbiBmaWxlLgorICoKKyAqIDxwPldoZW5ldmVyIE1ERCByZWNlaXZlcyBhIG5ldyBmaWxlZ3JvdXAsIGl0IHdpbGwgY2FsbCB7QGxpbmsgU2hhcmVkRmlsZU1hbmFnZXIjcmVzZXJ2ZUZpbGVFbnRyeX0KKyAqIGZvciBlYWNoIGZpbGUgd2l0aGluIHRoZSBncm91cC4KKyAqCisgKiA8cD5XaGVuIE1ERCBkaXNjYXJkcyBhIGZpbGUgZ3JvdXAgKGJlY2F1c2UgYSBuZXcgb25lIGhhcyBiZWVuIHJlY2VpdmVkLCBkb3dubG9hZGVkKSwgaXQgd2lsbCBjYWxsCisgKiB7QGxpbmsgU2hhcmVkRmlsZU1hbmFnZXIjcmVtb3ZlRmlsZUVudHJ5fSBmb3IgZWFjaCBmaWxlIHdpdGhpbiB0aGUgZ3JvdXAuCisgKgorICogPHA+Tm90ZTogU2hhcmVkRmlsZU1hbmFnZXIgaXMgY29uc2lkZXJlZCB0aHJlYWQtY29tcGF0aWJsZS4gQ2FsbHMgdG8gbWV0aG9kcyB0aGF0IG1vZGlmeSB0aGUKKyAqIHN0YXRlIG9mIFNoYXJlZEZpbGVNYW5hZ2VyIHtAbGluayBTaGFyZWRGaWxlTWFuYWdlciNyZXNlcnZlRmlsZUVudHJ5fSwge0BsaW5rCisgKiBTaGFyZWRGaWxlTWFuYWdlciNzdGFydERvd25sb2FkfSwge0BsaW5rIFNoYXJlZEZpbGVNYW5hZ2VyI2dldEZpbGVTdGF0dXN9LCBhbmQge0BsaW5rCisgKiBTaGFyZWRGaWxlTWFuYWdlciNyZW1vdmVGaWxlRW50cnl9IHJlcXVpcmUgZXhjbHVzaXZlIGFjY2Vzcy4KKyAqLworQENoZWNrUmV0dXJuVmFsdWUKK3B1YmxpYyBjbGFzcyBTaGFyZWRGaWxlTWFuYWdlciB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJTaGFyZWRGaWxlTWFuYWdlciI7CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUREX1NIQVJFRF9GSUxFX01BTkFHRVJfTUVUQURBVEEgPQorICAgICAgImdtc19pY2luZ19tZGRfc2hhcmVkX2ZpbGVfbWFuYWdlcl9tZXRhZGF0YSI7CisKKyAgQFZpc2libGVGb3JUZXN0aW5nIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJFRlNfS0VZX05FWFRfRklMRV9OQU1FID0gIm5leHRfZmlsZV9uYW1lX3YyIjsKKyAgQFZpc2libGVGb3JUZXN0aW5nIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9OQU1FX1BSRUZJWCA9ICJkYXRhZG93bmxvYWRmaWxlXyI7CisKKyAgQFZpc2libGVGb3JUZXN0aW5nCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJFRlNfS0VZX01JR1JBVEVEX1RPX05FV19GSUxFX0tFWSA9ICJtaWdyYXRlZF90b19uZXdfZmlsZV9rZXkiOworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIGZpbmFsIFNpbGVudEZlZWRiYWNrIHNpbGVudEZlZWRiYWNrOworICBwcml2YXRlIGZpbmFsIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YTsKKyAgcHJpdmF0ZSBmaW5hbCBNZGRGaWxlRG93bmxvYWRlciBmaWxlRG93bmxvYWRlcjsKKyAgcHJpdmF0ZSBmaW5hbCBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIGZpbmFsIE9wdGlvbmFsPERlbHRhRGVjb2Rlcj4gZGVsdGFEZWNvZGVyT3B0aW9uYWw7CisgIHByaXZhdGUgZmluYWwgT3B0aW9uYWw8RG93bmxvYWRQcm9ncmVzc01vbml0b3I+IGRvd25sb2FkTW9uaXRvck9wdGlvbmFsOworICBwcml2YXRlIGZpbmFsIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyOworICBwcml2YXRlIGZpbmFsIEZsYWdzIGZsYWdzOworICBwcml2YXRlIGZpbmFsIEZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGE7CisgIHByaXZhdGUgZmluYWwgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkOworICBwcml2YXRlIGZpbmFsIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CisKKyAgQEluamVjdAorICBwdWJsaWMgU2hhcmVkRmlsZU1hbmFnZXIoCisgICAgICBAQXBwbGljYXRpb25Db250ZXh0IENvbnRleHQgY29udGV4dCwKKyAgICAgIFNpbGVudEZlZWRiYWNrIHNpbGVudEZlZWRiYWNrLAorICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YSBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZSwKKyAgICAgIE1kZEZpbGVEb3dubG9hZGVyIGZpbGVEb3dubG9hZGVyLAorICAgICAgT3B0aW9uYWw8RGVsdGFEZWNvZGVyPiBkZWx0YURlY29kZXJPcHRpb25hbCwKKyAgICAgIE9wdGlvbmFsPERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yPiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCwKKyAgICAgIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyLAorICAgICAgRmxhZ3MgZmxhZ3MsCisgICAgICBGaWxlR3JvdXBzTWV0YWRhdGEgZmlsZUdyb3Vwc01ldGFkYXRhLAorICAgICAgQEluc3RhbmNlSWQgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkLAorICAgICAgQFNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikgeworICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CisgICAgdGhpcy5zaWxlbnRGZWVkYmFjayA9IHNpbGVudEZlZWRiYWNrOworICAgIHRoaXMuc2hhcmVkRmlsZXNNZXRhZGF0YSA9IHNoYXJlZEZpbGVzTWV0YWRhdGE7CisgICAgdGhpcy5maWxlU3RvcmFnZSA9IGZpbGVTdG9yYWdlOworICAgIHRoaXMuZmlsZURvd25sb2FkZXIgPSBmaWxlRG93bmxvYWRlcjsKKyAgICB0aGlzLmRlbHRhRGVjb2Rlck9wdGlvbmFsID0gZGVsdGFEZWNvZGVyT3B0aW9uYWw7CisgICAgdGhpcy5kb3dubG9hZE1vbml0b3JPcHRpb25hbCA9IGRvd25sb2FkTW9uaXRvck9wdGlvbmFsOworICAgIHRoaXMuZXZlbnRMb2dnZXIgPSBldmVudExvZ2dlcjsKKyAgICB0aGlzLmZsYWdzID0gZmxhZ3M7CisgICAgdGhpcy5maWxlR3JvdXBzTWV0YWRhdGEgPSBmaWxlR3JvdXBzTWV0YWRhdGE7CisgICAgdGhpcy5pbnN0YW5jZUlkID0gaW5zdGFuY2VJZDsKKyAgICB0aGlzLnNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgPSBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworICB9CisKKyAgLyoqCisgICAqIE1ha2VzIGFueSBjaGFuZ2VzIHRoYXQgc2hvdWxkIGJlIG1hZGUgYmVmb3JlIGFjY2Vzc2luZyB0aGUgaW50ZXJuYWwgc3RhdGUgb2YgdGhpcyBjbGFzcy4KKyAgICoKKyAgICogPHA+T3RoZXIgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGRvIG5vdCBjYWxsIG9yIGNoZWNrIGlmIHRoaXMgbWV0aG9kIHdhcyBhbHJlYWR5IGNhbGxlZCBiZWZvcmUKKyAgICogdHJ5aW5nIHRvIGFjY2VzcyBpbnRlcm5hbCBzdGF0ZS4gSXQgaXMgZXhwZWN0ZWQgZnJvbSB0aGUgY2FsbGVyIHRvIGNhbGwgdGhpcyBiZWZvcmUgYW55dGhpbmcKKyAgICogZWxzZS4KKyAgICoKKyAgICogQHJldHVybiBmYWxzZSBpZiBpbml0IGZhaWxlZCwgc2lnbmFsbGluZyBjYWxsZXIgdG8gY2xlYXIgaW50ZXJuYWwgc3RvcmFnZS4KKyAgICovCisgIC8vIFRPRE8oYi8xMjQwNzI3NTQpOiBDaGFuZ2UgdG8gcGFja2FnZSBwcml2YXRlIG9uY2UgYWxsIGNvZGUgaXMgcmVmYWN0b3JlZC4KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gaW5pdCgpIHsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBzaGFyZWRGaWxlTWFuYWdlck1ldGFkYXRhID0KKyAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKAorICAgICAgICAgICAgY29udGV4dCwgTUREX1NIQVJFRF9GSUxFX01BTkFHRVJfTUVUQURBVEEsIGluc3RhbmNlSWQpOworCisgICAgLy8gTWlncmF0aW9ucyBjbGFzcyB3YXMgYWRkZWQgaW4gdjI0LCB3aGVyZWFzIG5ldyBmaWxlIGtleSBtaWdyYXRpb24gZG9uZSBpbiB2MjMuIElmIHdlIGFscmVhZHkKKyAgICAvLyBtaWdyYXRlZCwgY2hlY2sgYW5kIHNldCBpdCBpbiBNaWdyYXRpb25zLgorICAgIGlmIChzaGFyZWRGaWxlTWFuYWdlck1ldGFkYXRhLmNvbnRhaW5zKFBSRUZTX0tFWV9NSUdSQVRFRF9UT19ORVdfRklMRV9LRVkpKSB7CisgICAgICBpZiAoc2hhcmVkRmlsZU1hbmFnZXJNZXRhZGF0YS5nZXRCb29sZWFuKFBSRUZTX0tFWV9NSUdSQVRFRF9UT19ORVdfRklMRV9LRVksIGZhbHNlKSkgeworICAgICAgICBNaWdyYXRpb25zLnNldE1pZ3JhdGVkVG9OZXdGaWxlS2V5KGNvbnRleHQsIHRydWUpOworICAgICAgfQorICAgICAgc2hhcmVkRmlsZU1hbmFnZXJNZXRhZGF0YS5lZGl0KCkucmVtb3ZlKFBSRUZTX0tFWV9NSUdSQVRFRF9UT19ORVdfRklMRV9LRVkpLmNvbW1pdCgpOworICAgIH0KKworICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKTsKKyAgfQorCisgIC8qKgorICAgKiBBZGRzIGEgc3Vic2NyaWJlZCBmaWxlIGVudHJ5IGlmIHRoZXJlIGlzIG5vIGV4aXN0aW5nIGVudHJ5IGZvciBuZXdGaWxlS2V5LiBEb2VzIG5vdGhpbmcgaWYgc3VjaAorICAgKiBhbiBlbnRyeSBhbHJlYWR5IGV4aXN0cy4KKyAgICoKKyAgICogQHBhcmFtIG5ld0ZpbGVLZXkgLSB0aGUgZmlsZSBrZXkgZm9yIHRoZSBlbnJ5IHRoYXQgeW91IHdpc2ggdG8gcmVzZXJ2ZS4KKyAgICogQHJldHVybiAtIEZ1dHVyZSByZXNvbHZpbmcgdG8gZmFsc2UgaWYgdW5hYmxlIHRvIGNvbW1pdCB0aGUgcmVzZXJ2YXRpb24KKyAgICovCisgIC8vIFRPRE8gLSByZWZhY3RvciB0byB0aHJvdyBFeGNlcHRpb24gd2hlbiB3cml0ZSB0byBTaGFyZWRQcmVmZXJlbmNlcyBmYWlscworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiByZXNlcnZlRmlsZUVudHJ5KE5ld0ZpbGVLZXkgbmV3RmlsZUtleSkgeworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSksCisgICAgICAgIHNoYXJlZEZpbGUgLT4geworICAgICAgICAgIGlmIChzaGFyZWRGaWxlICE9IG51bGwpIHsKKyAgICAgICAgICAgIC8vIFRoZXJlJ3MgYWxyZWFkeSBhbiBlbnRyeSBmb3IgdGhpcyBmaWxlLiBOb3RoaW5nIHRvIGRvIGhlcmUuCisgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSk7CisgICAgICAgICAgfQorICAgICAgICAgIC8vIFNldCB0aGUgZmlsZSBuYW1lIGFuZCB1cGRhdGUgdGhlIG1ldGFkYXRhIGZpbGUuCisgICAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXMgc2hhcmVkRmlsZU1hbmFnZXJNZXRhZGF0YSA9CisgICAgICAgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcygKKyAgICAgICAgICAgICAgICAgIGNvbnRleHQsIE1ERF9TSEFSRURfRklMRV9NQU5BR0VSX01FVEFEQVRBLCBpbnN0YW5jZUlkKTsKKyAgICAgICAgICBsb25nIG5leHRGaWxlTmFtZSA9CisgICAgICAgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyTWV0YWRhdGEuZ2V0TG9uZygKKyAgICAgICAgICAgICAgICAgIFBSRUZTX0tFWV9ORVhUX0ZJTEVfTkFNRSwgU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgICAgICAgIGlmICghc2hhcmVkRmlsZU1hbmFnZXJNZXRhZGF0YQorICAgICAgICAgICAgICAuZWRpdCgpCisgICAgICAgICAgICAgIC5wdXRMb25nKFBSRUZTX0tFWV9ORVhUX0ZJTEVfTkFNRSwgbmV4dEZpbGVOYW1lICsgMSkKKyAgICAgICAgICAgICAgLmNvbW1pdCgpKSB7CisgICAgICAgICAgICAvLyBUT0RPKGIvMTMxMTY2OTI1KTogTUREIGR1bXAgc2hvdWxkIG5vdCB1c2UgbGl0ZSBwcm90byB0b1N0cmluZy4KKyAgICAgICAgICAgIExvZ1V0aWwuZSgiJXM6IFVuYWJsZSB0byB1cGRhdGUgZmlsZSBuYW1lICVzIiwgVEFHLCBuZXdGaWxlS2V5KTsKKyAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmYWxzZSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgU3RyaW5nIGZpbGVOYW1lID0gRklMRV9OQU1FX1BSRUZJWCArIG5leHRGaWxlTmFtZTsKKyAgICAgICAgICBzaGFyZWRGaWxlID0KKyAgICAgICAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuU1VCU0NSSUJFRCkKKyAgICAgICAgICAgICAgICAgIC5zZXRGaWxlTmFtZShmaWxlTmFtZSkKKyAgICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIHNoYXJlZEZpbGUpLAorICAgICAgICAgICAgICB3cml0ZVN1Y2Nlc3MgLT4geworICAgICAgICAgICAgICAgIGlmICghd3JpdGVTdWNjZXNzKSB7CisgICAgICAgICAgICAgICAgICAvLyBUT0RPKGIvMTMxMTY2OTI1KTogTUREIGR1bXAgc2hvdWxkIG5vdCB1c2UgbGl0ZSBwcm90byB0b1N0cmluZy4KKyAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgICAgICAgICAiJXM6IFVuYWJsZSB0byB3cml0ZSBiYWNrIHN1YnNjcmlwdGlvbiBmb3IgZmlsZSBlbnRyeSB3aXRoICVzIiwKKyAgICAgICAgICAgICAgICAgICAgICBUQUcsIG5ld0ZpbGVLZXkpOworICAgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpOworICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKioKKyAgICogU3RhcnQgaW1wb3J0aW5nIGEgZ2l2ZW4gZmlsZSBzb3VyY2UgaWYgdGhlIGZpbGUgaGFzIG5vdCB5ZXQgYmVlbiBkb3dubG9hZGVkL2ltcG9ydGVkLgorICAgKgorICAgKiA8cD5UaGlzIG1ldGhvZCBleHBlY3RzIHtAY29kZSBkYXRhRmlsZX0gdG8gaGF2ZSBhbiAiaW5saW5lZmlsZToiIHNjaGVtZSB1cmwuIEEKKyAgICogRG93bmxvYWRFeGNlcHRpb24gd2lsbCBiZSByZXR1cm5lZCBpZiBhIG5vbi1pbmxpbmVmaWxlIHNjaGVtZSB1cmwgaXMgZ2l2ZW4uCisgICAqCisgICAqIDxwPklmIHRoZSBmaWxlIGhhcyBhbHJlYWR5IGJlZW4gZG93bmxvYWRlZC9pbXBvcnRlZCwgdGhpcyBtZXRob2QgaXMgYSBuby1vcC4KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gc3RhcnRJbXBvcnQoCisgICAgICBHcm91cEtleSBncm91cEtleSwKKyAgICAgIERhdGFGaWxlIGRhdGFGaWxlLAorICAgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5LAorICAgICAgQE51bGxhYmxlIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMsCisgICAgICBGaWxlU291cmNlIGlubGluZUZpbGVTb3VyY2UpIHsKKyAgICBpZiAoIWRhdGFGaWxlLmdldFVybFRvRG93bmxvYWQoKS5zdGFydHNXaXRoKE1kZENvbnN0YW50cy5JTkxJTkVfRklMRV9VUkxfU0NIRU1FKSkgeworICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5JTlZBTElEX0lOTElORV9GSUxFX1VSTF9TQ0hFTUUpCisgICAgICAgICAgICAgIC5zZXRNZXNzYWdlKCJJbXBvcnRpbmcgYW4gaW5saW5lIGZpbGUgcmVxdWlyZXMgaW5saW5lZmlsZSBzY2hlbWUiKQorICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgfQorICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSksCisgICAgICAgIHNoYXJlZEZpbGUgLT4geworICAgICAgICAgIGlmIChzaGFyZWRGaWxlID09IG51bGwpIHsKKyAgICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgICAiJXM6IFN0YXJ0IGltcG9ydCBjYWxsZWQgb24gZmlsZSB0aGF0IGRvZXNuJ3QgZXhpc3QuIElkID0gJXMiLAorICAgICAgICAgICAgICAgIFRBRywgZGF0YUZpbGUuZ2V0RmlsZUlkKCkpOworICAgICAgICAgICAgU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24gY2F1c2UgPSBuZXcgU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24oKTsKKyAgICAgICAgICAgIC8vIFRPRE8oYi8xNjc1ODI4MTUpOiBMb2cgdG8gQ2xlYXJjdXQKKyAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuU0hBUkVEX0ZJTEVfTk9UX0ZPVU5EX0VSUk9SKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2F1c2UoY2F1c2UpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICAvLyBJZiB3ZSBoYXZlIGFscmVhZHkgZG93bmxvYWRlZCB0aGUgZmlsZSwgdGhlbiByZXR1cm4uCisgICAgICAgICAgaWYgKHNoYXJlZEZpbGUuZ2V0RmlsZVN0YXR1cygpID09IEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpIHsKKyAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgfQorCisgICAgICAgICAgLy8gRGVsdGEgZmlsZXMgYXJlIG5vdCBzdXBwb3J0ZWQsIHNvIG9ubHkgY2hlY2sgZm9yIGRvd25sb2FkIHRyYW5zZm9ybXMKKyAgICAgICAgICBTaGFyZWRGaWxlLkJ1aWxkZXIgc2hhcmVkRmlsZUJ1aWxkZXIgPSBzaGFyZWRGaWxlLnRvQnVpbGRlcigpOworICAgICAgICAgIFN0cmluZyBkb3dubG9hZEZpbGVOYW1lID0KKyAgICAgICAgICAgICAgZGF0YUZpbGUuaGFzRG93bmxvYWRUcmFuc2Zvcm1zKCkKKyAgICAgICAgICAgICAgICAgID8gRmlsZU5hbWVVdGlsLmdldFRlbXBGaWxlTmFtZVdpdGhEb3dubG9hZGVkRmlsZUNoZWNrc3VtKAorICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSwgZGF0YUZpbGUuZ2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bSgpKQorICAgICAgICAgICAgICAgICAgOiBzaGFyZWRGaWxlLmdldEZpbGVOYW1lKCk7CisKKyAgICAgICAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgZ2V0RGF0YUZpbGVHcm91cE9yRGVmYXVsdChncm91cEtleSksCisgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAgLT4KKyAgICAgICAgICAgICAgICAgIGdldEltcG9ydEZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlQnVpbGRlciwKKyAgICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LAorICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZU5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRGaWxlR3JvdXBWZXJzaW9uTnVtYmVyKCksCisgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRCdWlsZElkKCksCisgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRWYXJpYW50SWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICBncm91cEtleSwKKyAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZENvbmRpdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgaW5saW5lRmlsZVNvdXJjZSksCisgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICB9LAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIGEgZnV0dXJlIHRoYXQgd2lsbCBwZXJmb3JtIHRoZSBpbXBvcnQuCisgICAqCisgICAqIDxwPlVwZGF0ZXMgdGhlIHNoYXJlZEZpbGUgc3RhdHVzIHRvIGluLXByb2dyZXNzIGFuZCBhdHRhY2hlcyBhIGNhbGxiYWNrIHRvIHRoZSBpbXBvcnQgdG8gaGFuZGxlCisgICAqIHBvc3QgaW1wb3J0IGFjdGlvbnMuCisgICAqLworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZ2V0SW1wb3J0RnV0dXJlKAorICAgICAgU2hhcmVkRmlsZS5CdWlsZGVyIHNoYXJlZEZpbGVCdWlsZGVyLAorICAgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5LAorICAgICAgU3RyaW5nIGRvd25sb2FkRmlsZU5hbWUsCisgICAgICBpbnQgZmlsZUdyb3VwVmVyc2lvbk51bWJlciwKKyAgICAgIGxvbmcgYnVpbGRJZCwKKyAgICAgIFN0cmluZyB2YXJpYW50SWQsCisgICAgICBHcm91cEtleSBncm91cEtleSwKKyAgICAgIERhdGFGaWxlIGRhdGFGaWxlLAorICAgICAgQE51bGxhYmxlIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMsCisgICAgICBGaWxlU291cmNlIGlubGluZUZpbGVTb3VyY2UpIHsKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFVyaT4gZG93bmxvYWRGaWxlT25EZXZpY2VVcmlGdXR1cmUgPQorICAgICAgICBnZXREb3dubG9hZEZpbGVPbkRldmljZVVyaSgKKyAgICAgICAgICAgIG5ld0ZpbGVLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKSwgZG93bmxvYWRGaWxlTmFtZSwgZGF0YUZpbGUuZ2V0Q2hlY2tzdW0oKSk7CisgICAgcmV0dXJuIEZsdWVudEZ1dHVyZS5mcm9tKGRvd25sb2FkRmlsZU9uRGV2aWNlVXJpRnV0dXJlKQorICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICB1bnVzZWQgLT4geworICAgICAgICAgICAgICBzaGFyZWRGaWxlQnVpbGRlci5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpOworCisgICAgICAgICAgICAgIC8vIFdyaXRlIHJldHVybnMgYSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBvciBub3QuIFdlIGNhbgorICAgICAgICAgICAgICAvLyBpZ25vcmUgdGhpcyBiZWNhdXNlIGEgZmFpbHVyZSB0byB3cml0ZSBoZXJlIHdvbid0IGltcGFjdCB0aGUgaW1wb3J0IG9wZXJhdGlvbi4gV2UKKyAgICAgICAgICAgICAgLy8gd2lsbCBhdHRlbXB0IHRvIHdyaXRlIHRoZSBmaW5hbCBzdGF0ZSAoY29tcGxldGVkIG9yIGZhaWxlZCkgYWZ0ZXIgdGhlIGltcG9ydAorICAgICAgICAgICAgICAvLyBvcGVyYXRpb24uCisgICAgICAgICAgICAgIHJldHVybiBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIHNoYXJlZEZpbGVCdWlsZGVyLmJ1aWxkKCkpOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIHVudXNlZCAtPiB7CisgICAgICAgICAgICAgIFVyaSBkb3dubG9hZEZpbGVPbkRldmljZVVyaSA9IEZ1dHVyZXMuZ2V0RG9uZShkb3dubG9hZEZpbGVPbkRldmljZVVyaUZ1dHVyZSk7CisgICAgICAgICAgICAgIERvd25sb2FkZXJDYWxsYmFjayBkb3dubG9hZGVyQ2FsbGJhY2sgPQorICAgICAgICAgICAgICAgICAgbmV3IERvd25sb2FkZXJDYWxsYmFja0ltcGwoCisgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIsCisgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwVmVyc2lvbk51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICBidWlsZElkLAorICAgICAgICAgICAgICAgICAgICAgIHZhcmlhbnRJZCwKKyAgICAgICAgICAgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgICAgICAgLy8gVE9ETzogd2hlbiBwYXJ0aWFsIGltcG9ydCBmaWxlcyBhcmUgc3VwcG9ydGVkLCBub3RpZnkgbW9uaXRvciBvZiBwYXJ0aWFsCisgICAgICAgICAgICAgIC8vIHByb2dyZXNzIGhlcmUuCisKKyAgICAgICAgICAgICAgcmV0dXJuIGZpbGVEb3dubG9hZGVyLnN0YXJ0Q29weWluZygKKyAgICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZU9uRGV2aWNlVXJpLAorICAgICAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpLAorICAgICAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0Qnl0ZVNpemUoKSwKKyAgICAgICAgICAgICAgICAgIGRvd25sb2FkQ29uZGl0aW9ucywKKyAgICAgICAgICAgICAgICAgIGRvd25sb2FkZXJDYWxsYmFjaywKKyAgICAgICAgICAgICAgICAgIGlubGluZUZpbGVTb3VyY2UpOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIFN0YXJ0IGRvd25sb2FkaW5nIHRoZSBmaWxlIGlmIHRoZSBmaWxlIGhhcyBub3QgeWV0IGJlZW4gZG93bmxvYWRlZC4gSWYgdGhlIGZpbGUgaGFzIGJlZW4KKyAgICogZG93bmxvYWRlZCwgdGhpcyBtZXRob2QgaXMgYSBuby1vcC4KKyAgICoKKyAgICogQHBhcmFtIGdyb3VwS2V5IC0gYSBLZXkgdGhhdCB1bmlxdWVseSBpZGVudGlmeSBhIGZpbGUgZ3JvdXAuCisgICAqIEBwYXJhbSBkYXRhRmlsZSAtIHRoZSBkYXRhIGZpbGUgcHJvdG8gcHJvdmlkZWQgYnkgY2xpZW50CisgICAqIEBwYXJhbSBuZXdGaWxlS2V5IC0gdGhlIGZpbGUga2V5IHRvIGdldCB0aGUgU2hhcmVkRmlsZS4KKyAgICogQHBhcmFtIGRvd25sb2FkQ29uZGl0aW9ucyAtIGNvbmRpdGlvbnMgdW5kZXIgd2hpY2ggdGhpcyBmaWxlIHNob3VsZCBiZSBkb3dubG9hZGVkLgorICAgKiBAcGFyYW0gdHJhZmZpY1RhZyAtIFRhZyBmb3IgdGhlIG5ldHdvcmsgdHJhZmZpYyB0byBkb3dubG9hZCB0aGlzIGRhdGFGaWxlLgorICAgKiBAcGFyYW0gZXh0cmFIdHRwSGVhZGVycyAtIEV4dHJhIEhlYWRlcnMgZm9yIHRoaXMgcmVxdWVzdC4KKyAgICogQHJldHVybiAtIExpc3RlbmFibGVGdXR1cmUgcmVwcmVzZW50aW5nIHRoZSBkb3dubG9hZCB0aGUgZmlsZS4gVGhlIExpc3RlbmFibGVGdXR1cmUgZmFpbHMgd2l0aAorICAgKiAgICAge0BsaW5rIERvd25sb2FkRXhjZXB0aW9ufSBpZiB0aGUgZG93bmxvYWQgaXMgdW5zdWNjZXNzZnVsLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBzdGFydERvd25sb2FkKAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksCisgICAgICBEYXRhRmlsZSBkYXRhRmlsZSwKKyAgICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSwKKyAgICAgIEBOdWxsYWJsZSBEb3dubG9hZENvbmRpdGlvbnMgZG93bmxvYWRDb25kaXRpb25zLAorICAgICAgaW50IHRyYWZmaWNUYWcsCisgICAgICBMaXN0PEV4dHJhSHR0cEhlYWRlcj4gZXh0cmFIdHRwSGVhZGVycykgeworICAgIGlmIChkYXRhRmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkuc3RhcnRzV2l0aChNZGRDb25zdGFudHMuSU5MSU5FX0ZJTEVfVVJMX1NDSEVNRSkpIHsKKyAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuSU5WQUxJRF9JTkxJTkVfRklMRV9VUkxfU0NIRU1FKQorICAgICAgICAgICAgICAuc2V0TWVzc2FnZSgKKyAgICAgICAgICAgICAgICAgICJkb3dubG9hZGluZyBhIGZpbGUgd2l0aCBhbiBpbmxpbmVmaWxlIHNjaGVtZSBpcyBub3Qgc3VwcG9ydGVkLCB1c2UgaW1wb3J0RmlsZXMiCisgICAgICAgICAgICAgICAgICAgICAgKyAiIGluc3RlYWQuIikKKyAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgIH0KKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKG5ld0ZpbGVLZXkpLAorICAgICAgICBzaGFyZWRGaWxlIC0+IHsKKyAgICAgICAgICBpZiAoc2hhcmVkRmlsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBUT0RPKGIvMTMxMTY2OTI1KTogTUREIGR1bXAgc2hvdWxkIG5vdCB1c2UgbGl0ZSBwcm90byB0b1N0cmluZy4KKyAgICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgICAiJXM6IFN0YXJ0IGRvd25sb2FkIGNhbGxlZCBvbiBmaWxlIHRoYXQgZG9lc24ndCBleGlzdHMuIEtleSA9ICVzISIsCisgICAgICAgICAgICAgICAgVEFHLCBuZXdGaWxlS2V5KTsKKyAgICAgICAgICAgIFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uIGNhdXNlID0gbmV3IFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uKCk7CisgICAgICAgICAgICBzaWxlbnRGZWVkYmFjay5zZW5kKGNhdXNlLCAiU2hhcmVkIGZpbGUgbm90IGZvdW5kIGluIGRvd25sb2FkRmlsZUdyb3VwIik7CisgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLlNIQVJFRF9GSUxFX05PVF9GT1VORF9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgLnNldENhdXNlKGNhdXNlKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBhbHJlYWR5IGRvd25sb2FkZWQgdGhlIGZpbGUsIHRoZW4gcmV0dXJuLgorICAgICAgICAgIGlmIChzaGFyZWRGaWxlLmdldEZpbGVTdGF0dXMoKSA9PSBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSB7CisgICAgICAgICAgICBpZiAoZG93bmxvYWRNb25pdG9yT3B0aW9uYWwuaXNQcmVzZW50KCkpIHsKKyAgICAgICAgICAgICAgLy8gRm9yIHRoZSBkb3dubG9hZGVkIGZpbGUsIHdlIGRvbid0IG5lZWQgdG8gbW9uaXRvciB0aGUgZmlsZSBjaGFuZ2UuIFdlIGp1c3QgbmVlZCB0bworICAgICAgICAgICAgICAvLyBpbmZvcm0gdGhlIG1vbml0b3IgYWJvdXQgaXRzIGN1cnJlbnQgc2l6ZS4KKyAgICAgICAgICAgICAgZG93bmxvYWRNb25pdG9yT3B0aW9uYWwKKyAgICAgICAgICAgICAgICAgIC5nZXQoKQorICAgICAgICAgICAgICAgICAgLm5vdGlmeUN1cnJlbnRGaWxlU2l6ZShncm91cEtleS5nZXRHcm91cE5hbWUoKSwgZGF0YUZpbGUuZ2V0Qnl0ZVNpemUoKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgIH0KKworICAgICAgICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICBmaW5kRmlyc3REZWx0YUZpbGVXaXRoQmFzZUZpbGVEb3dubG9hZGVkKGRhdGFGaWxlLCBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCkpLAorICAgICAgICAgICAgICBkZWx0YUZpbGUgLT4geworICAgICAgICAgICAgICAgIFNoYXJlZEZpbGUuQnVpbGRlciBzaGFyZWRGaWxlQnVpbGRlciA9IHNoYXJlZEZpbGUudG9CdWlsZGVyKCk7CisgICAgICAgICAgICAgICAgU3RyaW5nIGRvd25sb2FkRmlsZU5hbWUgPSBzaGFyZWRGaWxlLmdldEZpbGVOYW1lKCk7CisgICAgICAgICAgICAgICAgaWYgKGRlbHRhRmlsZSAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVOYW1lID0KKyAgICAgICAgICAgICAgICAgICAgICBGaWxlTmFtZVV0aWwuZ2V0VGVtcEZpbGVOYW1lV2l0aERvd25sb2FkZWRGaWxlQ2hlY2tzdW0oCisgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZU5hbWUsIGRlbHRhRmlsZS5nZXRDaGVja3N1bSgpKTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRhdGFGaWxlLmhhc0Rvd25sb2FkVHJhbnNmb3JtcygpKSB7CisgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVOYW1lID0KKyAgICAgICAgICAgICAgICAgICAgICBGaWxlTmFtZVV0aWwuZ2V0VGVtcEZpbGVOYW1lV2l0aERvd25sb2FkZWRGaWxlQ2hlY2tzdW0oCisgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZU5hbWUsIGRhdGFGaWxlLmdldERvd25sb2FkZWRGaWxlQ2hlY2tzdW0oKSk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgLy8gVmFyaWFibGVzIGNhcHR1cmVkIGluIGxhbWJkYXMgbXVzdCBiZSBlZmZlY3RpdmVseSBmaW5hbC4KKyAgICAgICAgICAgICAgICBTdHJpbmcgZG93bmxvYWRGaWxlTmFtZUNhcHR1cmUgPSBkb3dubG9hZEZpbGVOYW1lOworICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICAgICAgICBnZXREYXRhRmlsZUdyb3VwT3JEZWZhdWx0KGdyb3VwS2V5KSwKKyAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cCAtPgorICAgICAgICAgICAgICAgICAgICAgICAgZ2V0RG93bmxvYWRGdXR1cmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZUJ1aWxkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3RmlsZUtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVOYW1lQ2FwdHVyZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLmdldEZpbGVHcm91cFZlcnNpb25OdW1iZXIoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLmdldEJ1aWxkSWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLmdldFZhcmlhbnRJZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbHRhRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZENvbmRpdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhZmZpY1RhZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYUh0dHBIZWFkZXJzKSwKKyAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICB9LAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBnZXREb3dubG9hZEZ1dHVyZSgKKyAgICAgIFNoYXJlZEZpbGUuQnVpbGRlciBzaGFyZWRGaWxlQnVpbGRlciwKKyAgICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSwKKyAgICAgIFN0cmluZyBkb3dubG9hZEZpbGVOYW1lLAorICAgICAgaW50IGZpbGVHcm91cFZlcnNpb25OdW1iZXIsCisgICAgICBsb25nIGJ1aWxkSWQsCisgICAgICBTdHJpbmcgdmFyaWFudElkLAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksCisgICAgICBEYXRhRmlsZSBkYXRhRmlsZSwKKyAgICAgIEBOdWxsYWJsZSBEZWx0YUZpbGUgZGVsdGFGaWxlLAorICAgICAgQE51bGxhYmxlIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMsCisgICAgICBpbnQgdHJhZmZpY1RhZywKKyAgICAgIExpc3Q8RXh0cmFIdHRwSGVhZGVyPiBleHRyYUh0dHBIZWFkZXJzKSB7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxVcmk+IGRvd25sb2FkRmlsZU9uRGV2aWNlVXJpRnV0dXJlID0KKyAgICAgICAgZ2V0RG93bmxvYWRGaWxlT25EZXZpY2VVcmkoCisgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksIGRvd25sb2FkRmlsZU5hbWUsIGRhdGFGaWxlLmdldENoZWNrc3VtKCkpOworICAgIHJldHVybiBGbHVlbnRGdXR1cmUuZnJvbShkb3dubG9hZEZpbGVPbkRldmljZVVyaUZ1dHVyZSkKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgdW51c2VkIC0+IHsKKyAgICAgICAgICAgICAgc2hhcmVkRmlsZUJ1aWxkZXIuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKTsKKworICAgICAgICAgICAgICAvLyBJZ25vcmluZyBmYWlsdXJlIHRvIHdyaXRlIGJhY2sgaGVyZSwgYXMgaXQgd2lsbCBqdXN0IHJlc3VsdCBpbiBvbmUgZXh0cmEgdHJ5IHRvCisgICAgICAgICAgICAgIC8vIGRvd25sb2FkIHRoZSBmaWxlLgorICAgICAgICAgICAgICByZXR1cm4gc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBzaGFyZWRGaWxlQnVpbGRlci5idWlsZCgpKTsKKyAgICAgICAgICAgIH0sCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICB1bnVzZWQgLT4geworICAgICAgICAgICAgICBVcmkgZG93bmxvYWRGaWxlT25EZXZpY2VVcmkgPSBGdXR1cmVzLmdldERvbmUoZG93bmxvYWRGaWxlT25EZXZpY2VVcmlGdXR1cmUpOworICAgICAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGZpbGVEb3dubG9hZEZ1dHVyZTsKKyAgICAgICAgICAgICAgaWYgKCFkZWx0YURlY29kZXJPcHRpb25hbC5pc1ByZXNlbnQoKSB8fCBkZWx0YUZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgIC8vIERvd25sb2FkIGZ1bGwgZmlsZSB3aGVuIGRlbHRhIGZpbGUgaXMgbnVsbAorICAgICAgICAgICAgICAgIERvd25sb2FkZXJDYWxsYmFjayBkb3dubG9hZGVyQ2FsbGJhY2sgPQorICAgICAgICAgICAgICAgICAgICBuZXcgRG93bmxvYWRlckNhbGxiYWNrSW1wbCgKKyAgICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3RmlsZUtleS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIsCisgICAgICAgICAgICAgICAgICAgICAgICBncm91cEtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cFZlcnNpb25OdW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICBidWlsZElkLAorICAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFudElkLAorICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKworICAgICAgICAgICAgICAgIG1heU5vdGlmeUN1cnJlbnRTaXplT2ZQYXJ0aWFsbHlEb3dubG9hZGVkRmlsZShncm91cEtleSwgZG93bmxvYWRGaWxlT25EZXZpY2VVcmkpOworCisgICAgICAgICAgICAgICAgZmlsZURvd25sb2FkRnV0dXJlID0KKyAgICAgICAgICAgICAgICAgICAgZmlsZURvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwVmVyc2lvbk51bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGJ1aWxkSWQsCisgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZEZpbGVPbkRldmljZVVyaSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLmdldFVybFRvRG93bmxvYWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLmdldEJ5dGVTaXplKCksCisgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZENvbmRpdGlvbnMsCisgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZGVyQ2FsbGJhY2ssCisgICAgICAgICAgICAgICAgICAgICAgICB0cmFmZmljVGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFIdHRwSGVhZGVycyk7CisgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgRG93bmxvYWRlckNhbGxiYWNrIGRvd25sb2FkZXJDYWxsYmFjayA9CisgICAgICAgICAgICAgICAgICAgIG5ldyBEZWx0YUZpbGVEb3dubG9hZGVyQ2FsbGJhY2tJbXBsKAorICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUsCisgICAgICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICAgICAgICAgICAgICBkZWx0YURlY29kZXJPcHRpb25hbC5nZXQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbHRhRmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50TG9nZ2VyLAorICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBWZXJzaW9uTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhcmlhbnRJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQsCisgICAgICAgICAgICAgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworCisgICAgICAgICAgICAgICAgbWF5Tm90aWZ5Q3VycmVudFNpemVPZlBhcnRpYWxseURvd25sb2FkZWRGaWxlKGdyb3VwS2V5LCBkb3dubG9hZEZpbGVPbkRldmljZVVyaSk7CisKKyAgICAgICAgICAgICAgICBmaWxlRG93bmxvYWRGdXR1cmUgPQorICAgICAgICAgICAgICAgICAgICBmaWxlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKAorICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlR3JvdXBWZXJzaW9uTnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRJZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkRmlsZU9uRGV2aWNlVXJpLAorICAgICAgICAgICAgICAgICAgICAgICAgZGVsdGFGaWxlLmdldFVybFRvRG93bmxvYWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRlbHRhRmlsZS5nZXRCeXRlU2l6ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRDb25kaXRpb25zLAorICAgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRlckNhbGxiYWNrLAorICAgICAgICAgICAgICAgICAgICAgICAgdHJhZmZpY1RhZywKKyAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhSHR0cEhlYWRlcnMpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIHJldHVybiBmaWxlRG93bmxvYWRGdXR1cmU7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgVVJJIHdoZXJlIHRoZSBnaXZlbiBmaWxlIHNob3VsZCBiZSBsb2NhdGVkIG9uLWRldmljZS4KKyAgICoKKyAgICogQHBhcmFtIGFsbG93ZWRSZWFkZXJzIHRoZSBhbGxvd2VkIHJlYWRlcnMgb2YgdGhlIGZpbGUKKyAgICogQHBhcmFtIGRvd25sb2FkRmlsZU5hbWUgdGhlIG5hbWUgb2YgdGhlIGZpbGUKKyAgICogQHBhcmFtIGNoZWNrc3VtIHRoZSBjaGVja3N1bSBvZiB0aGUgZmlsZQorICAgKi8KKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFVyaT4gZ2V0RG93bmxvYWRGaWxlT25EZXZpY2VVcmkoCisgICAgICBBbGxvd2VkUmVhZGVycyBhbGxvd2VkUmVhZGVycywgU3RyaW5nIGRvd25sb2FkRmlsZU5hbWUsIFN0cmluZyBjaGVja3N1bSkgeworICAgIFVyaSBkb3dubG9hZEZpbGVPbkRldmljZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgYWxsb3dlZFJlYWRlcnMsCisgICAgICAgICAgICBkb3dubG9hZEZpbGVOYW1lLAorICAgICAgICAgICAgY2hlY2tzdW0sCisgICAgICAgICAgICBzaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIGluc3RhbmNlSWQsCisgICAgICAgICAgICAvKiBhbmRyb2lkU2hhcmVkID0gKi8gZmFsc2UpOworICAgIGlmIChkb3dubG9hZEZpbGVPbkRldmljZVVyaSA9PSBudWxsKSB7CisgICAgICBMb2dVdGlsLmUoIiVzOiBGYWlsZWQgdG8gZ2V0IGZpbGUgdXJpISIsIFRBRyk7CisgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLlVOQUJMRV9UT19DUkVBVEVfRklMRV9VUklfRVJST1IpCisgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICB9CisgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGRvd25sb2FkRmlsZU9uRGV2aWNlVXJpKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBtYXlOb3RpZnlDdXJyZW50U2l6ZU9mUGFydGlhbGx5RG93bmxvYWRlZEZpbGUoCisgICAgICBHcm91cEtleSBncm91cEtleSwgVXJpIGRvd25sb2FkRmlsZU9uRGV2aWNlVXJpKSB7CisgICAgaWYgKGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICAvLyBJbmZvcm0gdGhlIG1vbml0b3IgYWJvdXQgdGhlIGN1cnJlbnQgc2l6ZSBvZiB0aGUgcGFydGlhbGx5IGRvd25sb2FkZWQgZmlsZS4KKyAgICAgIHRyeSB7CisgICAgICAgIGxvbmcgY3VycmVudEZpbGVTaXplID0gZmlsZVN0b3JhZ2UuZmlsZVNpemUoZG93bmxvYWRGaWxlT25EZXZpY2VVcmkpOworICAgICAgICBpZiAoY3VycmVudEZpbGVTaXplID4gMCkgeworICAgICAgICAgIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsCisgICAgICAgICAgICAgIC5nZXQoKQorICAgICAgICAgICAgICAubm90aWZ5Q3VycmVudEZpbGVTaXplKGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpLCBjdXJyZW50RmlsZVNpemUpOworICAgICAgICB9CisgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgIC8vIElnbm9yZSBhbnkgZmlsZVNpemUgZXJyb3IuCisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZ2V0RGF0YUZpbGVHcm91cE9yRGVmYXVsdChHcm91cEtleSBncm91cEtleSkgeworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChncm91cEtleSksCisgICAgICAgIGZpbGVHcm91cCAtPgorICAgICAgICAgICAgRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoCisgICAgICAgICAgICAgICAgKGZpbGVHcm91cCA9PSBudWxsKSA/IERhdGFGaWxlR3JvdXBJbnRlcm5hbC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpbGVHcm91cCksCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIEBwYXJhbSBkYXRhRmlsZSAtIGEgRGF0YUZpbGUgcHJvdG8gb2JqZWN0CisgICAqIEBwYXJhbSBhbGxvd2VkUmVhZGVycyAtIGFsbG93ZWQgcmVhZGVycyBvZiB0aGUgZmlsZSBncm91cCwgYXNzdW1pbmcgdGhlIGJhc2UgZmlsZSBoYXMgdGhlIHNhbWUKKyAgICogICAgIHJlYWRlcnMgc2V0CisgICAqIEByZXR1cm4gLSB0aGUgZmlyc3QgRGVsdGEgZmlsZSB3aGljaCBpdHMgYmFzZSBmaWxlIGlzIG9uIGRldmljZSBhbmQgaXRzIGZpbGUgc3RhdHVzIGlzIGRvd25sb2FkCisgICAqICAgICBjb21wbGV0ZWQKKyAgICovCisgIEBWaXNpYmxlRm9yVGVzdGluZworICBMaXN0ZW5hYmxlRnV0dXJlPEBOdWxsYWJsZVR5cGUgRGVsdGFGaWxlPiBmaW5kRmlyc3REZWx0YUZpbGVXaXRoQmFzZUZpbGVEb3dubG9hZGVkKAorICAgICAgRGF0YUZpbGUgZGF0YUZpbGUsIEFsbG93ZWRSZWFkZXJzIGFsbG93ZWRSZWFkZXJzKSB7CisgICAgaWYgKE1pZ3JhdGlvbnMuZ2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgc2lsZW50RmVlZGJhY2spLnZhbHVlCisgICAgICAgICAgICA8IEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZLnZhbHVlCisgICAgICAgIHx8ICFkZWx0YURlY29kZXJPcHRpb25hbC5pc1ByZXNlbnQoKQorICAgICAgICB8fCBkZWx0YURlY29kZXJPcHRpb25hbC5nZXQoKS5nZXREZWNvZGVyTmFtZSgpID09IERpZmZEZWNvZGVyLlVOU1BFQ0lGSUVEKSB7CisgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCk7CisgICAgfQorICAgIHJldHVybiBmaW5kRmlyc3REZWx0YUZpbGVXaXRoQmFzZUZpbGVEb3dubG9hZGVkKAorICAgICAgICBkYXRhRmlsZS5nZXREZWx0YUZpbGVMaXN0KCksIC8qIGluZGV4ID0gKi8gMCwgYWxsb3dlZFJlYWRlcnMpOworICB9CisKKyAgLy8gV2UgbXVzdCB1c2UgcmVjdXJzaW9uIGhlcmUgc2luY2UgdGhlIGRlY2lzaW9uIHRvIGNvbnRpbnVlIGl0ZXJhdGluZyBpcyBkZXBlbmRlbnQgb24gdGhlIHJlc3VsdAorICAvLyBvZiB0aGUgYXN5bmNocm9ub3VzIFNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZCgpIG9wZXJhdGlvbgorICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8QE51bGxhYmxlVHlwZSBEZWx0YUZpbGU+IGZpbmRGaXJzdERlbHRhRmlsZVdpdGhCYXNlRmlsZURvd25sb2FkZWQoCisgICAgICBMaXN0PERlbHRhRmlsZT4gZGVsdGFGaWxlcywgaW50IGluZGV4LCBBbGxvd2VkUmVhZGVycyBhbGxvd2VkUmVhZGVycykgeworICAgIGlmIChpbmRleCA9PSBkZWx0YUZpbGVzLnNpemUoKSkgeworICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpOworICAgIH0KKyAgICBEZWx0YUZpbGUgZGVsdGFGaWxlID0gZGVsdGFGaWxlcy5nZXQoaW5kZXgpOworICAgIGlmIChkZWx0YUZpbGUuZ2V0RGlmZkRlY29kZXIoKSAhPSBkZWx0YURlY29kZXJPcHRpb25hbC5nZXQoKS5nZXREZWNvZGVyTmFtZSgpKSB7CisgICAgICByZXR1cm4gZmluZEZpcnN0RGVsdGFGaWxlV2l0aEJhc2VGaWxlRG93bmxvYWRlZChkZWx0YUZpbGVzLCBpbmRleCArIDEsIGFsbG93ZWRSZWFkZXJzKTsKKyAgICB9CisgICAgTmV3RmlsZUtleSBiYXNlRmlsZUtleSA9CisgICAgICAgIE5ld0ZpbGVLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oZGVsdGFGaWxlLmdldEJhc2VGaWxlKCkuZ2V0Q2hlY2tzdW0oKSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVycyhhbGxvd2VkUmVhZGVycykKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQoYmFzZUZpbGVLZXkpLAorICAgICAgICBiYXNlRmlsZU1ldGFkYXRhIC0+IHsKKyAgICAgICAgICBpZiAoYmFzZUZpbGVNZXRhZGF0YSAhPSBudWxsCisgICAgICAgICAgICAgICYmIGJhc2VGaWxlTWV0YWRhdGEuZ2V0RmlsZVN0YXR1cygpID09IEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpIHsKKyAgICAgICAgICAgIFVyaSBiYXNlRmlsZVVyaSA9CisgICAgICAgICAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgYmFzZUZpbGVLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgICAgICAgICAgYmFzZUZpbGVNZXRhZGF0YS5nZXRGaWxlTmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBiYXNlRmlsZUtleS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgICAgICAgICBzaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZCwKKyAgICAgICAgICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKyAgICAgICAgICAgIGlmIChiYXNlRmlsZVVyaSAhPSBudWxsKSB7CisgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkZWx0YUZpbGUpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gZmluZEZpcnN0RGVsdGFGaWxlV2l0aEJhc2VGaWxlRG93bmxvYWRlZChkZWx0YUZpbGVzLCBpbmRleCArIDEsIGFsbG93ZWRSZWFkZXJzKTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKyAgLyoqCisgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIHRoZSBmaWxlLgorICAgKgorICAgKiBAcGFyYW0gbmV3RmlsZUtleSAtIHRoZSBmaWxlIGtleSB0byBnZXQgdGhlIFNoYXJlZEZpbGUuCisgICAqIEByZXR1cm4gLSBGaWxlU3RhdHVzIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgZmlsZS4gVGhlIExpc3RlbmFibGVGdXR1cmUgbWF5IHRocm93CisgICAqICAgICBhIFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uIGlmIHRoZSBzaGFyZWQgZmlsZSBtZXRhZGF0YSBpcyBtaXNzaW5nLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxGaWxlU3RhdHVzPiBnZXRGaWxlU3RhdHVzKE5ld0ZpbGVLZXkgbmV3RmlsZUtleSkgeworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBnZXRTaGFyZWRGaWxlKG5ld0ZpbGVLZXkpLAorICAgICAgICBleGlzdGluZ1NoYXJlZEZpbGUgLT4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZXhpc3RpbmdTaGFyZWRGaWxlLmdldEZpbGVTdGF0dXMoKSksCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIFZlcmlmaWVzIHRoYXQgdGhlIGZpbGUgZXhpc3RzIGluIG1ldGFkYXRhIGFuZCBvbiBkaXNrLiBBbHNvIHBlcmZvcm1zIHRoZSBzYW1lIHZhbGlkYXRpb24gY2hlY2sKKyAgICogdGhhdCdzIHBlcmZvcm1lZCBhZnRlciBkb3dubG9hZCB0byBlbnN1cmUgdGhlIGZpbGUgaGFzbid0IGJlZW4gZGVsZXRlZCBvciBjb3JydXB0ZWQuCisgICAqCisgICAqIEBwYXJhbSBuZXdGaWxlS2V5IC0gdGhlIGZpbGUga2V5IHRvIGdldCB0aGUgU2hhcmVkRmlsZS4KKyAgICogQHJldHVybiAtIFRoZSBMaXN0ZW5hYmxlRnV0dXJlIG1heSB0aHJvdyBhIFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uIGlmIHRoZSBzaGFyZWQgZmlsZQorICAgKiAgICAgbWV0YWRhdGEgaXMgbWlzc2luZyBvciB0aGUgb24gZGlzayBmaWxlIGlzIGNvcnJ1cHRlZC4KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVWZXJpZnlGaWxlKE5ld0ZpbGVLZXkgbmV3RmlsZUtleSwgRGF0YUZpbGUgZGF0YUZpbGUpIHsKKyAgICByZXR1cm4gRmx1ZW50RnV0dXJlLmZyb20oZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KSkKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgZXhpc3RpbmdTaGFyZWRGaWxlIC0+IHsKKyAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nU2hhcmVkRmlsZS5nZXRGaWxlU3RhdHVzKCkgIT0gRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkgeworICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAvLyBEb3VibGUgY2hlY2sgdGhhdCBpdCdzIHJlYWxseSBjb21wbGV0ZSwgYW5kIHVwZGF0ZSBzdGF0dXMgaWYgaXQncyBub3QuCisgICAgICAgICAgICAgIHJldHVybiBGbHVlbnRGdXR1cmUuZnJvbShnZXRPbkRldmljZVVyaShuZXdGaWxlS2V5KSkKKyAgICAgICAgICAgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgICAgICAgICB1cmkgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEb3dubG9hZFJlc3VsdENvZGUuRE9XTkxPQURFRF9GSUxFX05PVF9GT1VORF9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nU2hhcmVkRmlsZS5nZXRBbmRyb2lkU2hhcmVkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSnVzdCBjaGVjayBmb3IgcHJlc2VuY2UuIEJsb2JTdG9yZU1hbmFnZXIgaXMgcmVzcG9uc2libGUgZm9yCisgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGludGVncml0eS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFmaWxlU3RvcmFnZS5leGlzdHModXJpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRSZXN1bHRDb2RlLkRPV05MT0FERURfRklMRV9OT1RfRk9VTkRfRVJST1IpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICBGaWxlVmFsaWRhdG9yLnZhbGlkYXRlRG93bmxvYWRlZEZpbGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZSwgZGF0YUZpbGUsIHVyaSwgZGF0YUZpbGUuZ2V0Q2hlY2tzdW0oKSk7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAgICAgICAgICAgLmNhdGNoaW5nQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgZSAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiByZVZlcmlmeUZpbGUgbG9zdCBvciBjb3JydXB0ZWQgY29kZSAlcyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgVEFHLCBlLmdldERvd25sb2FkUmVzdWx0Q29kZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFNoYXJlZEZpbGUgdXBkYXRlZFNoYXJlZEZpbGUgPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nU2hhcmVkRmlsZS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkNPUlJVUFRFRCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRmx1ZW50RnV0dXJlLmZyb20oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEud3JpdGUobmV3RmlsZUtleSwgdXBkYXRlZFNoYXJlZEZpbGUpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2sgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uIGV4ID0gbmV3IFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFvaykgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJmYWlsZWQgdG8gc2F2ZSBzaGFyZWRGaWxlc01ldGFkYXRhIiwgZXgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBleDsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgICAgIH0sCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSB7QGNvZGUgU2hhcmVkRmlsZX0uCisgICAqCisgICAqIEBwYXJhbSBuZXdGaWxlS2V5IC0gdGhlIGZpbGUga2V5IHRvIGdldCB0aGUgU2hhcmVkRmlsZS4KKyAgICogQHJldHVybiAtIHRoZSBTaGFyZWRGaWxlIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBtZXRhZGF0YSBvZiB0aGUgZmlsZS4gVGhlIExpc3RlbmFibGVGdXR1cmUKKyAgICogICAgIG1heSB0aHJvdyBhIFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uIGlmIHRoZSBzaGFyZWQgZmlsZSBtZXRhZGF0YSBpcyBtaXNzaW5nLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxTaGFyZWRGaWxlPiBnZXRTaGFyZWRGaWxlKE5ld0ZpbGVLZXkgbmV3RmlsZUtleSkgeworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSksCisgICAgICAgIGV4aXN0aW5nU2hhcmVkRmlsZSAtPiB7CisgICAgICAgICAgaWYgKGV4aXN0aW5nU2hhcmVkRmlsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBUT0RPKGIvMTMxMTY2OTI1KTogTUREIGR1bXAgc2hvdWxkIG5vdCB1c2UgbGl0ZSBwcm90byB0b1N0cmluZy4KKyAgICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgICAiJXM6IGdldFNoYXJlZEZpbGUgY2FsbGVkIG9uIGZpbGUgdGhhdCBkb2Vzbid0IGV4aXN0cyEgS2V5ID0gJXMiLCBUQUcsIG5ld0ZpbGVLZXkpOworICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKG5ldyBTaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbigpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGV4aXN0aW5nU2hhcmVkRmlsZSk7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIFNldHMgYSBmaWxlIGVudHJ5IGFzIGRvd25sb2FkZWQgYW5kIGFuZHJvaWQtc2hhcmVkLiBJZiB0aGVyZSBpcyBhbiBleGlzdGluZyBlbnRyeSBmb3Ige0Bjb2RlCisgICAqIG5ld0ZpbGVLZXl9LCBvdmVyd3JpdGVzIGl0LgorICAgKgorICAgKiBAcGFyYW0gbmV3RmlsZUtleSAtIHRoZSBmaWxlIGtleSBmb3IgdGhlIGVucnkgdGhhdCB5b3Ugd2lzaCB0byBzdG9yZS4KKyAgICogQHBhcmFtIGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0gLSB0aGUgZmlsZSBjaGVja3N1bSB0aGF0IHJlcHJlc2VudHMgYSBibG9iIGluIHRoZSBBbmRyb2lkIFNoYXJpbmcKKyAgICogICAgIFNlcnZpY2UuCisgICAqIEBwYXJhbSBtYXhFeHBpcmF0aW9uRGF0ZVNlY3MgLSB0aGUgbmV3IG1heGltdW0gZXhwaXJhdGlvbiBkYXRlCisgICAqIEByZXR1cm4gLSBmYWxzZSBpZiB1bmFibGUgdG8gY29tbWl0IHRoZSB3cml0ZSBvcGVyYXRpb24KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gc2V0QW5kcm9pZFNoYXJlZERvd25sb2FkZWRGaWxlRW50cnkoCisgICAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXksIFN0cmluZyBhbmRyb2lkU2hhcmluZ0NoZWNrc3VtLCBsb25nIG1heEV4cGlyYXRpb25EYXRlU2VjcykgeworICAgIFNoYXJlZEZpbGUgbmV3U2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJhbmRyb2lkX3NoYXJlZF8iICsgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSkKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKHRydWUpCisgICAgICAgICAgICAuc2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKG1heEV4cGlyYXRpb25EYXRlU2VjcykKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0pCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICByZXR1cm4gc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBuZXdTaGFyZWRGaWxlKTsKKyAgfQorCisgIC8qKgorICAgKiBJZiBuZWNlc3NhcnksIHVwZGF0ZXMgdGhlIHtAY29kZSBtYXhfZXhwaXJhdGlvbl9kYXRlfSBkYXRlIHN0b3JlZCBpbiB0aGUgc2hhcmVkIGZpbGUgbWV0YWRhdGEKKyAgICogYXNzb2NpYXRlZCB0byB7QGNvZGUgbmV3RmlsZUtleX0uIE5vLW9wIG90aGVyd2lzZS4KKyAgICoKKyAgICogQHBhcmFtIG5ld0ZpbGVLZXkgLSB0aGUgZmlsZSBrZXkgZm9yIHRoZSBlbnJ5IHRoYXQgeW91IHdpc2ggdG8gdXBkYXRlLgorICAgKiBAcGFyYW0gZmlsZUV4cGlyYXRpb25EYXRlU2VjcyAtIHRoZSBleHBpcmF0aW9uIGRhdGUgb2YgdGhlIGN1cnJlbnQgZmlsZS4KKyAgICogQHJldHVybiAtIGZhbHNlIGlmIHVuYWJsZSB0byBjb21taXQgdGhlIHdyaXRlIG9wZXJhdGlvbi4gVGhlIExpc3RlbmFibGVGdXR1cmUgbWF5IHRocm93IGEKKyAgICogICAgIFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uIGlmIHRoZSBzaGFyZWQgZmlsZSBtZXRhZGF0YSBpcyBtaXNzaW5nLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiB1cGRhdGVNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoCisgICAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXksIGxvbmcgZmlsZUV4cGlyYXRpb25EYXRlU2VjcykgeworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBnZXRTaGFyZWRGaWxlKG5ld0ZpbGVLZXkpLAorICAgICAgICBleGlzdGluZ1NoYXJlZEZpbGUgLT4geworICAgICAgICAgIGlmIChmaWxlRXhwaXJhdGlvbkRhdGVTZWNzID4gZXhpc3RpbmdTaGFyZWRGaWxlLmdldE1heEV4cGlyYXRpb25EYXRlU2VjcygpKSB7CisgICAgICAgICAgICBTaGFyZWRGaWxlIHVwZGF0ZWRTaGFyZWRGaWxlID0KKyAgICAgICAgICAgICAgICBleGlzdGluZ1NoYXJlZEZpbGUudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhmaWxlRXhwaXJhdGlvbkRhdGVTZWNzKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAgICAgICAgIHJldHVybiBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIHVwZGF0ZWRTaGFyZWRGaWxlKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpOworICAgICAgICB9LAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIGZ1dHVyZSByZXNvbHZpbmcgdG8gdXJpIGZvciB0aGUgZmlsZS4KKyAgICoKKyAgICogQHBhcmFtIG5ld0ZpbGVLZXkgLSB0aGUgZmlsZSBrZXkgdG8gZ2V0IHRoZSBTaGFyZWRGaWxlLgorICAgKiBAcmV0dXJuIC0gYSBmdXR1cmUgcmVzb2x2aW5nIHRvIHRoZSBNb2JTdG9yZSBhbmRyb2lkIFVyaSB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZmlsZS4gVGhlCisgICAqICAgICB1cmkgd2lsbCBiZSBudWxsIGlmIHRoZSBTaGFyZWRGaWxlTWFuYWdlciBkb2Vzbid0IGhhdmUgYW4gZW50cnkgbWF0Y2hpbmcgdGhhdCBmaWxlIG9yIHRoZXJlCisgICAqICAgICBpcyBhbiBlcnJvciBwb3B1bGF0aW5nIHRoZSB1cmkgb2YgdGhlIGZpbGUuCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxATnVsbGFibGVUeXBlIFVyaT4gZ2V0T25EZXZpY2VVcmkoTmV3RmlsZUtleSBuZXdGaWxlS2V5KSB7CisgICAgcmV0dXJuIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChuZXdGaWxlS2V5KSwKKyAgICAgICAgc2hhcmVkRmlsZSAtPiB7CisgICAgICAgICAgaWYgKHNoYXJlZEZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gVE9ETyhiLzEzMTE2NjkyNSk6IE1ERCBkdW1wIHNob3VsZCBub3QgdXNlIGxpdGUgcHJvdG8gdG9TdHJpbmcuCisgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgIiVzOiBnZXRPbkRldmljZVVyaSBjYWxsZWQgb24gZmlsZSB0aGF0IGRvZXNuJ3QgZXhpc3RzLiBLZXkgPSAlcyEiLAorICAgICAgICAgICAgICAgIFRBRywgbmV3RmlsZUtleSk7CisgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUobmV3IFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uKCkpOworICAgICAgICAgIH0KKworICAgICAgICAgIFVyaSBvbkRldmljZVVyaSA9CisgICAgICAgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgICAgICAgbmV3RmlsZUtleS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZS5nZXRGaWxlTmFtZSgpLAorICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCksCisgICAgICAgICAgICAgICAgICBzaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQsCisgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlLmdldEFuZHJvaWRTaGFyZWQoKSk7CisgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG9uRGV2aWNlVXJpKTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKioKKyAgICogUmVtb3ZlcyB0aGUgZmlsZSBlbnRyeSBjb3JyZXNwb25kaW5nIHRvIG5ld0ZpbGVLZXkuIElmIHRoZSBmaWxlIGhhc24ndCBiZWVuIGZ1bGx5IGRvd25sb2FkZWQsCisgICAqIHRoZSBwYXJ0aWFsIGZpbGUgaXMgZGVsZXRlZCBmcm9tIHRoZSBkZXZpY2UgYW5kIHRoZSBkb3dubG9hZCBpcyBjYW5jZWxsZWQuCisgICAqCisgICAqIEBwYXJhbSBuZXdGaWxlS2V5IC0gdGhlIGtleSBvZiB0aGUgZmlsZSBlbnRyeSB0byByZW1vdmUuCisgICAqIEByZXR1cm4gLSBmYWxzZSBpZiB0aGVyZSBpcyBubyBlbnRyeSB3aXRoIHRoaXMga2V5IG9yIHVuYWJsZSB0byByZW1vdmUgdGhlIGVudHJ5CisgICAqLworICAvLyBUT0RPIC0gcmVmYWN0b3IgdG8gdGhyb3cgRXhjZXB0aW9uIHdoZW4gd3JpdGUgdG8gU2hhcmVkUHJlZmVyZW5jZXMgZmFpbHMKKyAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiByZW1vdmVGaWxlRW50cnkoTmV3RmlsZUtleSBuZXdGaWxlS2V5KSB7CisgICAgcmV0dXJuIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChuZXdGaWxlS2V5KSwKKyAgICAgICAgc2hhcmVkRmlsZSAtPiB7CisgICAgICAgICAgaWYgKHNoYXJlZEZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgLy8gVE9ETyhiLzEzMTE2NjkyNSk6IE1ERCBkdW1wIHNob3VsZCBub3QgdXNlIGxpdGUgcHJvdG8gdG9TdHJpbmcuCisgICAgICAgICAgICBMb2dVdGlsLmUoIiVzOiBObyBmaWxlIGVudHJ5IHdpdGgga2V5ICVzIiwgVEFHLCBuZXdGaWxlS2V5KTsKKyAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmYWxzZSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgVXJpIG9uRGV2aWNlVXJpID0KKyAgICAgICAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlLmdldEZpbGVOYW1lKCksCisgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LmdldENoZWNrc3VtKCksCisgICAgICAgICAgICAgICAgICBzaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQsCisgICAgICAgICAgICAgICAgICAvKiBhbmRyb2lkU2hhcmVkID0gKi8gZmFsc2UpOworICAgICAgICAgIGlmIChvbkRldmljZVVyaSAhPSBudWxsKSB7CisgICAgICAgICAgICBmaWxlRG93bmxvYWRlci5zdG9wRG93bmxvYWRpbmcob25EZXZpY2VVcmkpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS5yZW1vdmUobmV3RmlsZUtleSksCisgICAgICAgICAgICAgIHJlbW92ZVN1Y2Nlc3MgLT4geworICAgICAgICAgICAgICAgIGlmICghcmVtb3ZlU3VjY2VzcykgeworICAgICAgICAgICAgICAgICAgLy8gVE9ETyhiLzEzMTE2NjkyNSk6IE1ERCBkdW1wIHNob3VsZCBub3QgdXNlIGxpdGUgcHJvdG8gdG9TdHJpbmcuCisgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoIiVzOiBVbmFibGUgdG8gbW9kaWZ5IGZpbGUgc3Vic2NyaXB0aW9uIGZvciBrZXkgJXMiLCBUQUcsIG5ld0ZpbGVLZXkpOworICAgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpOworICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKioKKyAgICogQ2xlYXJzIGFsbCBzdG9yYWdlIHVzZWQgYnkgdGhlIFNoYXJlZEZpbGVNYW5hZ2VyIGFuZCBkZWxldGVzIGFsbCBmaWxlcyB0aGF0IGhhdmUgYmVlbgorICAgKiBkb3dubG9hZGVkIHRvIE1ERCdzIGRpcmVjdG9yeS4KKyAgICovCisgIC8vIFRPRE8oYi8xMjQwNzI3NTQpOiBDaGFuZ2UgdG8gcGFja2FnZSBwcml2YXRlIG9uY2UgYWxsIGNvZGUgaXMgcmVmYWN0b3JlZC4KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gY2xlYXIoKSB7CisgICAgLy8gSWYgc2RrIGlzIFIrLCB0cnkgcmVsZWFzZSBhbGwgbGVhc2VzIHRoYXQgdGhlIE1ERCBDbGllbnQgbWF5IGhhdmUgYWNxdWlyZWQuIFRoaXMKKyAgICAvLyBwcmV2ZW50cyBmcm9tIGxlYXZpbmcgem9tYmllIGZpbGVzIGluIHRoZSBibG9iIHN0b3JhZ2UuCisgICAgaWYgKFZFUlNJT04uU0RLX0lOVCA+PSBWRVJTSU9OX0NPREVTLlIpIHsKKyAgICAgIHJlbGVhc2VBbGxBbmRyb2lkU2hhcmVkRmlsZXMoKTsKKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIGZpbGVTdG9yYWdlLmRlbGV0ZVJlY3Vyc2l2ZWx5KERpcmVjdG9yeVV0aWwuZ2V0QmFzZURvd25sb2FkRGlyZWN0b3J5KGNvbnRleHQsIGluc3RhbmNlSWQpKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBzaWxlbnRGZWVkYmFjay5zZW5kKGUsICJGYWlsdXJlIHdoaWxlIGRlbGV0aW5nIG1kZCBzdG9yYWdlIGR1cmluZyBjbGVhciIpOworICAgIH0KKyAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgIH0KKworICBwcml2YXRlIHZvaWQgcmVsZWFzZUFsbEFuZHJvaWRTaGFyZWRGaWxlcygpIHsKKyAgICB0cnkgeworICAgICAgVXJpIGFsbExlYXNlc1VyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlN0b3JlQWxsTGVhc2VzVXJpKGNvbnRleHQpOworICAgICAgZmlsZVN0b3JhZ2UuZGVsZXRlRmlsZShhbGxMZWFzZXNVcmkpOworICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24gZSkgeworICAgICAgTG9nVXRpbC52KAorICAgICAgICAgICIlczogRmFpbGVkIHRvIHJlbGVhc2UgdGhlIGxlYXNlcyBpbiB0aGUgYW5kcm9pZCBzaGFyZWQgc3RvcmFnZS4iCisgICAgICAgICAgICAgICsgIiBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uIHdhcyB0aHJvd24iLAorICAgICAgICAgIFRBRyk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTG9nVXRpbC5lKGUsICIlczogRmFpbGVkIHRvIHJlbGVhc2UgdGhlIGxlYXNlcyBpbiB0aGUgYW5kcm9pZCBzaGFyZWQgc3RvcmFnZSIsIFRBRyk7CisgICAgICBldmVudExvZ2dlci5sb2dFdmVudFNhbXBsZWQoMCk7CisgICAgfQorICB9CisKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gY2FuY2VsRG93bmxvYWRBbmRDbGVhcigpIHsKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpLAorICAgICAgICBuZXdGaWxlS2V5TGlzdCAtPiB7CisgICAgICAgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PiBjYW5jZWxEb3dubG9hZEZ1dHVyZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgICB0cnkgeworICAgICAgICAgICAgLy8gQ2xlYXIgaXMgY2FsbGVkIGluIGNhc2Ugc29tZXRoaW5nIGZhaWxzIGFuZCB3ZSB3YW50IHRvIGNsZWFyIGFsbCBvZiBNREQgaW50ZXJuYWwKKyAgICAgICAgICAgIC8vIHN0b3JhZ2UuIENhdGNoaW5nIGFueSBleGNlcHRpb24gaW4gY2FuY2VsbGluZyBkb3dubG9hZHMgaXMgYmV0dGVyIHRoYW4gY2xlYXIgZmFpbGluZywKKyAgICAgICAgICAgIC8vIGFzIGl0IGNhbiBsZWF2ZSB0aGUgc3lzdGVtIGluIGEgbm9uLXJlY292ZXJhYmxlIHN0YXRlLgorICAgICAgICAgICAgZm9yIChOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgOiBuZXdGaWxlS2V5TGlzdCkgeworICAgICAgICAgICAgICBjYW5jZWxEb3dubG9hZEZ1dHVyZXMuYWRkKGNhbmNlbERvd25sb2FkKG5ld0ZpbGVLZXkpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgeworICAgICAgICAgICAgc2lsZW50RmVlZGJhY2suc2VuZChlLCAiRmFpbGVkIHRvIGNhbmNlbCBhbGwgZG93bmxvYWRzIGR1cmluZyBjbGVhciIpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gRnV0dXJlcy53aGVuQWxsQ29tcGxldGUoY2FuY2VsRG93bmxvYWRGdXR1cmVzKQorICAgICAgICAgICAgICAuY2FsbEFzeW5jKHRoaXM6OmNsZWFyLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjYW5jZWxEb3dubG9hZChOZXdGaWxlS2V5IG5ld0ZpbGVLZXkpIHsKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKG5ld0ZpbGVLZXkpLAorICAgICAgICBzaGFyZWRGaWxlIC0+IHsKKyAgICAgICAgICBpZiAoc2hhcmVkRmlsZSA9PSBudWxsKSB7CisgICAgICAgICAgICBMb2dVdGlsLmUoIiVzOiBVbmFibGUgdG8gcmVhZCBzaGFyZWRGaWxlIGZyb20gc2hhcmVkIHByZWZlcmVuY2VzLiIsIFRBRyk7CisgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUobmV3IFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uKCkpOworICAgICAgICAgIH0KKyAgICAgICAgICBpZiAoc2hhcmVkRmlsZS5nZXRGaWxlU3RhdHVzKCkgIT0gRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkgeworICAgICAgICAgICAgVXJpIG9uRGV2aWNlVXJpID0KKyAgICAgICAgICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE9uRGV2aWNlVXJpKAorICAgICAgICAgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgbmV3RmlsZUtleS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgICAgICAgICBzaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZCwKKyAgICAgICAgICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsgLy8gd2hpbGUgZG93bmxvYWRpbmcgYW5kcm9pZFNoYXJlZCBpcyBhbHdheXMgZmFsc2UKKyAgICAgICAgICAgIGlmIChvbkRldmljZVVyaSAhPSBudWxsKSB7CisgICAgICAgICAgICAgIGZpbGVEb3dubG9hZGVyLnN0b3BEb3dubG9hZGluZyhvbkRldmljZVVyaSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqIER1bXBzIHRoZSBjdXJyZW50IGludGVybmFsIHN0YXRlIG9mIHRoZSBTaGFyZWRGaWxlTWFuYWdlci4gKi8KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZHVtcChmaW5hbCBQcmludFdyaXRlciB3cml0ZXIpIHsKKyAgICB3cml0ZXIucHJpbnRsbigiPT09PSBNRERfU0hBUkVEX0ZJTEVTID09PT0iKTsKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpLAorICAgICAgICBhbGxGaWxlS2V5cyAtPiB7CisgICAgICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiB3cml0ZUZpbGVzRnV0dXJlID0gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgIGZvciAoTmV3RmlsZUtleSBuZXdGaWxlS2V5IDogYWxsRmlsZUtleXMpIHsKKyAgICAgICAgICAgIHdyaXRlRmlsZXNGdXR1cmUgPQorICAgICAgICAgICAgICAgIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgIHdyaXRlRmlsZXNGdXR1cmUsCisgICAgICAgICAgICAgICAgICAgIHZvaWRBcmcgLT4KKyAgICAgICAgICAgICAgICAgICAgICAgIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKG5ld0ZpbGVLZXkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGUgLT4geworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNoYXJlZEZpbGUgPT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFVuYWJsZSB0byByZWFkIHNoYXJlZEZpbGUgZnJvbSBzaGFyZWQgcHJlZmVyZW5jZXMuIiwgVEFHKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyhiLzEzMTE2NjkyNSk6IE1ERCBkdW1wIHNob3VsZCBub3QgdXNlIGxpdGUgcHJvdG8gdG9TdHJpbmcuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIuZm9ybWF0KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGaWxlS2V5OiAlc1xuRmlsZU5hbWU6ICVzXG5TaGFyZWRGaWxlOiAlc1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LCBzaGFyZWRGaWxlLmdldEZpbGVOYW1lKCksIHNoYXJlZEZpbGUudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hhcmVkRmlsZS5nZXRBbmRyb2lkU2hhcmVkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmZvcm1hdCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDaGVja3N1bSBBbmRyb2lkLXNoYXJlZCBmaWxlOiAlc1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVyaSBzZXJpYWxpemVkVXJpID0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZS5nZXRGaWxlTmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGFuZHJvaWRTaGFyZWQgPSAqLyBmYWxzZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZXJpYWxpemVkVXJpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIuZm9ybWF0KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2hlY2tzdW0gZG93bmxvYWRlZCBmaWxlOiAlc1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmlsZVZhbGlkYXRvci5jb21wdXRlU2hhMURpZ2VzdChmaWxlU3RvcmFnZSwgc2VyaWFsaXplZFVyaSkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKSwKKyAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiB3cml0ZUZpbGVzRnV0dXJlOworICAgICAgICB9LAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9TaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbi5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9TaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbi5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhNGJiN2MKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL1NoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uLmphdmEKQEAgLTAsMCArMSwxOSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWw7CisKKy8qKiBUaHJvd24gd2hlbiBhIGZpbGUgaXMgcmVhZCBmcm9tIHNoYXJlZGZpbGVzIHRoYXQgaXMgbm90IHByZXNlbnQuICovCitwdWJsaWMgY2xhc3MgU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24gZXh0ZW5kcyBFeGNlcHRpb24ge30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvU2hhcmVkRmlsZXNNZXRhZGF0YS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9TaGFyZWRGaWxlc01ldGFkYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzVlNjAxOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvU2hhcmVkRmlsZXNNZXRhZGF0YS5qYXZhCkBAIC0wLDAgKzEsMTQ1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbDsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlNpbGVudEZlZWRiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuRmlsZUdyb3VwVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsLkFsbG93ZWRSZWFkZXJzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGVsdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uTmV3RmlsZUtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLlNoYXJlZEZpbGU7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKiBTdG9yZXMgYW5kIHByb3ZpZGVzIGFjY2VzcyB0byBzaGFyZWQgZmlsZSBtZXRhZGF0YS4gKi8KK3B1YmxpYyBpbnRlcmZhY2UgU2hhcmVkRmlsZXNNZXRhZGF0YSB7CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBOZXdGaWxlS2V5IG9iamVjdCBmcm9tIHRoZSBnaXZlbiBEYXRhRmlsZSwgYmFzZWQgb24gdGhlIGN1cnJlbnQgRmlsZUtleVZlcnNpb24uCisgICAqCisgICAqIEBwYXJhbSBmaWxlIC0gYSBEYXRhRmlsZSB3aG9zZSBrZXkgeW91IHdpc2ggdG8gY29uc3RydWN0LgorICAgKiBAcGFyYW0gYWxsb3dlZFJlYWRlcnNFbnVtIC0ge0BsaW5rIEFsbG93ZWRSZWFkZXJzfSBzaWduaWZpZXMgd2hvIGhhcyBhY2Nlc3MgdG8gdGhlIGZpbGUuCisgICAqLworICAvLyBUT0RPKGIvMTI3NDkwOTc4KTogUmVwbGFjZSBhbGwgdXNhZ2Ugb2Yge0Bjb2RlICNjcmVhdGVLZXlGcm9tRGF0YUZpbGV9IG9uY2UgYWxsIHVzZXJzIGhhdmUKKyAgLy8gYmVlbiBtaWdyYXRlZCB0byB1c2Ugb25seSB0aGUgbm9uLWRlcHJlY2F0ZWQgZmllbGRzIGZyb20gdGhlIHJldHVybmVkIHZhbHVlLgorICBwdWJsaWMgc3RhdGljIE5ld0ZpbGVLZXkgY3JlYXRlS2V5RnJvbURhdGFGaWxlRm9yQ3VycmVudFZlcnNpb24oCisgICAgICBDb250ZXh0IGNvbnRleHQsCisgICAgICBEYXRhRmlsZSBmaWxlLAorICAgICAgQWxsb3dlZFJlYWRlcnMgYWxsb3dlZFJlYWRlcnNFbnVtLAorICAgICAgU2lsZW50RmVlZGJhY2sgc2lsZW50RmVlZGJhY2spIHsKKyAgICBOZXdGaWxlS2V5LkJ1aWxkZXIgbmV3RmlsZUtleUJ1aWxkZXIgPSBOZXdGaWxlS2V5Lm5ld0J1aWxkZXIoKTsKKyAgICBTdHJpbmcgY2hlY2tzdW0gPSBGaWxlR3JvdXBVdGlsLmdldEZpbGVDaGVja3N1bShmaWxlKTsKKworICAgIHN3aXRjaCAoTWlncmF0aW9ucy5nZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBzaWxlbnRGZWVkYmFjaykpIHsKKyAgICAgIGNhc2UgTkVXX0ZJTEVfS0VZOgorICAgICAgICBuZXdGaWxlS2V5QnVpbGRlcgorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoZmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkpCisgICAgICAgICAgICAuc2V0Qnl0ZVNpemUoZmlsZS5nZXRCeXRlU2l6ZSgpKQorICAgICAgICAgICAgLnNldENoZWNrc3VtKGNoZWNrc3VtKQorICAgICAgICAgICAgLnNldEFsbG93ZWRSZWFkZXJzKGFsbG93ZWRSZWFkZXJzRW51bSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBBRERfRE9XTkxPQURfVFJBTlNGT1JNOgorICAgICAgICBuZXdGaWxlS2V5QnVpbGRlcgorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoZmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkpCisgICAgICAgICAgICAuc2V0Qnl0ZVNpemUoZmlsZS5nZXRCeXRlU2l6ZSgpKQorICAgICAgICAgICAgLnNldENoZWNrc3VtKGNoZWNrc3VtKQorICAgICAgICAgICAgLnNldEFsbG93ZWRSZWFkZXJzKGFsbG93ZWRSZWFkZXJzRW51bSk7CisgICAgICAgIGlmIChmaWxlLmhhc0Rvd25sb2FkVHJhbnNmb3JtcygpKSB7CisgICAgICAgICAgbmV3RmlsZUtleUJ1aWxkZXIuc2V0RG93bmxvYWRUcmFuc2Zvcm1zKGZpbGUuZ2V0RG93bmxvYWRUcmFuc2Zvcm1zKCkpOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVU0VfQ0hFQ0tTVU1fT05MWToKKyAgICAgICAgbmV3RmlsZUtleUJ1aWxkZXIuc2V0Q2hlY2tzdW0oY2hlY2tzdW0pLnNldEFsbG93ZWRSZWFkZXJzKGFsbG93ZWRSZWFkZXJzRW51bSk7CisgICAgfQorCisgICAgcmV0dXJuIG5ld0ZpbGVLZXlCdWlsZGVyLmJ1aWxkKCk7CisgIH0KKworICAvKioKKyAgICogQ3JlYXRlcyBhIE5ld0ZpbGVLZXkgb2JqZWN0IGZyb20gdGhlIGdpdmVuIERhdGFGaWxlLgorICAgKgorICAgKiBAcGFyYW0gZmlsZSAtIGEgRGF0YUZpbGUgd2hvc2Uga2V5IHlvdSB3aXNoIHRvIGNvbnN0cnVjdC4KKyAgICogQHBhcmFtIGFsbG93ZWRSZWFkZXJzRW51bSAtIHtAbGluayBBbGxvd2VkUmVhZGVyc30gc2lnbmlmaWVzIHdobyBoYXMgYWNjZXNzIHRvIHRoZSBmaWxlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBOZXdGaWxlS2V5IGNyZWF0ZUtleUZyb21EYXRhRmlsZShEYXRhRmlsZSBmaWxlLCBBbGxvd2VkUmVhZGVycyBhbGxvd2VkUmVhZGVyc0VudW0pIHsKKyAgICBOZXdGaWxlS2V5LkJ1aWxkZXIgbmV3RmlsZUtleUJ1aWxkZXIgPQorICAgICAgICBOZXdGaWxlS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoZmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkpCisgICAgICAgICAgICAuc2V0Qnl0ZVNpemUoZmlsZS5nZXRCeXRlU2l6ZSgpKQorICAgICAgICAgICAgLnNldENoZWNrc3VtKEZpbGVHcm91cFV0aWwuZ2V0RmlsZUNoZWNrc3VtKGZpbGUpKQorICAgICAgICAgICAgLnNldEFsbG93ZWRSZWFkZXJzKGFsbG93ZWRSZWFkZXJzRW51bSk7CisgICAgaWYgKGZpbGUuaGFzRG93bmxvYWRUcmFuc2Zvcm1zKCkpIHsKKyAgICAgIG5ld0ZpbGVLZXlCdWlsZGVyLnNldERvd25sb2FkVHJhbnNmb3JtcyhmaWxlLmdldERvd25sb2FkVHJhbnNmb3JtcygpKTsKKyAgICB9CisgICAgcmV0dXJuIG5ld0ZpbGVLZXlCdWlsZGVyLmJ1aWxkKCk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyBhIHRlbXBvcmFyeSBGaWxlS2V5IHRoYXQgY2FuIGJlIHVzZWQgdG8gaW50ZXJhY3Qgd2l0aCB0aGUgTWRkRmlsZURvd25sb2FkZXIgdG8gZG93bmxvYWQKKyAgICogYSBkZWx0YSBmaWxlLgorICAgKgorICAgKiBAcGFyYW0gZGVsdGFGaWxlIC0gYSBEZWx0YUZpbGUgd2hvc2Uga2V5IHlvdSB3aXNoIHRvIGNvbnN0cnVjdC4KKyAgICogQHBhcmFtIGFsbG93ZWRSZWFkZXJzRW51bSAtIHtAbGluayBBbGxvd2VkUmVhZGVyc30gc2lnbmlmaWVzIHdobyBoYXMgYWNjZXNzIHRvIHRoZSBmaWxlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBOZXdGaWxlS2V5IGNyZWF0ZVRlbXBLZXlGb3JEZWx0YUZpbGUoCisgICAgICBEZWx0YUZpbGUgZGVsdGFGaWxlLCBBbGxvd2VkUmVhZGVycyBhbGxvd2VkUmVhZGVyc0VudW0pIHsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBOZXdGaWxlS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoZGVsdGFGaWxlLmdldFVybFRvRG93bmxvYWQoKSkKKyAgICAgICAgICAgIC5zZXRCeXRlU2l6ZShkZWx0YUZpbGUuZ2V0Qnl0ZVNpemUoKSkKKyAgICAgICAgICAgIC5zZXRDaGVja3N1bShkZWx0YUZpbGUuZ2V0Q2hlY2tzdW0oKSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVycyhhbGxvd2VkUmVhZGVyc0VudW0pCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHJldHVybiBuZXdGaWxlS2V5OworICB9CisKKyAgLyoqCisgICAqIE1ha2VzIGFueSBjaGFuZ2VzIHRoYXQgc2hvdWxkIGJlIG1hZGUgYmVmb3JlIGFjY2Vzc2luZyB0aGUgaW50ZXJuYWwgc3RhdGUgb2YgdGhpcyBzdG9yZS4KKyAgICoKKyAgICogPHA+T3RoZXIgbWV0aG9kcyBpbiB0aGlzIGNsYXNzIGRvIG5vdCBjYWxsIG9yIGNoZWNrIGlmIHRoaXMgbWV0aG9kIHdhcyBhbHJlYWR5IGNhbGxlZCBiZWZvcmUKKyAgICogdHJ5aW5nIHRvIGFjY2VzcyBpbnRlcm5hbCBzdGF0ZS4gSXQgaXMgZXhwZWN0ZWQgZnJvbSB0aGUgY2FsbGVyIHRvIGNhbGwgdGhpcyBiZWZvcmUgYW55dGhpbmcKKyAgICogZWxzZS4KKyAgICoKKyAgICogQHJldHVybiBhIGZ1dHVyZSB0aGF0IHJlc29sdmVzIHRvIGZhbHNlIGlmIGluaXQgZmFpbGVkLCBzaWduYWxsaW5nIGNhbGxlciB0byBjbGVhciBpbnRlcm5hbAorICAgKiAgICAgc3RvcmFnZS4KKyAgICovCisgIC8vIFRPRE8oYi8xMjQwNzI3NTQpOiBDaGFuZ2UgdG8gcGFja2FnZSBwcml2YXRlIG9uY2UgYWxsIGNvZGUgaXMgcmVmYWN0b3JlZC4KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gaW5pdCgpOworCisgIC8qKiBSZXR1cm4ge0BsaW5rIFNoYXJlZEZpbGV9IGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4ga2V5LiAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxTaGFyZWRGaWxlPiByZWFkKE5ld0ZpbGVLZXkgbmV3RmlsZUtleSk7CisKKyAgLyoqCisgICAqIE1hcCB0aGUga2V5ICJuZXdGaWxlS2V5IiB0byB0aGUgdmFsdWUgInNoYXJlZEZpbGUiLiBSZXR1cm5zIGEgZnV0dXJlIHJlc29sdmluZyB0byB0cnVlIGlmIHRoZQorICAgKiBvcGVyYXRpb24gc3VjY2VlZHMsIGZhbHNlIGlmIGl0IGZhaWxzLgorICAgKi8KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gd3JpdGUoTmV3RmlsZUtleSBuZXdGaWxlS2V5LCBTaGFyZWRGaWxlIHNoYXJlZEZpbGUpOworCisgIC8qKgorICAgKiBSZW1vdmUgdGhlIHZhbHVlIHN0b3JlZCBhdCAibmV3RmlsZUtleSIuIFJldHVybnMgYSBmdXR1cmUgcmVzb2x2aW5nIHRvIHRydWUgaWYgdGhlIG9wZXJhdGlvbgorICAgKiBzdWNjZWVkcywgZmFsc2UgaWYgaXQgZmFpbHMuCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiByZW1vdmUoTmV3RmlsZUtleSBuZXdGaWxlS2V5KTsKKworICAvKiogUmV0dXJuIGFsbCBrZXlzIGluIHRoZSBzdG9yZS4gKi8KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8TGlzdDxOZXdGaWxlS2V5Pj4gZ2V0QWxsRmlsZUtleXMoKTsKKworICAvKiogQ2xlYXIgdGhlIHN0b3JlLiAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjbGVhcigpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9TaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9TaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjNDA3ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL1NoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhLmphdmEKQEAgLTAsMCArMSwyODggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LlNoYXJlZFByZWZlcmVuY2VzOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGFuZHJvaWR4LmFubm90YXRpb24uVmlzaWJsZUZvclRlc3Rpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuU2lsZW50RmVlZGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGltZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5hbm5vdGF0aW9ucy5JbnN0YW5jZUlkOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmFubm90YXRpb25zLlNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuRmlsZUdyb3VwVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLkZpbGVHcm91cHNNZXRhZGF0YVV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5GaWxlR3JvdXBzTWV0YWRhdGFVdGlsLkdyb3VwS2V5RGVzZXJpYWxpemF0aW9uRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuUHJvdG9MaXRlVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLlNoYXJlZFByZWZlcmVuY2VzVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DaGVja1JldHVyblZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uR3JvdXBLZXk7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleVByb3BlcnRpZXM7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmlvLkJ5dGVCdWZmZXI7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZheC5pbmplY3QuSW5qZWN0OworaW1wb3J0IG9yZy5jaGVja2VyZnJhbWV3b3JrLmNoZWNrZXIubnVsbG5lc3MuY29tcGF0cXVhbC5OdWxsYWJsZVR5cGU7CisKKy8qKiBTdG9yZXMgYW5kIHByb3ZpZGVzIGFjY2VzcyB0byBmaWxlIGdyb3VwIG1ldGFkYXRhIHVzaW5nIFNoYXJlZFByZWZlcmVuY2VzLiAqLworQENoZWNrUmV0dXJuVmFsdWUKK3B1YmxpYyBmaW5hbCBjbGFzcyBTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YSBpbXBsZW1lbnRzIEZpbGVHcm91cHNNZXRhZGF0YSB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YSI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfRklMRV9HUk9VUFMgPSBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLk1ERF9GSUxFX0dST1VQUzsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE1ERF9GSUxFX0dST1VQX0tFWV9QUk9QRVJUSUVTID0KKyAgICAgIEZpbGVHcm91cHNNZXRhZGF0YVV0aWwuTUREX0ZJTEVfR1JPVVBfS0VZX1BST1BFUlRJRVM7CisKKyAgLy8gVE9ETyhiLzE0NDAzMzE2Myk6IE1pZ3JhdGUgdGhlIEdhcmJhZ2UgQ29sbGVjdG9yIEZpbGUgdG8gUERTLgorICBAVmlzaWJsZUZvclRlc3Rpbmcgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfR0FSQkFHRV9DT0xMRUNUSU9OX0ZJTEUgPSAiZ21zX2ljaW5nX21kZF9nYXJiYWdlX2ZpbGUiOworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIGZpbmFsIFRpbWVTb3VyY2UgdGltZVNvdXJjZTsKKyAgcHJpdmF0ZSBmaW5hbCBTaWxlbnRGZWVkYmFjayBzaWxlbnRGZWVkYmFjazsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQ7CisgIHByaXZhdGUgZmluYWwgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKworICBASW5qZWN0CisgIFNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhKAorICAgICAgQEFwcGxpY2F0aW9uQ29udGV4dCBDb250ZXh0IGNvbnRleHQsCisgICAgICBUaW1lU291cmNlIHRpbWVTb3VyY2UsCisgICAgICBTaWxlbnRGZWVkYmFjayBzaWxlbnRGZWVkYmFjaywKKyAgICAgIEBJbnN0YW5jZUlkIE9wdGlvbmFsPFN0cmluZz4gaW5zdGFuY2VJZCwKKyAgICAgIEBTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpIHsKKyAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OworICAgIHRoaXMudGltZVNvdXJjZSA9IHRpbWVTb3VyY2U7CisgICAgdGhpcy5zaWxlbnRGZWVkYmFjayA9IHNpbGVudEZlZWRiYWNrOworICAgIHRoaXMuaW5zdGFuY2VJZCA9IGluc3RhbmNlSWQ7CisgICAgdGhpcy5zZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yID0gc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBpbml0KCkgeworICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxATnVsbGFibGVUeXBlIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gcmVhZChHcm91cEtleSBncm91cEtleSkgeworICAgIFN0cmluZyBzZXJpYWxpemVkR3JvdXBLZXkgPSBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLmdldFNlcmlhbGl6ZWRHcm91cEtleShncm91cEtleSwgY29udGV4dCk7CisKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcyhjb250ZXh0LCBNRERfRklMRV9HUk9VUFMsIGluc3RhbmNlSWQpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwucmVhZFByb3RvKHByZWZzLCBzZXJpYWxpemVkR3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5wYXJzZXIoKSk7CisKKyAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmlsZUdyb3VwKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiB3cml0ZShHcm91cEtleSBncm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCkgeworICAgIFN0cmluZyBzZXJpYWxpemVkR3JvdXBLZXkgPSBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLmdldFNlcmlhbGl6ZWRHcm91cEtleShncm91cEtleSwgY29udGV4dCk7CisKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcyhjb250ZXh0LCBNRERfRklMRV9HUk9VUFMsIGluc3RhbmNlSWQpOworICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSgKKyAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLndyaXRlUHJvdG8ocHJlZnMsIHNlcmlhbGl6ZWRHcm91cEtleSwgZmlsZUdyb3VwKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gcmVtb3ZlKEdyb3VwS2V5IGdyb3VwS2V5KSB7CisgICAgU3RyaW5nIHNlcmlhbGl6ZWRHcm91cEtleSA9IEZpbGVHcm91cHNNZXRhZGF0YVV0aWwuZ2V0U2VyaWFsaXplZEdyb3VwS2V5KGdyb3VwS2V5LCBjb250ZXh0KTsKKworICAgIFNoYXJlZFByZWZlcmVuY2VzIHByZWZzID0KKyAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKGNvbnRleHQsIE1ERF9GSUxFX0dST1VQUywgaW5zdGFuY2VJZCk7CisgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKFNoYXJlZFByZWZlcmVuY2VzVXRpbC5yZW1vdmVQcm90byhwcmVmcywgc2VyaWFsaXplZEdyb3VwS2V5KSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8QE51bGxhYmxlVHlwZSBHcm91cEtleVByb3BlcnRpZXM+IHJlYWRHcm91cEtleVByb3BlcnRpZXMoCisgICAgICBHcm91cEtleSBncm91cEtleSkgeworICAgIFN0cmluZyBzZXJpYWxpemVkR3JvdXBLZXkgPSBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLmdldFNlcmlhbGl6ZWRHcm91cEtleShncm91cEtleSwgY29udGV4dCk7CisKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcygKKyAgICAgICAgICAgIGNvbnRleHQsIE1ERF9GSUxFX0dST1VQX0tFWV9QUk9QRVJUSUVTLCBpbnN0YW5jZUlkKTsKKyAgICBHcm91cEtleVByb3BlcnRpZXMgZ3JvdXBLZXlQcm9wZXJ0aWVzID0KKyAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLnJlYWRQcm90byhwcmVmcywgc2VyaWFsaXplZEdyb3VwS2V5LCBHcm91cEtleVByb3BlcnRpZXMucGFyc2VyKCkpOworCisgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGdyb3VwS2V5UHJvcGVydGllcyk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gd3JpdGVHcm91cEtleVByb3BlcnRpZXMoCisgICAgICBHcm91cEtleSBncm91cEtleSwgR3JvdXBLZXlQcm9wZXJ0aWVzIGdyb3VwS2V5UHJvcGVydGllcykgeworICAgIFN0cmluZyBzZXJpYWxpemVkR3JvdXBLZXkgPSBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLmdldFNlcmlhbGl6ZWRHcm91cEtleShncm91cEtleSwgY29udGV4dCk7CisKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcygKKyAgICAgICAgICAgIGNvbnRleHQsIE1ERF9GSUxFX0dST1VQX0tFWV9QUk9QRVJUSUVTLCBpbnN0YW5jZUlkKTsKKyAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoCisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC53cml0ZVByb3RvKHByZWZzLCBzZXJpYWxpemVkR3JvdXBLZXksIGdyb3VwS2V5UHJvcGVydGllcykpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPExpc3Q8R3JvdXBLZXk+PiBnZXRBbGxHcm91cEtleXMoKSB7CisgICAgTGlzdDxHcm91cEtleT4gZ3JvdXBLZXlMaXN0ID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMgcHJlZnMgPQorICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoY29udGV4dCwgTUREX0ZJTEVfR1JPVVBTLCBpbnN0YW5jZUlkKTsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcy5FZGl0b3IgZWRpdG9yID0gbnVsbDsKKyAgICBmb3IgKFN0cmluZyBzZXJpYWxpemVkR3JvdXBLZXkgOiBwcmVmcy5nZXRBbGwoKS5rZXlTZXQoKSkgeworICAgICAgdHJ5IHsKKyAgICAgICAgR3JvdXBLZXkgbmV3RmlsZUtleSA9IEZpbGVHcm91cHNNZXRhZGF0YVV0aWwuZGVzZXJpYWxpemVHcm91cEtleShzZXJpYWxpemVkR3JvdXBLZXkpOworICAgICAgICBncm91cEtleUxpc3QuYWRkKG5ld0ZpbGVLZXkpOworICAgICAgfSBjYXRjaCAoR3JvdXBLZXlEZXNlcmlhbGl6YXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICBMb2dVdGlsLmUoZSwgIkZhaWxlZCB0byBkZXNlcmlhbGl6ZSBncm91cEtleToiICsgc2VyaWFsaXplZEdyb3VwS2V5KTsKKyAgICAgICAgc2lsZW50RmVlZGJhY2suc2VuZChlLCAiRmFpbGVkIHRvIGRlc2VyaWFsaXplIGdyb3VwS2V5Iik7CisgICAgICAgIC8vIFRPRE8oYi8xMjg4NTAwMDApOiBSZWZhY3RvciB0aGlzIGNvZGUgdG8gYSBzaW5nbGUgY29ycnVwdGlvbiBoYW5kbGluZyB0YXNrIGR1cmluZworICAgICAgICAvLyBtYWludGVuYW5jZS4KKyAgICAgICAgLy8gUmVtb3ZlIHRoZSBjb3JydXB0ZWQgZmlsZSBtZXRhZGF0YSBhbmQgdGhlIHJlbGF0ZWQgU2hhcmVkRmlsZSBtZXRhZGF0YSB3aWxsIGJlIGRlbGV0ZWQKKyAgICAgICAgLy8gaW4gbmV4dCBtYWludGVuYW5jZSB0YXNrLgorICAgICAgICBpZiAoZWRpdG9yID09IG51bGwpIHsKKyAgICAgICAgICBlZGl0b3IgPSBwcmVmcy5lZGl0KCk7CisgICAgICAgIH0KKyAgICAgICAgZWRpdG9yLnJlbW92ZShzZXJpYWxpemVkR3JvdXBLZXkpOworICAgICAgICBMb2dVdGlsLmQoIiVzOiBEZWxldGluZyBudWxsIGZpbGUgZ3JvdXAgIiwgVEFHKTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgfQorICAgIGlmIChlZGl0b3IgIT0gbnVsbCkgeworICAgICAgZWRpdG9yLmNvbW1pdCgpOworICAgIH0KKyAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZ3JvdXBLZXlMaXN0KTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxMaXN0PFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4+PiBnZXRBbGxGcmVzaEdyb3VwcygpIHsKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgZ2V0QWxsR3JvdXBLZXlzKCksCisgICAgICAgIGdyb3VwS2V5TGlzdCAtPiB7CisgICAgICAgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPEBOdWxsYWJsZVR5cGUgRGF0YUZpbGVHcm91cEludGVybmFsPj4gZ3JvdXBSZWFkRnV0dXJlcyA9CisgICAgICAgICAgICAgIG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICAgIGZvciAoR3JvdXBLZXkga2V5IDogZ3JvdXBLZXlMaXN0KSB7CisgICAgICAgICAgICBncm91cFJlYWRGdXR1cmVzLmFkZChyZWFkKGtleSkpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gRnV0dXJlcy53aGVuQWxsQ29tcGxldGUoZ3JvdXBSZWFkRnV0dXJlcykKKyAgICAgICAgICAgICAgLmNhbGxBc3luYygKKyAgICAgICAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiByZXRyaWV2ZWRHcm91cHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBncm91cEtleUxpc3Quc2l6ZSgpOyBpKyspIHsKKyAgICAgICAgICAgICAgICAgICAgICBHcm91cEtleSBrZXkgPSBncm91cEtleUxpc3QuZ2V0KGkpOworICAgICAgICAgICAgICAgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBncm91cCA9IEZ1dHVyZXMuZ2V0RG9uZShncm91cFJlYWRGdXR1cmVzLmdldChpKSk7CisgICAgICAgICAgICAgICAgICAgICAgaWYgKGdyb3VwID09IG51bGwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICByZXRyaWV2ZWRHcm91cHMuYWRkKFBhaXIuY3JlYXRlKGtleSwgZ3JvdXApKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUocmV0cmlldmVkR3JvdXBzKTsKKyAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gcmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoTGlzdDxHcm91cEtleT4ga2V5cykgeworICAgIFNoYXJlZFByZWZlcmVuY2VzIHByZWZzID0KKyAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKGNvbnRleHQsIE1ERF9GSUxFX0dST1VQUywgaW5zdGFuY2VJZCk7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMuRWRpdG9yIGVkaXRvciA9IHByZWZzLmVkaXQoKTsKKyAgICBmb3IgKEdyb3VwS2V5IGtleSA6IGtleXMpIHsKKyAgICAgIExvZ1V0aWwuZCgiJXM6IFJlbW92aW5nIGdyb3VwICVzICVzIiwgVEFHLCBrZXkuZ2V0R3JvdXBOYW1lKCksIGtleS5nZXRPd25lclBhY2thZ2UoKSk7CisgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwucmVtb3ZlUHJvdG8oZWRpdG9yLCBrZXkpOworICAgIH0KKyAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZWRpdG9yLmNvbW1pdCgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxMaXN0PERhdGFGaWxlR3JvdXBJbnRlcm5hbD4+IGdldEFsbFN0YWxlR3JvdXBzKCkgeworICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSgKKyAgICAgICAgRmlsZUdyb3Vwc01ldGFkYXRhVXRpbC5nZXRBbGxTdGFsZUdyb3VwcygKKyAgICAgICAgICAgIEZpbGVHcm91cHNNZXRhZGF0YVV0aWwuZ2V0R2FyYmFnZUNvbGxlY3RvckZpbGUoY29udGV4dCwgaW5zdGFuY2VJZCkpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiBhZGRTdGFsZUdyb3VwKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXApIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBBZGRpbmcgZmlsZSBncm91cCAlcyIsIFRBRywgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKworICAgIGxvbmcgY3VycmVudFRpbWVTZWNvbmRzID0gdGltZVNvdXJjZS5jdXJyZW50VGltZU1pbGxpcygpIC8gMTAwMDsKKyAgICBmaWxlR3JvdXAgPQorICAgICAgICBGaWxlR3JvdXBVdGlsLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUoCisgICAgICAgICAgICBmaWxlR3JvdXAsIGN1cnJlbnRUaW1lU2Vjb25kcyArIGZpbGVHcm91cC5nZXRTdGFsZUxpZmV0aW1lU2VjcygpKTsKKworICAgIExpc3Q8RGF0YUZpbGVHcm91cEludGVybmFsPiBmaWxlR3JvdXBzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgZmlsZUdyb3Vwcy5hZGQoZmlsZUdyb3VwKTsKKworICAgIHJldHVybiB3cml0ZVN0YWxlR3JvdXBzKGZpbGVHcm91cHMpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IHdyaXRlU3RhbGVHcm91cHMoTGlzdDxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGZpbGVHcm91cHMpIHsKKyAgICBGaWxlIGdhcmJhZ2VDb2xsZWN0b3JGaWxlID0gZ2V0R2FyYmFnZUNvbGxlY3RvckZpbGUoKTsKKyAgICBGaWxlT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbTsKKyAgICB0cnkgeworICAgICAgb3V0cHV0U3RyZWFtID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZ2FyYmFnZUNvbGxlY3RvckZpbGUsIC8qIGFwcGVuZCAqLyB0cnVlKTsKKyAgICB9IGNhdGNoIChGaWxlTm90Rm91bmRFeGNlcHRpb24gZSkgeworICAgICAgTG9nVXRpbC5lKCJGaWxlICVzIG5vdCBmb3VuZCB3aGlsZSB3cml0aW5nLiIsIGdhcmJhZ2VDb2xsZWN0b3JGaWxlLmdldEFic29sdXRlUGF0aCgpKTsKKyAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmYWxzZSk7CisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIC8vIHRhaWxfY3JjID09IGZhbHNlLCBtZWFucyB0aGF0IGVhY2ggbWVzc2FnZSBoYXMgaXRzIG93biBjcmMKKyAgICAgIEJ5dGVCdWZmZXIgYnVmID0gUHJvdG9MaXRlVXRpbC5kdW1wSW50b0J1ZmZlcihmaWxlR3JvdXBzLCBmYWxzZSAvKnRhaWwgY3JjKi8pOworICAgICAgaWYgKGJ1ZiAhPSBudWxsKSB7CisgICAgICAgIG91dHB1dFN0cmVhbS5nZXRDaGFubmVsKCkud3JpdGUoYnVmKTsKKyAgICAgIH0KKyAgICAgIG91dHB1dFN0cmVhbS5jbG9zZSgpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExvZ1V0aWwuZSgiSU9FeGNlcHRpb24gb2NjdXJyZWQgd2hpbGUgd3JpdGluZyBmaWxlIGdyb3Vwcy4iKTsKKyAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmYWxzZSk7CisgICAgfQorICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKTsKKyAgfQorCisgIEBWaXNpYmxlRm9yVGVzdGluZworICBGaWxlIGdldEdhcmJhZ2VDb2xsZWN0b3JGaWxlKCkgeworICAgIHJldHVybiBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLmdldEdhcmJhZ2VDb2xsZWN0b3JGaWxlKGNvbnRleHQsIGluc3RhbmNlSWQpOworICB9CisKKyAgLy8gVE9ETyhiLzEyNDA3Mjc1NCk6IENoYW5nZSB0byBwYWNrYWdlIHByaXZhdGUgb25jZSBhbGwgY29kZSBpcyByZWZhY3RvcmVkLgorICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVtb3ZlQWxsU3RhbGVHcm91cHMoKSB7CisgICAgZ2V0R2FyYmFnZUNvbGxlY3RvckZpbGUoKS5kZWxldGUoKTsKKyAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gY2xlYXIoKSB7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMgcHJlZnMgPQorICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoY29udGV4dCwgTUREX0ZJTEVfR1JPVVBTLCBpbnN0YW5jZUlkKTsKKyAgICBwcmVmcy5lZGl0KCkuY2xlYXIoKS5jb21taXQoKTsKKworICAgIFNoYXJlZFByZWZlcmVuY2VzIGFjdGl2YXRlZEdyb3VwUHJlZnMgPQorICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoCisgICAgICAgICAgICBjb250ZXh0LCBNRERfRklMRV9HUk9VUF9LRVlfUFJPUEVSVElFUywgaW5zdGFuY2VJZCk7CisgICAgYWN0aXZhdGVkR3JvdXBQcmVmcy5lZGl0KCkuY2xlYXIoKS5jb21taXQoKTsKKworICAgIHJldHVybiByZW1vdmVBbGxTdGFsZUdyb3VwcygpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL1NoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9TaGFyZWRQcmVmZXJlbmNlc1NoYXJlZEZpbGVzTWV0YWRhdGEuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NjJhYzViCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9TaGFyZWRQcmVmZXJlbmNlc1NoYXJlZEZpbGVzTWV0YWRhdGEuamF2YQpAQCAtMCwwICsxLDMyOSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWw7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWRkQ29uc3RhbnRzLlNQTElUX0NIQVI7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuTUREX1NIQVJFRF9GSUxFUzsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5TaGFyZWRQcmVmZXJlbmNlczsKK2ltcG9ydCBhbmRyb2lkeC5hbm5vdGF0aW9uLlZpc2libGVGb3JUZXN0aW5nOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkZsYWdzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlNpbGVudEZlZWRiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmFubm90YXRpb25zLkluc3RhbmNlSWQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWlncmF0aW9ucy5GaWxlS2V5VmVyc2lvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5TaGFyZWRGaWxlc01ldGFkYXRhVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLlNoYXJlZEZpbGVzTWV0YWRhdGFVdGlsLkZpbGVLZXlEZXNlcmlhbGl6YXRpb25FeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5TaGFyZWRQcmVmZXJlbmNlc1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlNwbGl0dGVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DaGVja1JldHVyblZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uTmV3RmlsZUtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLlNoYXJlZEZpbGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZheC5pbmplY3QuSW5qZWN0OworCisvKioKKyAqIFN0b3JlcyBhbmQgcHJvdmlkZXMgYWNjZXNzIHRvIHNoYXJlZCBmaWxlIG1ldGFkYXRhIHVzaW5nIFNoYXJlZFByZWZlcmVuY2VzLgorICoKKyAqIDxwPlN5bmNocm9uaXphdGlvbiBvbiB0aGlzIGNsYXNzIGRlcGVuZHMgb24gdGhlIGZhY3QgdGhhdCBNREQgQ29udHJvbCBGbG93IGFyZSBleGVjdXRlZCBvbiBhCisgKiBTZXF1ZW50aWFsRXhlY3V0b3IuCisgKi8KK0BDaGVja1JldHVyblZhbHVlCitwdWJsaWMgZmluYWwgY2xhc3MgU2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhIGltcGxlbWVudHMgU2hhcmVkRmlsZXNNZXRhZGF0YSB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJTaGFyZWRGaWxlc01ldGFkYXRhIjsKKworICBAVmlzaWJsZUZvclRlc3Rpbmcgc3RhdGljIGZpbmFsIFN0cmluZyBQUkVGU19LRVlfTkVYVF9GSUxFX05BTUVfT0xEID0gIm5leHRfZmlsZV9uYW1lIjsKKyAgQFZpc2libGVGb3JUZXN0aW5nIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJFRlNfS0VZX05FWFRfRklMRV9OQU1FID0gIm5leHRfZmlsZV9uYW1lX3YyIjsKKworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dDsKKyAgcHJpdmF0ZSBmaW5hbCBTaWxlbnRGZWVkYmFjayBzaWxlbnRGZWVkYmFjazsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQ7CisgIHByaXZhdGUgZmluYWwgRmxhZ3MgZmxhZ3M7CisKKyAgQEluamVjdAorICBwdWJsaWMgU2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhKAorICAgICAgQEFwcGxpY2F0aW9uQ29udGV4dCBDb250ZXh0IGNvbnRleHQsCisgICAgICBTaWxlbnRGZWVkYmFjayBzaWxlbnRGZWVkYmFjaywKKyAgICAgIEBJbnN0YW5jZUlkIE9wdGlvbmFsPFN0cmluZz4gaW5zdGFuY2VJZCwKKyAgICAgIEZsYWdzIGZsYWdzKSB7CisgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsKKyAgICB0aGlzLnNpbGVudEZlZWRiYWNrID0gc2lsZW50RmVlZGJhY2s7CisgICAgdGhpcy5pbnN0YW5jZUlkID0gaW5zdGFuY2VJZDsKKyAgICB0aGlzLmZsYWdzID0gZmxhZ3M7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gaW5pdCgpIHsKKyAgICAvLyBNaWdyYXRlIHRvIHRoZSBuZXcgZmlsZSBrZXkuCisgICAgaWYgKCFNaWdyYXRpb25zLmlzTWlncmF0ZWRUb05ld0ZpbGVLZXkoY29udGV4dCkpIHsKKyAgICAgIExvZ1V0aWwuZCgiJXMgRGV2aWNlIGlzbid0IG1pZ3JhdGVkIHRvIG5ldyBmaWxlIGtleSwgY2xlYXIgYW5kIHNldCBtaWdyYXRpb24uIiwgVEFHKTsKKyAgICAgIE1pZ3JhdGlvbnMuc2V0TWlncmF0ZWRUb05ld0ZpbGVLZXkoY29udGV4dCwgdHJ1ZSk7CisgICAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLmdldFZlcnNpb24oZmxhZ3MuZmlsZUtleVZlcnNpb24oKSkpOworICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKTsKKyAgICB9CisgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHVwZ3JhZGVUb05ld1ZlcnNpb24oKSk7CisgIH0KKworICAvKioKKyAgICogU2VxdWVudGlhbGx5IHVwZ3JhZGUgRmlsZUtleSB2ZXJzaW9uIHRvIEZlYXR1cmVGbGFncy5maWxlS2V5VmVyc2lvbgorICAgKgorICAgKiBAcmV0dXJuIGZhbHNlIGlmIGFueSB1cGdyYWRlIGZhaWxzIHdoaWNoIHdpbGwgcmVzdWx0IGluIGNsZWFyaW5nIG9mIGFsbCBtZXRhIGRhdGEsIHRydWUgb24KKyAgICogICAgIHN1Y2Nlc3NmdWwgdXBncmFkZS4KKyAgICovCisgIHByaXZhdGUgYm9vbGVhbiB1cGdyYWRlVG9OZXdWZXJzaW9uKCkgeworICAgIGZpbmFsIEZpbGVLZXlWZXJzaW9uIHRhcmdldFZlcnNpb24gPSBGaWxlS2V5VmVyc2lvbi5nZXRWZXJzaW9uKGZsYWdzLmZpbGVLZXlWZXJzaW9uKCkpOworICAgIGZpbmFsIEZpbGVLZXlWZXJzaW9uIGN1cnJlbnRWZXJzaW9uID0gTWlncmF0aW9ucy5nZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBzaWxlbnRGZWVkYmFjayk7CisKKyAgICBpZiAodGFyZ2V0VmVyc2lvbi52YWx1ZSA9PSBjdXJyZW50VmVyc2lvbi52YWx1ZSkgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgaWYgKHRhcmdldFZlcnNpb24udmFsdWUgPCBjdXJyZW50VmVyc2lvbi52YWx1ZSkgeworICAgICAgLy8gV2UgZG9uJ3Qgc3VwcG9ydCBkb3duZ3JhZGluZyBmaWxlIGtleSB2ZXJzaW9uLiBDbGVhciBldmVyeXRoaW5nLgorICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICIlcyBDYW5ub3QgbWlncmF0ZSBiYWNrIGZyb20gdmFsdWUgJXMgdG8gJXMuIENsZWFyIGV2ZXJ5dGhpbmchIiwKKyAgICAgICAgICBUQUcsIGN1cnJlbnRWZXJzaW9uLCB0YXJnZXRWZXJzaW9uKTsKKyAgICAgIHNpbGVudEZlZWRiYWNrLnNlbmQoCisgICAgICAgICAgbmV3IEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgIkRvd25ncmFkZWQgZmlsZSBrZXkgZnJvbSAiICsgY3VycmVudFZlcnNpb24gKyAiIHRvICIgKyB0YXJnZXRWZXJzaW9uICsgIi4iKSwKKyAgICAgICAgICAiRmlsZUtleSBtaWdyYXRpb25zIHVuZXhwZWN0ZWQgZG93bmdyYWRlLiIpOworICAgICAgTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCB0YXJnZXRWZXJzaW9uKTsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBNaWdyYXRlIG9uZSB2ZXJzaW9uIGF0IGEgdGltZSBvbmUgYnkgb25lCisgICAgdHJ5IHsKKyAgICAgIGZvciAoaW50IG5leHRWZXJzaW9uID0gY3VycmVudFZlcnNpb24udmFsdWUgKyAxOworICAgICAgICAgIG5leHRWZXJzaW9uIDw9IHRhcmdldFZlcnNpb24udmFsdWU7CisgICAgICAgICAgbmV4dFZlcnNpb24rKykgeworICAgICAgICBpZiAodXBncmFkZVRvKEZpbGVLZXlWZXJzaW9uLmdldFZlcnNpb24obmV4dFZlcnNpb24pKSkgeworICAgICAgICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uZ2V0VmVyc2lvbihuZXh0VmVyc2lvbikpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIC8vIElmIG1pZ3JhdGlvbiB0byBuZXh0IHZlcnNpb24gZmFpbCwgd2Ugd2lsbCBjbGVhciBhbGwgZGF0YSBhbmQgc2V0IHRoZSBjdXJyZW50VmVyc2lvbgorICAgICAgICAgIC8vIHRvIHRhcmdldFZlcnNpb24gKHBoRmlsZUtleVZlcnNpb24pCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICB9CisgICAgICB9CisgICAgfSBmaW5hbGx5IHsKKyAgICAgIGlmIChNaWdyYXRpb25zLmdldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIHNpbGVudEZlZWRiYWNrKS52YWx1ZSAhPSB0YXJnZXRWZXJzaW9uLnZhbHVlKSB7CisgICAgICAgIGlmICghTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCB0YXJnZXRWZXJzaW9uKSkgeworICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgIkZhaWxlZCB0byBjb21taXQgbWlncmF0aW9uIHZlcnNpb24gdG8gZGlzay4gRmFpbCB0byBzZXQgdGFyZ2V0IHZlcnNpb24gdG8gIgorICAgICAgICAgICAgICAgICAgKyB0YXJnZXRWZXJzaW9uCisgICAgICAgICAgICAgICAgICArICIuIik7CisgICAgICAgICAgc2lsZW50RmVlZGJhY2suc2VuZCgKKyAgICAgICAgICAgICAgbmV3IEV4Y2VwdGlvbigiRmFpbCB0byBzZXQgdGFyZ2V0IHZlcnNpb24gIiArIHRhcmdldFZlcnNpb24gKyAiLiIpLAorICAgICAgICAgICAgICAiRmFpbGVkIHRvIGNvbW1pdCBtaWdyYXRpb24gdmVyc2lvbiB0byBkaXNrLiIpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBwcml2YXRlIGJvb2xlYW4gdXBncmFkZVRvKEZpbGVLZXlWZXJzaW9uIHRhcmdldFZlcnNpb24pIHsKKyAgICBzd2l0Y2ggKHRhcmdldFZlcnNpb24pIHsKKyAgICAgIGNhc2UgQUREX0RPV05MT0FEX1RSQU5TRk9STToKKyAgICAgICAgcmV0dXJuIG1pZ3JhdGVUb0FkZERvd25sb2FkVHJhbnNmb3JtKCk7CisgICAgICBjYXNlIFVTRV9DSEVDS1NVTV9PTkxZOgorICAgICAgICByZXR1cm4gbWlncmF0ZVRvRGVkdXBPbkNoZWNrc3VtT25seSgpOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgIlVwZ3JhZGUgdG8gdmVyc2lvbiAiICsgdGFyZ2V0VmVyc2lvbi5uYW1lKCkgKyAibm90IHN1cHBvcnRlZCEiKTsKKyAgICB9CisgIH0KKworICAvKiogQSBvbmUgb2ZmIG1ldGhvZCB0aGF0IGlzIGNhbGxlZCB3aGVuIHdlIG1pZ3JhdGUga2V5IHRvIGFkZCBkb3dubG9hZCB0cmFuc2Zvcm0uICovCisgIHByaXZhdGUgYm9vbGVhbiBtaWdyYXRlVG9BZGREb3dubG9hZFRyYW5zZm9ybSgpIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBTdGFydGluZyBtaWdyYXRpb24gdG8gYWRkIGRvd25sb2FkIHRyYW5zZm9ybSIsIFRBRyk7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMgcHJlZnMgPQorICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoY29udGV4dCwgTUREX1NIQVJFRF9GSUxFUywgaW5zdGFuY2VJZCk7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMuRWRpdG9yIGVkaXRvciA9IHByZWZzLmVkaXQoKTsKKyAgICBmb3IgKFN0cmluZyBzZXJpYWxpemVkRmlsZUtleSA6IHByZWZzLmdldEFsbCgpLmtleVNldCgpKSB7CisKKyAgICAgIC8vIFJlbW92ZSB0aGUgZGF0YSB0aGF0IHdlIGFyZSB1bmFibGUgdG8gcmVhZCBvciBwYXJzZS4KKyAgICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleTsKKyAgICAgIHRyeSB7CisgICAgICAgIG5ld0ZpbGVLZXkgPQorICAgICAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuZGVzZXJpYWxpemVOZXdGaWxlS2V5KAorICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRGaWxlS2V5LCBjb250ZXh0LCBzaWxlbnRGZWVkYmFjayk7CisgICAgICB9IGNhdGNoIChGaWxlS2V5RGVzZXJpYWxpemF0aW9uRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICAgIiVzIEZhaWxlZCB0byBkZXNlcmlhbGl6ZSBmaWxlIGtleSAlcywgcmVtb3ZlIGFuZCBjb250aW51ZS4iLCBUQUcsIHNlcmlhbGl6ZWRGaWxlS2V5KTsKKyAgICAgICAgc2lsZW50RmVlZGJhY2suc2VuZChlLCAiRmFpbGVkIHRvIGRlc2VyaWFsaXplIGZpbGUga2V5LCByZW1vdmUgYW5kIGNvbnRpbnVlLiIpOworICAgICAgICBlZGl0b3IucmVtb3ZlKHNlcmlhbGl6ZWRGaWxlS2V5KTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPQorICAgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5yZWFkUHJvdG8ocHJlZnMsIHNlcmlhbGl6ZWRGaWxlS2V5LCBTaGFyZWRGaWxlLnBhcnNlcigpKTsKKyAgICAgIGlmIChzaGFyZWRGaWxlID09IG51bGwpIHsKKyAgICAgICAgTG9nVXRpbC5lKCIlczogVW5hYmxlIHRvIHJlYWQgc2hhcmVkRmlsZSBmcm9tIHNoYXJlZCBwcmVmZXJlbmNlcy4iLCBUQUcpOworICAgICAgICBlZGl0b3IucmVtb3ZlKHNlcmlhbGl6ZWRGaWxlS2V5KTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIC8vIFJlbW92ZSB0aGUgb2xkIGtleSBhbmQgd3JpdGUgdGhlIG5ldyBvbmUuCisgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwucmVtb3ZlUHJvdG8oZWRpdG9yLCBzZXJpYWxpemVkRmlsZUtleSk7CisgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwud3JpdGVQcm90bygKKyAgICAgICAgICBlZGl0b3IsCisgICAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuc2VyaWFsaXplTmV3RmlsZUtleVdpdGhEb3dubG9hZFRyYW5zZm9ybShuZXdGaWxlS2V5KSwKKyAgICAgICAgICBzaGFyZWRGaWxlKTsKKyAgICB9CisKKyAgICBpZiAoIWVkaXRvci5jb21taXQoKSkgeworICAgICAgTG9nVXRpbC5lKCJGYWlsZWQgdG8gY29tbWl0IG1pZ3JhdGlvbiBtZXRhZGF0YSB0byBkaXNrIik7CisgICAgICBzaWxlbnRGZWVkYmFjay5zZW5kKAorICAgICAgICAgIG5ldyBFeGNlcHRpb24oIk1pZ3JhdGUgdG8gRG93bmxvYWRUcmFuc2Zvcm0gZmFpbGVkLiIpLAorICAgICAgICAgICJGYWlsZWQgdG8gY29tbWl0IG1pZ3JhdGlvbiBtZXRhZGF0YSB0byBkaXNrLiIpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLyoqIEEgb25lIG9mZiBtZXRob2QgdGhhdCBpcyBjYWxsZWQgd2hlbiB3ZSBtaWdyYXRlIGtleSB0byBjb250YWluIGNoZWNrc3VtIGFuZCBhbGxvd2VkUmVhZGVycy4gKi8KKyAgcHJpdmF0ZSBib29sZWFuIG1pZ3JhdGVUb0RlZHVwT25DaGVja3N1bU9ubHkoKSB7CisgICAgTG9nVXRpbC5kKCIlczogU3RhcnRpbmcgbWlncmF0aW9uIHRvIGRlZHVwIG9uIGNoZWNrc3VtIG9ubHkiLCBUQUcpOworICAgIFNoYXJlZFByZWZlcmVuY2VzIHByZWZzID0KKyAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKGNvbnRleHQsIE1ERF9TSEFSRURfRklMRVMsIGluc3RhbmNlSWQpOworICAgIFNoYXJlZFByZWZlcmVuY2VzLkVkaXRvciBlZGl0b3IgPSBwcmVmcy5lZGl0KCk7CisgICAgZm9yIChTdHJpbmcgc2VyaWFsaXplZEZpbGVLZXkgOiBwcmVmcy5nZXRBbGwoKS5rZXlTZXQoKSkgeworCisgICAgICAvLyBSZW1vdmUgdGhlIGRhdGEgdGhhdCB3ZSBhcmUgdW5hYmxlIHRvIHJlYWQgb3IgcGFyc2UuCisgICAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXk7CisgICAgICB0cnkgeworICAgICAgICBuZXdGaWxlS2V5ID0KKyAgICAgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGFVdGlsLmRlc2VyaWFsaXplTmV3RmlsZUtleSgKKyAgICAgICAgICAgICAgICBzZXJpYWxpemVkRmlsZUtleSwgY29udGV4dCwgc2lsZW50RmVlZGJhY2spOworICAgICAgfSBjYXRjaCAoRmlsZUtleURlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbiBlKSB7CisgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICIlcyBGYWlsZWQgdG8gZGVzZXJpYWxpemUgZmlsZSBrZXkgJXMsIHJlbW92ZSBhbmQgY29udGludWUuIiwgVEFHLCBzZXJpYWxpemVkRmlsZUtleSk7CisgICAgICAgIHNpbGVudEZlZWRiYWNrLnNlbmQoZSwgIkZhaWxlZCB0byBkZXNlcmlhbGl6ZSBmaWxlIGtleSwgcmVtb3ZlIGFuZCBjb250aW51ZS4iKTsKKyAgICAgICAgZWRpdG9yLnJlbW92ZShzZXJpYWxpemVkRmlsZUtleSk7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorCisgICAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPQorICAgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5yZWFkUHJvdG8ocHJlZnMsIHNlcmlhbGl6ZWRGaWxlS2V5LCBTaGFyZWRGaWxlLnBhcnNlcigpKTsKKyAgICAgIGlmIChzaGFyZWRGaWxlID09IG51bGwpIHsKKyAgICAgICAgTG9nVXRpbC5lKCIlczogVW5hYmxlIHRvIHJlYWQgc2hhcmVkRmlsZSBmcm9tIHNoYXJlZCBwcmVmZXJlbmNlcy4iLCBUQUcpOworICAgICAgICBlZGl0b3IucmVtb3ZlKHNlcmlhbGl6ZWRGaWxlS2V5KTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIC8vIFJlbW92ZSB0aGUgb2xkIGtleSBhbmQgd3JpdGUgdGhlIG5ldyBvbmUuCisgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwucmVtb3ZlUHJvdG8oZWRpdG9yLCBzZXJpYWxpemVkRmlsZUtleSk7CisgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwud3JpdGVQcm90bygKKyAgICAgICAgICBlZGl0b3IsCisgICAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuc2VyaWFsaXplTmV3RmlsZUtleVdpdGhDaGVja3N1bU9ubHkobmV3RmlsZUtleSksCisgICAgICAgICAgc2hhcmVkRmlsZSk7CisgICAgfQorCisgICAgaWYgKCFlZGl0b3IuY29tbWl0KCkpIHsKKyAgICAgIExvZ1V0aWwuZSgiRmFpbGVkIHRvIGNvbW1pdCBtaWdyYXRpb24gbWV0YWRhdGEgdG8gZGlzayIpOworICAgICAgc2lsZW50RmVlZGJhY2suc2VuZCgKKyAgICAgICAgICBuZXcgRXhjZXB0aW9uKCJNaWdyYXRlIHRvIENoZWNrc3VtT25seSBmYWlsZWQuIiksCisgICAgICAgICAgIkZhaWxlZCB0byBjb21taXQgbWlncmF0aW9uIG1ldGFkYXRhIHRvIGRpc2suIik7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICBAU3VwcHJlc3NXYXJuaW5ncygibnVsbG5lc3MiKQorICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8U2hhcmVkRmlsZT4gcmVhZChOZXdGaWxlS2V5IG5ld0ZpbGVLZXkpIHsKKyAgICBTdHJpbmcgc2VyaWFsaXplZEZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhVXRpbC5nZXRTZXJpYWxpemVkRmlsZUtleShuZXdGaWxlS2V5LCBjb250ZXh0LCBzaWxlbnRGZWVkYmFjayk7CisKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcyhjb250ZXh0LCBNRERfU0hBUkVEX0ZJTEVTLCBpbnN0YW5jZUlkKTsKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwucmVhZFByb3RvKHByZWZzLCBzZXJpYWxpemVkRmlsZUtleSwgU2hhcmVkRmlsZS5wYXJzZXIoKSk7CisKKyAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoc2hhcmVkRmlsZSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gd3JpdGUoTmV3RmlsZUtleSBuZXdGaWxlS2V5LCBTaGFyZWRGaWxlIHNoYXJlZEZpbGUpIHsKKyAgICBTdHJpbmcgc2VyaWFsaXplZEZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhVXRpbC5nZXRTZXJpYWxpemVkRmlsZUtleShuZXdGaWxlS2V5LCBjb250ZXh0LCBzaWxlbnRGZWVkYmFjayk7CisKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcyhjb250ZXh0LCBNRERfU0hBUkVEX0ZJTEVTLCBpbnN0YW5jZUlkKTsKKyAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoCisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC53cml0ZVByb3RvKHByZWZzLCBzZXJpYWxpemVkRmlsZUtleSwgc2hhcmVkRmlsZSkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IHJlbW92ZShOZXdGaWxlS2V5IG5ld0ZpbGVLZXkpIHsKKyAgICBTdHJpbmcgc2VyaWFsaXplZEZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhVXRpbC5nZXRTZXJpYWxpemVkRmlsZUtleShuZXdGaWxlS2V5LCBjb250ZXh0LCBzaWxlbnRGZWVkYmFjayk7CisKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcyhjb250ZXh0LCBNRERfU0hBUkVEX0ZJTEVTLCBpbnN0YW5jZUlkKTsKKyAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoU2hhcmVkUHJlZmVyZW5jZXNVdGlsLnJlbW92ZVByb3RvKHByZWZzLCBzZXJpYWxpemVkRmlsZUtleSkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPExpc3Q8TmV3RmlsZUtleT4+IGdldEFsbEZpbGVLZXlzKCkgeworICAgIExpc3Q8TmV3RmlsZUtleT4gbmV3RmlsZUtleUxpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcyhjb250ZXh0LCBNRERfU0hBUkVEX0ZJTEVTLCBpbnN0YW5jZUlkKTsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcy5FZGl0b3IgZWRpdG9yID0gbnVsbDsKKyAgICBmb3IgKFN0cmluZyBzZXJpYWxpemVkRmlsZUtleSA6IHByZWZzLmdldEFsbCgpLmtleVNldCgpKSB7CisgICAgICB0cnkgeworICAgICAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuZGVzZXJpYWxpemVOZXdGaWxlS2V5KAorICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRGaWxlS2V5LCBjb250ZXh0LCBzaWxlbnRGZWVkYmFjayk7CisgICAgICAgIG5ld0ZpbGVLZXlMaXN0LmFkZChuZXdGaWxlS2V5KTsKKyAgICAgIH0gY2F0Y2ggKEZpbGVLZXlEZXNlcmlhbGl6YXRpb25FeGNlcHRpb24gZSkgeworICAgICAgICBMb2dVdGlsLmUoZSwgIkZhaWxlZCB0byBkZXNlcmlhbGl6ZSBuZXdGaWxlS2V5OiIgKyBzZXJpYWxpemVkRmlsZUtleSk7CisgICAgICAgIHNpbGVudEZlZWRiYWNrLnNlbmQoCisgICAgICAgICAgICBlLAorICAgICAgICAgICAgIkZhaWxlZCB0byBkZXNlcmlhbGl6ZSBuZXdGaWxlS2V5LCB1bmV4cGVjdGVkIGtleSBzaXplOiAlZCIsCisgICAgICAgICAgICBTcGxpdHRlci5vbihTUExJVF9DSEFSKS5zcGxpdFRvTGlzdChzZXJpYWxpemVkRmlsZUtleSkuc2l6ZSgpKTsKKyAgICAgICAgLy8gVE9ETyhiLzEyODg1MDAwMCk6IFJlZmFjdG9yIHRoaXMgY29kZSB0byBhIHNpbmdsZSBjb3JydXB0aW9uIGhhbmRsaW5nIHRhc2sgZHVyaW5nCisgICAgICAgIC8vIG1haW50ZW5hbmNlLgorICAgICAgICAvLyBSZW1vdmUgdGhlIGNvcnJ1cHRlZCBmaWxlIG1ldGFkYXRhIGFuZCB0aGUgcmVsYXRlZCBGaWxlR3JvdXAgbWV0YWRhdGEgd2lsbCBiZSBkZWxldGVkCisgICAgICAgIC8vIGluIG5leHQgbWFpbnRlbmFuY2UgdGFzay4KKyAgICAgICAgaWYgKGVkaXRvciA9PSBudWxsKSB7CisgICAgICAgICAgZWRpdG9yID0gcHJlZnMuZWRpdCgpOworICAgICAgICB9CisgICAgICAgIGVkaXRvci5yZW1vdmUoc2VyaWFsaXplZEZpbGVLZXkpOworICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKGVkaXRvciAhPSBudWxsKSB7CisgICAgICBlZGl0b3IuY29tbWl0KCk7CisgICAgfQorICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShuZXdGaWxlS2V5TGlzdCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gY2xlYXIoKSB7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMgcHJlZnMgPQorICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoY29udGV4dCwgTUREX1NIQVJFRF9GSUxFUywgaW5zdGFuY2VJZCk7CisgICAgcHJlZnMuZWRpdCgpLmNsZWFyKCkuY29tbWl0KCk7CisgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL1VuaW5zdGFsbGVkQXBwRXhjZXB0aW9uLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL1VuaW5zdGFsbGVkQXBwRXhjZXB0aW9uLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzc4NGIxMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvVW5pbnN0YWxsZWRBcHBFeGNlcHRpb24uamF2YQpAQCAtMCwwICsxLDIxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbDsKKworLyoqCisgKiBUaHJvd24gd2hlbiB0cnlpbmcgdG8gYWRkIGEgRmlsZSBHcm91cCB0aGF0IGlzIG93bmVkIGJ5IGFuIGFwcCB0aGF0IGlzIG5vdCBwcmVzZW50IG9uIHRoZSBkZXZpY2UuCisgKi8KK3B1YmxpYyBjbGFzcyBVbmluc3RhbGxlZEFwcEV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7fQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9hbm5vdGF0aW9ucy9Bbm5vdGF0aW9ucy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9hbm5vdGF0aW9ucy9Bbm5vdGF0aW9ucy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4NmIxOTIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Fubm90YXRpb25zL0Fubm90YXRpb25zLmphdmEKQEAgLTAsMCArMSw2MSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuYW5ub3RhdGlvbnM7CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5SZXRlbnRpb247CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uUmV0ZW50aW9uUG9saWN5OworaW1wb3J0IGphdmF4LmluamVjdC5RdWFsaWZpZXI7CisKKy8qKiBBbm5vdGF0aW9ucyBmb3IgTUREIGludGVybmFscy4gKi8KKy8vIFRPRE8oYi8xNjgwODEwNzMpOiBBZGQgQWNjb3VudE1hbmFnZXIgYW5kIFNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgdG8gdGhpcyBmaWxlLgorcHVibGljIGZpbmFsIGNsYXNzIEFubm90YXRpb25zIHsKKyAgLyoqIFF1YWxpZmllciBmb3IgdGhlIFBEUyBtaWdyYXRpb24gZGlhZ25vc3RpYyBtZXRhZGF0YS4gKi8KKyAgQFF1YWxpZmllcgorICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorICBwdWJsaWMgQGludGVyZmFjZSBQZHNNaWdyYXRpb25EaWFnbm9zdGljIHt9CisKKyAgLyoqIFF1YWxpZmllciBmb3IgdGhlIFBEUyBtaWdyYXRpb24gZGVzdGluYXRpb24gbWV0YWRhdGEuICovCisgIEBRdWFsaWZpZXIKKyAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKKyAgcHVibGljIEBpbnRlcmZhY2UgUGRzTWlncmF0aW9uRGVzdGluYXRpb24ge30KKworICAvKiogUXVhbGlmaWVyIGZvciB0aGUgUERTIG1pZ3JhdGlvbiBmaWxlIGdyb3VwcyBkZXN0aW5hdGlvbiB1cmkuICovCisgIEBRdWFsaWZpZXIKKyAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKKyAgcHVibGljIEBpbnRlcmZhY2UgRmlsZUdyb3Vwc0Rlc3RpbmF0aW9uVXJpIHt9CisKKyAgLyoqIFF1YWxpZmllciBmb3IgdGhlIFBEUyBtaWdyYXRpb24gZmlsZSBncm91cHMgZGlhZ25vc3RpYyB1cmkuICovCisgIEBRdWFsaWZpZXIKKyAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKKyAgcHVibGljIEBpbnRlcmZhY2UgRmlsZUdyb3Vwc0RpYWdub3N0aWNVcmkge30KKworICAvKiogUXVhbGlmaWVyIGZvciB0aGUgUERTIG1pZ3JhdGlvbiBzaGFyZWQgZmlsZXMgZGVzdGluYXRpb24gdXJpLiAqLworICBAUXVhbGlmaWVyCisgIEBSZXRlbnRpb24oUmV0ZW50aW9uUG9saWN5LlJVTlRJTUUpCisgIHB1YmxpYyBAaW50ZXJmYWNlIFNoYXJlZEZpbGVzRGVzdGluYXRpb25Vcmkge30KKworICAvKiogUXVhbGlmaWVyIGZvciB0aGUgUERTIG1pZ3JhdGlvbiBzaGFyZWQgZmlsZXMgZGlhZ25vc3RpYyB1cmkuICovCisgIEBRdWFsaWZpZXIKKyAgQFJldGVudGlvbihSZXRlbnRpb25Qb2xpY3kuUlVOVElNRSkKKyAgcHVibGljIEBpbnRlcmZhY2UgU2hhcmVkRmlsZXNEaWFnbm9zdGljVXJpIHt9CisKKyAgLyoqIFF1YWxpZmllciBmb3IgdGhlIFBEUyBmb3IgbG9nZ2luZyBzdGF0ZS4gKi8KKyAgQFF1YWxpZmllcgorICBAUmV0ZW50aW9uKFJldGVudGlvblBvbGljeS5SVU5USU1FKQorICBwdWJsaWMgQGludGVyZmFjZSBMb2dnaW5nU3RhdGVTdG9yZSB7fQorCisgIHByaXZhdGUgQW5ub3RhdGlvbnMoKSB7fQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9hbm5vdGF0aW9ucy9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvYW5ub3RhdGlvbnMvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGM5NTllNgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvYW5ub3RhdGlvbnMvQlVJTEQKQEAgLTAsMCArMSw0MSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIlNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX2RhZ2dlciIsCisgICAgICAgICJAamF2YXhfaW5qZWN0IiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJhbm5vdGF0aW9ucyIsCisgICAgc3JjcyA9IFsiQW5ub3RhdGlvbnMuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICJAY29tX2dvb2dsZV9kYWdnZXIiLAorICAgICAgICAiQGphdmF4X2luamVjdCIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvYW5ub3RhdGlvbnMvU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9hbm5vdGF0aW9ucy9TZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzg0OTg5ZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvYW5ub3RhdGlvbnMvU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvci5qYXZhCkBAIC0wLDAgKzEsMjggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmFubm90YXRpb25zOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworaW1wb3J0IGphdmF4LmluamVjdC5RdWFsaWZpZXI7CisKKy8qKgorICogQSBTZXF1ZW50aWFsIEV4ZWN1dG9yIG9uIHdoaWNoIE1ERCBydW5zIGNvbnRyb2wgZXhlY3V0aW9uIGZsb3cgd2hpY2ggd2lsbCB0b3VjaCBJL08uIE1ERCBkZXBlbmRzCisgKiBvbiB0aGlzIFNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgZm9yIHN5bmNocm9uaXphdGlvbnMuCisgKi8KK0BUYXJnZXQoe0VsZW1lbnRUeXBlLlBBUkFNRVRFUiwgRWxlbWVudFR5cGUuTUVUSE9ELCBFbGVtZW50VHlwZS5GSUVMRH0pCitAUXVhbGlmaWVyCitwdWJsaWMgQGludGVyZmFjZSBTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIHt9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2RhZ2dlci9BcHBsaWNhdGlvbkNvbnRleHRNb2R1bGUuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZGFnZ2VyL0FwcGxpY2F0aW9uQ29udGV4dE1vZHVsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMwNzYxMjAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2RhZ2dlci9BcHBsaWNhdGlvbkNvbnRleHRNb2R1bGUuamF2YQpAQCAtMCwwICsxLDM4IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kYWdnZXI7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5BcHBsaWNhdGlvbkNvbnRleHQ7CitpbXBvcnQgZGFnZ2VyLk1vZHVsZTsKK2ltcG9ydCBkYWdnZXIuUHJvdmlkZXM7CisKKy8qKiBNb2R1bGUgZm9yIGluamVjdGluZyBhIGNvbnRleHQgZnJvbSB3aGljaCB3ZSBnZXQgdGhlIGFwcGxpY2F0aW9uIENvbnRleHQgKi8KK0BNb2R1bGUKK3B1YmxpYyBjbGFzcyBBcHBsaWNhdGlvbkNvbnRleHRNb2R1bGUgeworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworCisgIHB1YmxpYyBBcHBsaWNhdGlvbkNvbnRleHRNb2R1bGUoQ29udGV4dCBjb250ZXh0KSB7CisgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dC5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKyAgfQorCisgIEBQcm92aWRlcworICBAQXBwbGljYXRpb25Db250ZXh0CisgIENvbnRleHQgcHJvdmlkZUNvbnRleHQoKSB7CisgICAgcmV0dXJuIGNvbnRleHQ7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZGFnZ2VyL0JVSUxEIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kYWdnZXIvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDY1YzIyMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZGFnZ2VyL0JVSUxECkBAIC0wLDAgKzEsOTkgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJBcHBsaWNhdGlvbkNvbnRleHRNb2R1bGUiLAorICAgIHNyY3MgPSBbIkFwcGxpY2F0aW9uQ29udGV4dE1vZHVsZS5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpBcHBsaWNhdGlvbkNvbnRleHQiLAorICAgICAgICAiQGNvbV9nb29nbGVfZGFnZ2VyIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJFeGVjdXRvcnNNb2R1bGUiLAorICAgIHNyY3MgPSBbIkV4ZWN1dG9yc01vZHVsZS5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9hbm5vdGF0aW9uczpTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2RhZ2dlciIsCisgICAgICAgICJAamF2YXhfaW5qZWN0IiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJEb3dubG9hZGVyTW9kdWxlIiwKKyAgICBzcmNzID0gWyJEb3dubG9hZGVyTW9kdWxlLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2RlbHRhOkRlbHRhRGVjb2RlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlcjpGaWxlRG93bmxvYWRlciIsCisgICAgICAgICJAY29tX2dvb2dsZV9kYWdnZXIiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGphdmF4X2luamVjdCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiTWFpbk1kZExpYk1vZHVsZSIsCisgICAgc3JjcyA9IFsiTWFpbk1kZExpYk1vZHVsZS5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpBY2NvdW50U291cmNlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpFeHBlcmltZW50YXRpb25Db25maWciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpTaWxlbnRGZWVkYmFjayIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6VGltZVNvdXJjZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkFwcGxpY2F0aW9uQ29udGV4dCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6RmlsZUdyb3Vwc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6U2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9hbm5vdGF0aW9uczpTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9leHBlcmltZW50YXRpb246RG93bmxvYWRTdGFnZU1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2V4cGVyaW1lbnRhdGlvbjpOb09wRG93bmxvYWRTdGFnZU1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6RXZlbnRMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nZ2luZ1N0YXRlU3RvcmUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6Tm9PcExvZ2dpbmdTdGF0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpGdXR1cmVzVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpOZXR3b3JrVXNhZ2VNb25pdG9yIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2RhZ2dlciIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAamF2YXhfaW5qZWN0IiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJTdGFuZGFsb25lQ29tcG9uZW50IiwKKyAgICBzcmNzID0gWworICAgICAgICAiU3RhbmRhbG9uZUNvbXBvbmVudC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6QXBwbGljYXRpb25Db250ZXh0TW9kdWxlIiwKKyAgICAgICAgIjpEb3dubG9hZGVyTW9kdWxlIiwKKyAgICAgICAgIjpFeGVjdXRvcnNNb2R1bGUiLAorICAgICAgICAiOk1haW5NZGRMaWJNb2R1bGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOk1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6RXZlbnRMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nZ2luZ1N0YXRlU3RvcmUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZGFnZ2VyIiwKKyAgICAgICAgIkBqYXZheF9pbmplY3QiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2RhZ2dlci9Eb3dubG9hZGVyTW9kdWxlLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2RhZ2dlci9Eb3dubG9hZGVyTW9kdWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzNlMjE4YwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZGFnZ2VyL0Rvd25sb2FkZXJNb2R1bGUuamF2YQpAQCAtMCwwICsxLDUyIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kYWdnZXI7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kZWx0YS5EZWx0YURlY29kZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuU3VwcGxpZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5TdXBwbGllcnM7CitpbXBvcnQgZGFnZ2VyLk1vZHVsZTsKK2ltcG9ydCBkYWdnZXIuUHJvdmlkZXM7CitpbXBvcnQgamF2YXguaW5qZWN0LlNpbmdsZXRvbjsKKworLyoqIE1vZHVsZSBmb3IgTUREIExpYiBkb3dubG9hZGVyIGRlcGVuZGVuY2llcyAqICovCitATW9kdWxlCitwdWJsaWMgY2xhc3MgRG93bmxvYWRlck1vZHVsZSB7CisKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxEZWx0YURlY29kZXI+IGRlbHRhRGVjb2Rlck9wdGlvbmFsOworICBwcml2YXRlIGZpbmFsIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyOworCisgIHB1YmxpYyBEb3dubG9hZGVyTW9kdWxlKAorICAgICAgT3B0aW9uYWw8RGVsdGFEZWNvZGVyPiBkZWx0YURlY29kZXJPcHRpb25hbCwKKyAgICAgIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyKSB7CisgICAgdGhpcy5kZWx0YURlY29kZXJPcHRpb25hbCA9IGRlbHRhRGVjb2Rlck9wdGlvbmFsOworICAgIHRoaXMuZmlsZURvd25sb2FkZXJTdXBwbGllciA9IFN1cHBsaWVycy5tZW1vaXplKGZpbGVEb3dubG9hZGVyU3VwcGxpZXIpOworICB9CisKKyAgQFByb3ZpZGVzCisgIEBTaW5nbGV0b24KKyAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IHByb3ZpZGVGaWxlRG93bmxvYWRlclN1cHBsaWVyKCkgeworICAgIHJldHVybiBmaWxlRG93bmxvYWRlclN1cHBsaWVyOworICB9CisKKyAgQFByb3ZpZGVzCisgIEBTaW5nbGV0b24KKyAgT3B0aW9uYWw8RGVsdGFEZWNvZGVyPiBwcm92aWRlRGVsdGFEZWNvZGVyKCkgeworICAgIHJldHVybiBkZWx0YURlY29kZXJPcHRpb25hbDsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kYWdnZXIvRXhlY3V0b3JzTW9kdWxlLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2RhZ2dlci9FeGVjdXRvcnNNb2R1bGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZTc4NTNjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kYWdnZXIvRXhlY3V0b3JzTW9kdWxlLmphdmEKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZGFnZ2VyOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuYW5ub3RhdGlvbnMuU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKK2ltcG9ydCBkYWdnZXIuTW9kdWxlOworaW1wb3J0IGRhZ2dlci5Qcm92aWRlczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZheC5pbmplY3QuU2luZ2xldG9uOworCisvKiogTW9kdWxlIHRoYXQgcHJvdmlkZXMgdmFyaW91cyBFeGVjdXRvcnMgZm9yIE1ERC4gKi8KK0BNb2R1bGUKK3B1YmxpYyBjbGFzcyBFeGVjdXRvcnNNb2R1bGUgeworICAvLyBUT0RPKGIvMjA0MjExNjgyKTogQWxzbyBrZWVwIHRoZSBnZW5lcmFsIChub24tc2VxdWVudGlhbCkgY29udHJvbEV4ZWN1dG9yLgorICAvLyBFeGVjdXRvciB0byBleGVjdXRlIE1ERCB0YXNrcyB0aGF0IG5lZWRzIHRvIGJlIGRvbmUgc2VxdWVudGlhbGx5LgorICBwcml2YXRlIGZpbmFsIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CisKKyAgcHVibGljIEV4ZWN1dG9yc01vZHVsZShFeGVjdXRvciBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKSB7CisgICAgdGhpcy5zZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yID0gc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKyAgfQorCisgIEBQcm92aWRlcworICBAU2luZ2xldG9uCisgIEBTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yCisgIHB1YmxpYyBFeGVjdXRvciBwcm92aWRlU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcigpIHsKKyAgICByZXR1cm4gc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kYWdnZXIvTWFpbk1kZExpYk1vZHVsZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kYWdnZXIvTWFpbk1kZExpYk1vZHVsZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4YzIzZjAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2RhZ2dlci9NYWluTWRkTGliTW9kdWxlLmphdmEKQEAgLTAsMCArMSwxODggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmRhZ2dlcjsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkFjY291bnRTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRXhwZXJpbWVudGF0aW9uQ29uZmlnOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkZsYWdzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlNpbGVudEZlZWRiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlRpbWVTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuYW5ub3RhdGlvbnMuSW5zdGFuY2VJZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuQXBwbGljYXRpb25Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLkZpbGVHcm91cHNNZXRhZGF0YTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5TaGFyZWRGaWxlc01ldGFkYXRhOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLlNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLlNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5hbm5vdGF0aW9ucy5TZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmV4cGVyaW1lbnRhdGlvbi5Eb3dubG9hZFN0YWdlTWFuYWdlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5leHBlcmltZW50YXRpb24uTm9PcERvd25sb2FkU3RhZ2VNYW5hZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuRXZlbnRMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dnaW5nU3RhdGVTdG9yZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLk5vT3BMb2dnaW5nU3RhdGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5GdXR1cmVzVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuTmV0d29ya1VzYWdlTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGRhZ2dlci5Nb2R1bGU7CitpbXBvcnQgZGFnZ2VyLlByb3ZpZGVzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworaW1wb3J0IGphdmF4LmluamVjdC5TaW5nbGV0b247CisKKy8qKiBNb2R1bGUgZm9yIE1ERCBMaWIgZGVwZW5kZW5jaWVzICovCitATW9kdWxlCitwdWJsaWMgY2xhc3MgTWFpbk1kZExpYk1vZHVsZSB7CisgIC8qKiBUaGUgdmVyc2lvbiBvZiBNREQgbGlicmFyeS4gU2FtZSBhcyBtZGlfZG93bmxvYWQgbW9kdWxlIHZlcnNpb24uICovCisgIC8vIFRPRE8oYi8xMjIyNzE3NjYpOiBGaWd1cmUgb3V0IGhvdyB0byB1cGRhdGUgdGhpcyBhdXRvbWF0aWNhbGx5LgorICAvLyBMSU5ULklmQ2hhbmdlCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1ERF9MSUJfVkVSU0lPTiA9IDQyMjg4MzgzODsKKyAgLy8gTElOVC5UaGVuQ2hhbmdlKDxpbnRlcm5hbD4pCisKKyAgcHJpdmF0ZSBmaW5hbCBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIGZpbmFsIE5ldHdvcmtVc2FnZU1vbml0b3IgbmV0d29ya1VzYWdlTW9uaXRvcjsKKyAgcHJpdmF0ZSBmaW5hbCBFdmVudExvZ2dlciBldmVudExvZ2dlcjsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxEb3dubG9hZFByb2dyZXNzTW9uaXRvcj4gZG93bmxvYWRQcm9ncmVzc01vbml0b3JPcHRpb25hbDsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxTaWxlbnRGZWVkYmFjaz4gc2lsZW50RmVlZGJhY2tPcHRpb25hbDsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQ7CisgIHByaXZhdGUgZmluYWwgT3B0aW9uYWw8QWNjb3VudFNvdXJjZT4gYWNjb3VudFNvdXJjZU9wdGlvbmFsOworICBwcml2YXRlIGZpbmFsIEZsYWdzIGZsYWdzOworICBwcml2YXRlIGZpbmFsIE9wdGlvbmFsPEV4cGVyaW1lbnRhdGlvbkNvbmZpZz4gZXhwZXJpbWVudGF0aW9uQ29uZmlnT3B0aW9uYWw7CisKKyAgcHVibGljIE1haW5NZGRMaWJNb2R1bGUoCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLAorICAgICAgTmV0d29ya1VzYWdlTW9uaXRvciBuZXR3b3JrVXNhZ2VNb25pdG9yLAorICAgICAgRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXIsCisgICAgICBPcHRpb25hbDxEb3dubG9hZFByb2dyZXNzTW9uaXRvcj4gZG93bmxvYWRQcm9ncmVzc01vbml0b3JPcHRpb25hbCwKKyAgICAgIE9wdGlvbmFsPFNpbGVudEZlZWRiYWNrPiBzaWxlbnRGZWVkYmFja09wdGlvbmFsLAorICAgICAgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkLAorICAgICAgT3B0aW9uYWw8QWNjb3VudFNvdXJjZT4gYWNjb3VudFNvdXJjZU9wdGlvbmFsLAorICAgICAgRmxhZ3MgZmxhZ3MsCisgICAgICBPcHRpb25hbDxFeHBlcmltZW50YXRpb25Db25maWc+IGV4cGVyaW1lbnRhdGlvbkNvbmZpZ09wdGlvbmFsKSB7CisgICAgdGhpcy5maWxlU3RvcmFnZSA9IGZpbGVTdG9yYWdlOworICAgIHRoaXMubmV0d29ya1VzYWdlTW9uaXRvciA9IG5ldHdvcmtVc2FnZU1vbml0b3I7CisgICAgdGhpcy5ldmVudExvZ2dlciA9IGV2ZW50TG9nZ2VyOworICAgIHRoaXMuZG93bmxvYWRQcm9ncmVzc01vbml0b3JPcHRpb25hbCA9IGRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yT3B0aW9uYWw7CisgICAgdGhpcy5zaWxlbnRGZWVkYmFja09wdGlvbmFsID0gc2lsZW50RmVlZGJhY2tPcHRpb25hbDsKKyAgICB0aGlzLmluc3RhbmNlSWQgPSBpbnN0YW5jZUlkOworICAgIHRoaXMuYWNjb3VudFNvdXJjZU9wdGlvbmFsID0gYWNjb3VudFNvdXJjZU9wdGlvbmFsOworICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKKyAgICB0aGlzLmV4cGVyaW1lbnRhdGlvbkNvbmZpZ09wdGlvbmFsID0gZXhwZXJpbWVudGF0aW9uQ29uZmlnT3B0aW9uYWw7CisgIH0KKworICBAUHJvdmlkZXMKKyAgQFNpbmdsZXRvbgorICBzdGF0aWMgRmlsZUdyb3Vwc01ldGFkYXRhIHByb3ZpZGVGaWxlR3JvdXBzTWV0YWRhdGEoCisgICAgICBTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGEpIHsKKyAgICByZXR1cm4gZmlsZUdyb3Vwc01ldGFkYXRhOworICB9CisKKyAgQFByb3ZpZGVzCisgIEBTaW5nbGV0b24KKyAgc3RhdGljIFNoYXJlZEZpbGVzTWV0YWRhdGEgcHJvdmlkZVNoYXJlZEZpbGVzTWV0YWRhdGEoCisgICAgICBTaGFyZWRQcmVmZXJlbmNlc1NoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YSkgeworICAgIHJldHVybiBzaGFyZWRGaWxlc01ldGFkYXRhOworICB9CisKKyAgQFByb3ZpZGVzCisgIEBTaW5nbGV0b24KKyAgRXZlbnRMb2dnZXIgcHJvdmlkZUV2ZW50TG9nZ2VyKCkgeworICAgIHJldHVybiBldmVudExvZ2dlcjsKKyAgfQorCisgIEBQcm92aWRlcworICBAU2luZ2xldG9uCisgIFNpbGVudEZlZWRiYWNrIHByb3ZpZGVzU2lsZW50RmVlZGJhY2soKSB7CisgICAgaWYgKHRoaXMuc2lsZW50RmVlZGJhY2tPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgcmV0dXJuIHRoaXMuc2lsZW50RmVlZGJhY2tPcHRpb25hbC5nZXQoKTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuICh0aHJvd2FibGUsIGRlc2NyaXB0aW9uLCBhcmdzKSAtPiB7CisgICAgICAgIC8vIE5vLW9wIFNpbGVudEZlZWRiYWNrLgorICAgICAgfTsKKyAgICB9CisgIH0KKworICBAUHJvdmlkZXMKKyAgQFNpbmdsZXRvbgorICBPcHRpb25hbDxBY2NvdW50U291cmNlPiBwcm92aWRlQWNjb3VudFNvdXJjZU9wdGlvbmFsKEBBcHBsaWNhdGlvbkNvbnRleHQgQ29udGV4dCBjb250ZXh0KSB7CisgICAgcmV0dXJuIHRoaXMuYWNjb3VudFNvdXJjZU9wdGlvbmFsOworICB9CisKKyAgQFByb3ZpZGVzCisgIEBTaW5nbGV0b24KKyAgc3RhdGljIFRpbWVTb3VyY2UgcHJvdmlkZVRpbWVTb3VyY2UoKSB7CisgICAgcmV0dXJuIFN5c3RlbTo6Y3VycmVudFRpbWVNaWxsaXM7CisgIH0KKworICBAUHJvdmlkZXMKKyAgQFNpbmdsZXRvbgorICBASW5zdGFuY2VJZAorICBPcHRpb25hbDxTdHJpbmc+IHByb3ZpZGVJbnN0YW5jZUlkKCkgeworICAgIHJldHVybiB0aGlzLmluc3RhbmNlSWQ7CisgIH0KKworICBAUHJvdmlkZXMKKyAgQFNpbmdsZXRvbgorICBOZXR3b3JrVXNhZ2VNb25pdG9yIHByb3ZpZGVOZXR3b3JrVXNhZ2VNb25pdG9yKCkgeworICAgIHJldHVybiB0aGlzLm5ldHdvcmtVc2FnZU1vbml0b3I7CisgIH0KKworICBAUHJvdmlkZXMKKyAgQFNpbmdsZXRvbgorICAvLyBUT0RPOiBXZSBkb24ndCBuZWVkIHRvIGhhdmUgQFNpbmdsZXRvbiBoZXJlIGFuZCBmZXcgb3RoZXIgcGxhY2VzIGluIHRoaXMgY2xhc3MKKyAgLy8gc2luY2UgaXQgY29tZXMgZnJvbSB0aGUgdGhpcyBpbnN0YW5jZS4gV2Ugc2hvdWxkIHJlbW92ZSB0aGlzIHNpbmNlIGl0IGNvdWxkIGluY3JlYXNlIEFQSyBzaXplLgorICBPcHRpb25hbDxEb3dubG9hZFByb2dyZXNzTW9uaXRvcj4gcHJvdmlkZURvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKCkgeworICAgIHJldHVybiB0aGlzLmRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yT3B0aW9uYWw7CisgIH0KKworICBAUHJvdmlkZXMKKyAgQFNpbmdsZXRvbgorICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHByb3ZpZGVTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKCkgeworICAgIHJldHVybiB0aGlzLmZpbGVTdG9yYWdlOworICB9CisKKyAgQFByb3ZpZGVzCisgIEBTaW5nbGV0b24KKyAgRmxhZ3MgcHJvdmlkZUZsYWdzKCkgeworICAgIHJldHVybiB0aGlzLmZsYWdzOworICB9CisKKyAgQFByb3ZpZGVzCisgIE9wdGlvbmFsPEV4cGVyaW1lbnRhdGlvbkNvbmZpZz4gcHJvdmlkZUV4cGVyaW1lbnRhdGlvbkNvbmZpZ09wdGlvbmFsKCkgeworICAgIHJldHVybiB0aGlzLmV4cGVyaW1lbnRhdGlvbkNvbmZpZ09wdGlvbmFsOworICB9CisKKyAgQFByb3ZpZGVzCisgIEBTaW5nbGV0b24KKyAgc3RhdGljIEZ1dHVyZXNVdGlsIHByb3ZpZGVGdXR1cmVzVXRpbChAU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciBFeGVjdXRvciBzZXF1ZW50aWFsRXhlY3V0b3IpIHsKKyAgICByZXR1cm4gbmV3IEZ1dHVyZXNVdGlsKHNlcXVlbnRpYWxFeGVjdXRvcik7CisgIH0KKworICBAUHJvdmlkZXMKKyAgQFNpbmdsZXRvbgorICBzdGF0aWMgTG9nZ2luZ1N0YXRlU3RvcmUgcHJvdmlkZUxvZ2dpbmdTdGF0ZVN0b3JlKCkgeworICAgIHJldHVybiBuZXcgTm9PcExvZ2dpbmdTdGF0ZSgpOworICB9CisKKyAgQFByb3ZpZGVzCisgIHN0YXRpYyBEb3dubG9hZFN0YWdlTWFuYWdlciBwcm92aWRlRG93bmxvYWRTdGFnZU1hbmFnZXIoCisgICAgICBGaWxlR3JvdXBzTWV0YWRhdGEgZmlsZUdyb3Vwc01ldGFkYXRhLAorICAgICAgT3B0aW9uYWw8RXhwZXJpbWVudGF0aW9uQ29uZmlnPiBleHBlcmltZW50YXRpb25Db25maWdPcHRpb25hbCwKKyAgICAgIEBTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIEV4ZWN1dG9yIGV4ZWN1dG9yLAorICAgICAgRmxhZ3MgZmxhZ3MpIHsKKyAgICByZXR1cm4gbmV3IE5vT3BEb3dubG9hZFN0YWdlTWFuYWdlcigpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2RhZ2dlci9TdGFuZGFsb25lQ29tcG9uZW50LmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2RhZ2dlci9TdGFuZGFsb25lQ29tcG9uZW50LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDgzNjdhNAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZGFnZ2VyL1N0YW5kYWxvbmVDb21wb25lbnQuamF2YQpAQCAtMCwwICsxLDQxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kYWdnZXI7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5Nb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuRXZlbnRMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dnaW5nU3RhdGVTdG9yZTsKK2ltcG9ydCBkYWdnZXIuQ29tcG9uZW50OworaW1wb3J0IGphdmF4LmluamVjdC5TaW5nbGV0b247CisKKy8qKiBNYWluIGNvbXBvbmVudCBmb3Igc3RhbmRhbG9uZSBNREQgbGlicmFyeS4gKi8KK0BDb21wb25lbnQoCisgICAgbW9kdWxlcyA9IHsKKyAgICAgIEFwcGxpY2F0aW9uQ29udGV4dE1vZHVsZS5jbGFzcywKKyAgICAgIERvd25sb2FkZXJNb2R1bGUuY2xhc3MsCisgICAgICBFeGVjdXRvcnNNb2R1bGUuY2xhc3MsCisgICAgICBNYWluTWRkTGliTW9kdWxlLmNsYXNzLAorICAgIH0pCitAU2luZ2xldG9uCitwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU3RhbmRhbG9uZUNvbXBvbmVudCB7CisKKyAgcHVibGljIGFic3RyYWN0IE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIgZ2V0TW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcigpOworCisgIHB1YmxpYyBhYnN0cmFjdCBFdmVudExvZ2dlciBnZXRFdmVudExvZ2dlcigpOworCisgIC8vIFRPRE8oYi8yMTQ2MzI3NzMpOiByZW1vdmUgdGhpcyB3aGVuIGV2ZW50IGxvZ2dlciBjYW4gYmUgY29uc3RydWN0ZWQgaW50ZXJuYWxseQorICBwdWJsaWMgYWJzdHJhY3QgTG9nZ2luZ1N0YXRlU3RvcmUgZ2V0TG9nZ2luZ1N0YXRlU3RvcmUoKTsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlci9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlci9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZDIzOWMxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyL0JVSUxECkBAIC0wLDAgKzEsMTI0IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9saWJyYXJ5IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiTWRkRmlsZURvd25sb2FkZXIiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJNZGRGaWxlRG93bmxvYWRlci5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZpbGVTb3VyY2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyOkZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpBcHBsaWNhdGlvbkNvbnRleHQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Fubm90YXRpb25zOlNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dnaW5nU3RhdGVTdG9yZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yOkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yOk5ldHdvcmtVc2FnZU1vbml0b3IiLAorICAgICAgICAiQGFuZHJvaWR4X2Fubm90YXRpb25fYW5ub3RhdGlvbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICJAY29tX2dvb2dsZV9kYWdnZXIiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGphdmF4X2luamVjdCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiRmlsZU5hbWVVdGlsIiwKKyAgICBzcmNzID0gWyJGaWxlTmFtZVV0aWwuamF2YSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJGaWxlVmFsaWRhdG9yIiwKKyAgICBzcmNzID0gWyJGaWxlVmFsaWRhdG9yLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyZWFtIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ1V0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpGaWxlR3JvdXBVdGlsIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJEb3dubG9hZGVyQ2FsbGJhY2tJbXBsIiwKKyAgICBzcmNzID0gWworICAgICAgICAiRG93bmxvYWRlckNhbGxiYWNrSW1wbC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICJNZGRGaWxlRG93bmxvYWRlciIsCisgICAgICAgICI6RmlsZU5hbWVVdGlsIiwKKyAgICAgICAgIjpGaWxlVmFsaWRhdG9yIiwKKyAgICAgICAgIjpaaXBGb2xkZXJPcGVuZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnJlY3Vyc2l2ZV9zaXplIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyZWFtIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOlNoYXJlZEZpbGVzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6RXZlbnRMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOkZpbGVHcm91cFV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3RyYWNpbmc6Y29uY3VycmVudCIsCisgICAgICAgICJAYW5kcm9pZHhfYW5ub3RhdGlvbl9hbm5vdGF0aW9uIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJEZWx0YUZpbGVEb3dubG9hZGVyQ2FsbGJhY2tJbXBsIiwKKyAgICBzcmNzID0gWyJEZWx0YUZpbGVEb3dubG9hZGVyQ2FsbGJhY2tJbXBsLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiTWRkRmlsZURvd25sb2FkZXIiLAorICAgICAgICAiOkRvd25sb2FkZXJDYWxsYmFja0ltcGwiLAorICAgICAgICAiOkZpbGVOYW1lVXRpbCIsCisgICAgICAgICI6RmlsZVZhbGlkYXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpTaWxlbnRGZWVkYmFjayIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZGVsdGE6RGVsdGFEZWNvZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkV2ZW50TG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ1V0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpEaXJlY3RvcnlVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nOmNvbmN1cnJlbnQiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIlppcEZvbGRlck9wZW5lciIsCisgICAgc3JjcyA9IFsiWmlwRm9sZGVyT3BlbmVyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW0iLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXIvRGVsdGFGaWxlRG93bmxvYWRlckNhbGxiYWNrSW1wbC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyL0RlbHRhRmlsZURvd25sb2FkZXJDYWxsYmFja0ltcGwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hODQzOTdhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyL0RlbHRhRmlsZURvd25sb2FkZXJDYWxsYmFja0ltcGwuamF2YQpAQCAtMCwwICsxLDI3NCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZG93bmxvYWRlcjsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmU7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZC5WRVJTSU9OOworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQuVkVSU0lPTl9DT0RFUzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbi5Eb3dubG9hZFJlc3VsdENvZGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuU2lsZW50RmVlZGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZGVsdGEuRGVsdGFEZWNvZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5TaGFyZWRGaWxlc01ldGFkYXRhOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmRvd25sb2FkZXIuTWRkRmlsZURvd25sb2FkZXIuRG93bmxvYWRlckNhbGxiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuRXZlbnRMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuRGlyZWN0b3J5VXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlByb3BhZ2F0ZWRGbHVlbnRGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5Qcm9wYWdhdGVkRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLkFzY2lpOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbC5BbGxvd2VkUmVhZGVyczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRlbHRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkZpbGVTdGF0dXM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLk5ld0ZpbGVLZXk7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKKworLyoqCisgKiBJbXBsIGZvciB7QGxpbmsgRG93bmxvYWRlckNhbGxiYWNrfSB0aGF0IGhhbmRsZXMgZGVsdGEgZG93bmxvYWQgZmlsZSwgdG8gcmVzdG9yZSBmdWxsIGZpbGUgd2l0aAorICogb24gZGV2aWNlIGJhc2UgZmlsZSBhbmQgdGhlIGRvd25sb2FkZWQgZGVsdGEgZmlsZS4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIERlbHRhRmlsZURvd25sb2FkZXJDYWxsYmFja0ltcGwgaW1wbGVtZW50cyBEb3dubG9hZGVyQ2FsbGJhY2sgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIkRlbHRhRmlsZURvd25sb2FkZXJDYWxsYmFja0ltcGwiOworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIGZpbmFsIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YTsKKyAgcHJpdmF0ZSBmaW5hbCBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIGZpbmFsIFNpbGVudEZlZWRiYWNrIHNpbGVudEZlZWRiYWNrOworICBwcml2YXRlIGZpbmFsIERhdGFGaWxlIGRhdGFGaWxlOworICBwcml2YXRlIGZpbmFsIEFsbG93ZWRSZWFkZXJzIGFsbG93ZWRSZWFkZXJzOworICBwcml2YXRlIGZpbmFsIERlbHRhRGVjb2RlciBkZWx0YURlY29kZXI7CisgIHByaXZhdGUgZmluYWwgRGVsdGFGaWxlIGRlbHRhRmlsZTsKKyAgcHJpdmF0ZSBmaW5hbCBFdmVudExvZ2dlciBldmVudExvZ2dlcjsKKyAgcHJpdmF0ZSBmaW5hbCBHcm91cEtleSBncm91cEtleTsKKyAgcHJpdmF0ZSBmaW5hbCBpbnQgZmlsZUdyb3VwVmVyc2lvbk51bWJlcjsKKyAgcHJpdmF0ZSBmaW5hbCBsb25nIGJ1aWxkSWQ7CisgIHByaXZhdGUgZmluYWwgU3RyaW5nIHZhcmlhbnRJZDsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQ7CisgIHByaXZhdGUgZmluYWwgRmxhZ3MgZmxhZ3M7CisgIHByaXZhdGUgZmluYWwgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKworICBwdWJsaWMgRGVsdGFGaWxlRG93bmxvYWRlckNhbGxiYWNrSW1wbCgKKyAgICAgIENvbnRleHQgY29udGV4dCwKKyAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsCisgICAgICBTaWxlbnRGZWVkYmFjayBzaWxlbnRGZWVkYmFjaywKKyAgICAgIERhdGFGaWxlIGRhdGFGaWxlLAorICAgICAgQWxsb3dlZFJlYWRlcnMgYWxsb3dlZFJlYWRlcnMsCisgICAgICBEZWx0YURlY29kZXIgZGVsdGFEZWNvZGVyLAorICAgICAgRGVsdGFGaWxlIGRlbHRhRmlsZSwKKyAgICAgIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyLAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksCisgICAgICBpbnQgZmlsZUdyb3VwVmVyc2lvbk51bWJlciwKKyAgICAgIGxvbmcgYnVpbGRJZCwKKyAgICAgIFN0cmluZyB2YXJpYW50SWQsCisgICAgICBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQsCisgICAgICBGbGFncyBmbGFncywKKyAgICAgIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpIHsKKyAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OworICAgIHRoaXMuc2hhcmVkRmlsZXNNZXRhZGF0YSA9IHNoYXJlZEZpbGVzTWV0YWRhdGE7CisgICAgdGhpcy5maWxlU3RvcmFnZSA9IGZpbGVTdG9yYWdlOworICAgIHRoaXMuc2lsZW50RmVlZGJhY2sgPSBzaWxlbnRGZWVkYmFjazsKKyAgICB0aGlzLmRhdGFGaWxlID0gZGF0YUZpbGU7CisgICAgdGhpcy5hbGxvd2VkUmVhZGVycyA9IGFsbG93ZWRSZWFkZXJzOworICAgIHRoaXMuZGVsdGFEZWNvZGVyID0gZGVsdGFEZWNvZGVyOworICAgIHRoaXMuZGVsdGFGaWxlID0gZGVsdGFGaWxlOworICAgIHRoaXMuZXZlbnRMb2dnZXIgPSBldmVudExvZ2dlcjsKKyAgICB0aGlzLmdyb3VwS2V5ID0gZ3JvdXBLZXk7CisgICAgdGhpcy5maWxlR3JvdXBWZXJzaW9uTnVtYmVyID0gZmlsZUdyb3VwVmVyc2lvbk51bWJlcjsKKyAgICB0aGlzLmJ1aWxkSWQgPSBidWlsZElkOworICAgIHRoaXMudmFyaWFudElkID0gdmFyaWFudElkOworICAgIHRoaXMuaW5zdGFuY2VJZCA9IGluc3RhbmNlSWQ7CisgICAgdGhpcy5mbGFncyA9IGZsYWdzOworICAgIHRoaXMuc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciA9IHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gb25Eb3dubG9hZENvbXBsZXRlKFVyaSBkZWx0YUZpbGVVcmkpIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBTdWNjZXNzZnVsbHkgZG93bmxvYWRlZCBkZWx0YSBmaWxlICVzIiwgVEFHLCBkZWx0YUZpbGVVcmkpOworCisgICAgaWYgKCFGaWxlVmFsaWRhdG9yLnZlcmlmeUNoZWNrc3VtKGZpbGVTdG9yYWdlLCBkZWx0YUZpbGVVcmksIGRlbHRhRmlsZS5nZXRDaGVja3N1bSgpKSkgeworICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICIlczogRG93bmxvYWRlZCBkZWx0YSBmaWxlIGF0IHVyaSA9ICVzLCBjaGVja3N1bSA9ICVzIHZlcmlmaWNhdGlvbiBmYWlsZWQiLAorICAgICAgICAgIFRBRywgZGVsdGFGaWxlVXJpLCBkZWx0YUZpbGUuZ2V0Q2hlY2tzdW0oKSk7CisgICAgICBEb3dubG9hZEV4Y2VwdGlvbiBleGNlcHRpb24gPQorICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5ET1dOTE9BREVEX0ZJTEVfQ0hFQ0tTVU1fTUlTTUFUQ0hfRVJST1IpCisgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgLy8gRmlsZSB3YXMgZG93bmxvYWRlZCBzdWNjZXNzZnVsbHksIGJ1dCBmYWlsZWQgY2hlY2tzdW0gbWlzbWF0Y2ggZXJyb3IuIFRoaXMgaW5kaWNhdGVzIGEKKyAgICAgIC8vIGNvcnJ1cHRlZCBmaWxlIHRoYXQgc2hvdWxkIGJlIGRlbGV0ZWQgc28gTUREIGNhbiBhdHRlbXB0IHRvIHJlZG93bmxvYWQgZnJvbSBzY3JhdGNoLgorICAgICAgcmV0dXJuIFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmUuZnJvbSgKKyAgICAgICAgICAgICAgRG93bmxvYWRlckNhbGxiYWNrSW1wbC5tYXliZURlbGV0ZUZpbGVPbkNoZWNrc3VtTWlzbWF0Y2goCisgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICAgICAgICAgICAgZGF0YUZpbGUsCisgICAgICAgICAgICAgICAgICBhbGxvd2VkUmVhZGVycywKKyAgICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgICAgICAgZGVsdGFGaWxlVXJpLAorICAgICAgICAgICAgICAgICAgZGVsdGFGaWxlLmdldENoZWNrc3VtKCksCisgICAgICAgICAgICAgICAgICBldmVudExvZ2dlciwKKyAgICAgICAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikpCisgICAgICAgICAgLmNhdGNoaW5nQXN5bmMoCisgICAgICAgICAgICAgIElPRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICBpb0V4Y2VwdGlvbiAtPiB7CisgICAgICAgICAgICAgICAgLy8gRGVsZXRlIG9uIGNoZWNrc3VtIGZhaWxlZCwgYWRkIGl0IGFzIGEgc3VwcHJlc3NlZCBleGNlcHRpb24gaWYgc3VwcG9ydGVkIChBUEkKKyAgICAgICAgICAgICAgICAvLyBsZXZlbCAxOSBvciBoaWdoZXIpLgorICAgICAgICAgICAgICAgIGlmIChWRVJTSU9OLlNES19JTlQgPj0gVkVSU0lPTl9DT0RFUy5LSVRLQVQpIHsKKyAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5hZGRTdXBwcmVzc2VkKGlvRXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikKKyAgICAgICAgICAudHJhbnNmb3JtQXN5bmModW51c2VkIC0+IGltbWVkaWF0ZUZhaWxlZEZ1dHVyZShleGNlcHRpb24pLCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICB9CisKKyAgICBVcmkgZnVsbEZpbGVVcmkgPSBGaWxlTmFtZVV0aWwuZ2V0RmluYWxGaWxlVXJpV2l0aFRlbXBEb3dubG9hZGVkRmlsZShkZWx0YUZpbGVVcmkpOworICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgaGFuZGxlRGVsdGFEb3dubG9hZEZpbGUoZnVsbEZpbGVVcmksIGRlbHRhRmlsZVVyaSksCisgICAgICAgIHZvaWRBcmcgLT4geworICAgICAgICAgIC8vIFRPRE8oYi8xNDkyNjA0OTYpOiBvbmNlIERlbHRhRG93bmxvYWRlciBzdXBwb3J0cyBzaGFyZWQgZmlsZXMsIHdoaWNoIGhhdmUgQ2hlY2tzdW1UeXBlCisgICAgICAgICAgLy8gPT0gU0hBMjU2LCBjaGFuZ2UgZnJvbSBEYXRhRmlsZS5DaGVja3N1bVR5cGUuREZFRkFVTFQgdG8gZGF0YUZpbGUuZ2V0Q2hlY2tzdW1UeXBlKCkuCisgICAgICAgICAgaWYgKCFGaWxlVmFsaWRhdG9yLnZlcmlmeUNoZWNrc3VtKGZpbGVTdG9yYWdlLCBmdWxsRmlsZVVyaSwgZGF0YUZpbGUuZ2V0Q2hlY2tzdW0oKSkpIHsKKyAgICAgICAgICAgIExvZ1V0aWwuZSgiJXM6IEZpbmFsIGZpbGUgY2hlY2tzdW0gdmVyaWZpY2F0aW9uIGZhaWxlZC4gJXMuIiwgVEFHLCBmdWxsRmlsZVVyaSk7CisgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5GSU5BTF9GSUxFX0NIRUNLU1VNX01JU01BVENIX0VSUk9SKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgcmV0dXJuIERvd25sb2FkZXJDYWxsYmFja0ltcGwudXBkYXRlRmlsZVN0YXR1cygKKyAgICAgICAgICAgICAgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSwKKyAgICAgICAgICAgICAgZGF0YUZpbGUsCisgICAgICAgICAgICAgIGFsbG93ZWRSZWFkZXJzLAorICAgICAgICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gb25Eb3dubG9hZEZhaWxlZChEb3dubG9hZEV4Y2VwdGlvbiBleGNlcHRpb24pIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBGYWlsZWQgdG8gZG93bmxvYWQgZmlsZShkZWx0YSkgJXMiLCBUQUcsIGRhdGFGaWxlLmdldENoZWNrc3VtKCkpOworICAgIGlmIChleGNlcHRpb24KKyAgICAgICAgLmdldERvd25sb2FkUmVzdWx0Q29kZSgpCisgICAgICAgIC5lcXVhbHMoRG93bmxvYWRSZXN1bHRDb2RlLkRPV05MT0FERURfRklMRV9DSEVDS1NVTV9NSVNNQVRDSF9FUlJPUikpIHsKKyAgICAgIHJldHVybiBEb3dubG9hZGVyQ2FsbGJhY2tJbXBsLnVwZGF0ZUZpbGVTdGF0dXMoCisgICAgICAgICAgRmlsZVN0YXR1cy5DT1JSVVBURUQsCisgICAgICAgICAgZGF0YUZpbGUsCisgICAgICAgICAgYWxsb3dlZFJlYWRlcnMsCisgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICB9CisgICAgcmV0dXJuIERvd25sb2FkZXJDYWxsYmFja0ltcGwudXBkYXRlRmlsZVN0YXR1cygKKyAgICAgICAgRmlsZVN0YXR1cy5ET1dOTE9BRF9GQUlMRUQsCisgICAgICAgIGRhdGFGaWxlLAorICAgICAgICBhbGxvd2VkUmVhZGVycywKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gaGFuZGxlRGVsdGFEb3dubG9hZEZpbGUoVXJpIGZ1bGxGaWxlVXJpLCBVcmkgZGVsdGFGaWxlVXJpKSB7CisgICAgTmV3RmlsZUtleSBiYXNlRmlsZUtleSA9CisgICAgICAgIE5ld0ZpbGVLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oZGVsdGFGaWxlLmdldEJhc2VGaWxlKCkuZ2V0Q2hlY2tzdW0oKSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVycyhhbGxvd2VkUmVhZGVycykKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKGJhc2VGaWxlS2V5KSwKKyAgICAgICAgYmFzZUZpbGVNZXRhZGF0YSAtPiB7CisgICAgICAgICAgVXJpIGJhc2VGaWxlVXJpID0gbnVsbDsKKyAgICAgICAgICBpZiAoYmFzZUZpbGVNZXRhZGF0YSAhPSBudWxsCisgICAgICAgICAgICAgICYmIGJhc2VGaWxlTWV0YWRhdGEuZ2V0RmlsZVN0YXR1cygpID09IEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpIHsKKyAgICAgICAgICAgIGJhc2VGaWxlVXJpID0KKyAgICAgICAgICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE9uRGV2aWNlVXJpKAorICAgICAgICAgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgICAgICAgICBhbGxvd2VkUmVhZGVycywKKyAgICAgICAgICAgICAgICAgICAgYmFzZUZpbGVNZXRhZGF0YS5nZXRGaWxlTmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBiYXNlRmlsZUtleS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgICAgICAgICBzaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZCwKKyAgICAgICAgICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICBpZiAoYmFzZUZpbGVVcmkgPT0gbnVsbCkgeworICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIERvd25sb2FkUmVzdWx0Q29kZS5ERUxUQV9ET1dOTE9BRF9CQVNFX0ZJTEVfTk9UX0ZPVU5EX0VSUk9SKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIGRlY29kZURlbHRhRmlsZShiYXNlRmlsZVVyaSwgZnVsbEZpbGVVcmksIGRlbHRhRmlsZVVyaSk7CisgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICAgICAgIGUsCisgICAgICAgICAgICAgICAgIiVzOiBGYWlsZWQgdG8gZGVjb2RlIGRlbHRhIGZpbGUgd2l0aCB1cmwgPSAlcyBmYWlsZWQuIGNoZWNrc3VtID0gJXMgIiwKKyAgICAgICAgICAgICAgICBUQUcsCisgICAgICAgICAgICAgICAgZGVsdGFGaWxlLmdldFVybFRvRG93bmxvYWQoKSwKKyAgICAgICAgICAgICAgICBkYXRhRmlsZS5nZXRDaGVja3N1bSgpKTsKKyAgICAgICAgICAgIHNpbGVudEZlZWRiYWNrLnNlbmQoZSwgIkZhaWxlZCB0byBkZWNvZGUgZGVsdGEgZmlsZS4iKTsKKyAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLkRFTFRBX0RPV05MT0FEX0RFQ09ERV9JT19FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgLnNldENhdXNlKGUpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgVm9pZCBmaWxlR3JvdXBTdGF0cyA9IG51bGw7CisgICAgICAgICAgZXZlbnRMb2dnZXIubG9nTWRkTmV0d29ya1NhdmluZ3MoCisgICAgICAgICAgICAgIGZpbGVHcm91cFN0YXRzLAorICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICBkYXRhRmlsZS5nZXRCeXRlU2l6ZSgpLAorICAgICAgICAgICAgICBkZWx0YUZpbGUuZ2V0Qnl0ZVNpemUoKSwKKyAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0RmlsZUlkKCksCisgICAgICAgICAgICAgIGdldERlbHRhRmlsZUluZGV4KCkpOworICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgcHJpdmF0ZSBpbnQgZ2V0RGVsdGFGaWxlSW5kZXgoKSB7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkYXRhRmlsZS5nZXREZWx0YUZpbGVDb3VudCgpOyBpKyspIHsKKyAgICAgIGlmIChBc2NpaS5lcXVhbHNJZ25vcmVDYXNlKGRhdGFGaWxlLmdldERlbHRhRmlsZShpKS5nZXRDaGVja3N1bSgpLCBkZWx0YUZpbGUuZ2V0Q2hlY2tzdW0oKSkpIHsKKyAgICAgICAgcmV0dXJuIGkgKyAxOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBkZWNvZGVEZWx0YUZpbGUoVXJpIGJhc2VGaWxlVXJpLCBVcmkgZnVsbEZpbGVVcmksIFVyaSBkZWx0YUZpbGVVcmkpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGlmIChmaWxlU3RvcmFnZS5leGlzdHMoZnVsbEZpbGVVcmkpKSB7CisgICAgICAvLyBEZWxldGUgaWYgdGhlIGZ1bGwgZmlsZSB3YXMgcGFydGlhbGx5IGRvd25sb2FkZWQgYmVmb3JlLgorICAgICAgZmlsZVN0b3JhZ2UuZGVsZXRlRmlsZShmdWxsRmlsZVVyaSk7CisgICAgfQorICAgIGRlbHRhRGVjb2Rlci5kZWNvZGUoYmFzZUZpbGVVcmksIGRlbHRhRmlsZVVyaSwgZnVsbEZpbGVVcmkpOworICAgIC8vIE9ubHkgZGVsZXRlIGRlbHRhIGZpbGUgb24gc3VjY2VzcyBjYXNlLiBOb3QgZGVsZXRlIGFuZCByZS1kb3dubG9hZCBpZiBkZWNvZGUgZmFpbHMgYXMgaXQgaXMKKyAgICAvLyBtb3N0IGxpa2VseSBjb25maWd1cmF0aW9uIGlzc3VlLgorICAgIC8vIFRPRE8oYi8xMjM1ODQ4OTApOiBEZWxldGUgZGVsdGEgZmlsZSBvbiBkZWNvZGUgZmFpbHVyZSBvbmNlIE1ERCBzZXJ2ZXIgdGVzdCBpcyBpbiBwbGFjZS4KKyAgICBmaWxlU3RvcmFnZS5kZWxldGVGaWxlKGRlbHRhRmlsZVVyaSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlci9Eb3dubG9hZGVyQ2FsbGJhY2tJbXBsLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXIvRG93bmxvYWRlckNhbGxiYWNrSW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg5NzI2MWQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXIvRG93bmxvYWRlckNhbGxiYWNrSW1wbC5qYXZhCkBAIC0wLDAgKzEsNDUxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kb3dubG9hZGVyOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQuVkVSU0lPTjsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkLlZFUlNJT05fQ09ERVM7CitpbXBvcnQgYW5kcm9pZHguYW5ub3RhdGlvbi5WaXNpYmxlRm9yVGVzdGluZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbi5Eb3dubG9hZFJlc3VsdENvZGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWFkU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWN1cnNpdmVTaXplT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5Xcml0ZVN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuVHJhbnNmb3JtUHJvdG9zOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLlNoYXJlZEZpbGVzTWV0YWRhdGE7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZG93bmxvYWRlci5NZGRGaWxlRG93bmxvYWRlci5Eb3dubG9hZGVyQ2FsbGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5FdmVudExvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5GaWxlR3JvdXBVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRyYWNpbmcuUHJvcGFnYXRlZEZsdWVudEZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlByb3BhZ2F0ZWRGdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmlvLkJ5dGVTdHJlYW1zOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwSW50ZXJuYWwuQWxsb3dlZFJlYWRlcnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5GaWxlU3RhdHVzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uR3JvdXBLZXk7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5OZXdGaWxlS2V5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uU2hhcmVkRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CisKKy8qKgorICogSW1wbCBmb3Ige0BsaW5rIERvd25sb2FkZXJDYWxsYmFja30sIHRoYXQgaXMgY2FsbGVkIGJ5IHRoZSBmaWxlIGRvd25sb2FkZXIgb24gZG93bmxvYWQgY29tcGxldGUKKyAqIG9yIGZhaWxlZCBldmVudHMKKyAqLworcHVibGljIGNsYXNzIERvd25sb2FkZXJDYWxsYmFja0ltcGwgaW1wbGVtZW50cyBEb3dubG9hZGVyQ2FsbGJhY2sgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiRG93bmxvYWRlckNhbGxiYWNrSW1wbCI7CisKKyAgcHJpdmF0ZSBmaW5hbCBTaGFyZWRGaWxlc01ldGFkYXRhIHNoYXJlZEZpbGVzTWV0YWRhdGE7CisgIHByaXZhdGUgZmluYWwgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHJpdmF0ZSBmaW5hbCBEYXRhRmlsZSBkYXRhRmlsZTsKKyAgcHJpdmF0ZSBmaW5hbCBBbGxvd2VkUmVhZGVycyBhbGxvd2VkUmVhZGVyczsKKyAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgY2hlY2tzdW07CisgIHByaXZhdGUgZmluYWwgRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXI7CisgIHByaXZhdGUgZmluYWwgR3JvdXBLZXkgZ3JvdXBLZXk7CisgIHByaXZhdGUgZmluYWwgaW50IGZpbGVHcm91cFZlcnNpb25OdW1iZXI7CisgIHByaXZhdGUgZmluYWwgbG9uZyBidWlsZElkOworICBwcml2YXRlIGZpbmFsIFN0cmluZyB2YXJpYW50SWQ7CisgIHByaXZhdGUgZmluYWwgRmxhZ3MgZmxhZ3M7CisgIHByaXZhdGUgZmluYWwgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKworICBwdWJsaWMgRG93bmxvYWRlckNhbGxiYWNrSW1wbCgKKyAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsCisgICAgICBEYXRhRmlsZSBkYXRhRmlsZSwKKyAgICAgIEFsbG93ZWRSZWFkZXJzIGFsbG93ZWRSZWFkZXJzLAorICAgICAgRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXIsCisgICAgICBHcm91cEtleSBncm91cEtleSwKKyAgICAgIGludCBmaWxlR3JvdXBWZXJzaW9uTnVtYmVyLAorICAgICAgbG9uZyBidWlsZElkLAorICAgICAgU3RyaW5nIHZhcmlhbnRJZCwKKyAgICAgIEZsYWdzIGZsYWdzLAorICAgICAgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikgeworICAgIHRoaXMuc2hhcmVkRmlsZXNNZXRhZGF0YSA9IHNoYXJlZEZpbGVzTWV0YWRhdGE7CisgICAgdGhpcy5maWxlU3RvcmFnZSA9IGZpbGVTdG9yYWdlOworICAgIHRoaXMuZGF0YUZpbGUgPSBkYXRhRmlsZTsKKyAgICB0aGlzLmFsbG93ZWRSZWFkZXJzID0gYWxsb3dlZFJlYWRlcnM7CisgICAgY2hlY2tzdW0gPSBGaWxlR3JvdXBVdGlsLmdldEZpbGVDaGVja3N1bShkYXRhRmlsZSk7CisgICAgdGhpcy5ldmVudExvZ2dlciA9IGV2ZW50TG9nZ2VyOworICAgIHRoaXMuZ3JvdXBLZXkgPSBncm91cEtleTsKKyAgICB0aGlzLmZpbGVHcm91cFZlcnNpb25OdW1iZXIgPSBmaWxlR3JvdXBWZXJzaW9uTnVtYmVyOworICAgIHRoaXMuYnVpbGRJZCA9IGJ1aWxkSWQ7CisgICAgdGhpcy52YXJpYW50SWQgPSB2YXJpYW50SWQ7CisgICAgdGhpcy5mbGFncyA9IGZsYWdzOworICAgIHRoaXMuc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciA9IHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gb25Eb3dubG9hZENvbXBsZXRlKFVyaSBmaWxlVXJpKSB7CisgICAgTG9nVXRpbC5kKCIlczogU3VjY2Vzc2Z1bGx5IGRvd25sb2FkZWQgZmlsZSAlcyIsIFRBRywgY2hlY2tzdW0pOworCisgICAgLy8gVXNlIERvd25sb2FkZWRGaWxlQ2hlY2tzdW0gdG8gdmVyaWZ5IGRvd25sb2FkZWQgZmlsZSBpbnRlZ3JpdHkgaWYgdGhlIGZpbGUgaGFzIERvd25sb2FkCisgICAgLy8gVHJhbnNmb3JtcworICAgIFN0cmluZyBkb3dubG9hZGVkRmlsZUNoZWNrc3VtID0KKyAgICAgICAgZGF0YUZpbGUuaGFzRG93bmxvYWRUcmFuc2Zvcm1zKCkKKyAgICAgICAgICAgID8gZGF0YUZpbGUuZ2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bSgpCisgICAgICAgICAgICA6IGRhdGFGaWxlLmdldENoZWNrc3VtKCk7CisKKyAgICB0cnkgeworICAgICAgRmlsZVZhbGlkYXRvci52YWxpZGF0ZURvd25sb2FkZWRGaWxlKGZpbGVTdG9yYWdlLCBkYXRhRmlsZSwgZmlsZVVyaSwgZG93bmxvYWRlZEZpbGVDaGVja3N1bSk7CisKKyAgICAgIGlmIChkYXRhRmlsZS5oYXNEb3dubG9hZFRyYW5zZm9ybXMoKSkgeworICAgICAgICBoYW5kbGVEb3dubG9hZFRyYW5zZm9ybShmaWxlVXJpKTsKKyAgICAgIH0KKyAgICB9IGNhdGNoIChEb3dubG9hZEV4Y2VwdGlvbiBleGNlcHRpb24pIHsKKyAgICAgIGlmIChleGNlcHRpb24KKyAgICAgICAgICAuZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkKKyAgICAgICAgICAuZXF1YWxzKERvd25sb2FkUmVzdWx0Q29kZS5ET1dOTE9BREVEX0ZJTEVfQ0hFQ0tTVU1fTUlTTUFUQ0hfRVJST1IpKSB7CisgICAgICAgIC8vIEZpbGUgd2FzIGRvd25sb2FkZWQgc3VjY2Vzc2Z1bGx5LCBidXQgZmFpbGVkIGNoZWNrc3VtIG1pc21hdGNoIGVycm9yLiBBdHRlbXB0IHRvIGRlbGV0ZQorICAgICAgICAvLyB0aGUgZmlsZSwgdGhlbiBmYWlsIHdpdGggdGhlIGdpdmVuIGV4Y2VwdGlvbi4KKyAgICAgICAgcmV0dXJuIFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmUuZnJvbSgKKyAgICAgICAgICAgICAgICBtYXliZURlbGV0ZUZpbGVPbkNoZWNrc3VtTWlzbWF0Y2goCisgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgICAgICAgICAgICAgIGRhdGFGaWxlLAorICAgICAgICAgICAgICAgICAgICBhbGxvd2VkUmVhZGVycywKKyAgICAgICAgICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAgICAgICAgIGZpbGVVcmksCisgICAgICAgICAgICAgICAgICAgIGNoZWNrc3VtLAorICAgICAgICAgICAgICAgICAgICBldmVudExvZ2dlciwKKyAgICAgICAgICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpKQorICAgICAgICAgICAgLmNhdGNoaW5nQXN5bmMoCisgICAgICAgICAgICAgICAgSU9FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAgICAgaW9FeGNlcHRpb24gLT4geworICAgICAgICAgICAgICAgICAgLy8gRGVsZXRlIG9uIGNoZWNrc3VtIGZhaWxlZCwgYWRkIGl0IGFzIGEgc3VwcHJlc3NlZCBleGNlcHRpb24gaWYgc3VwcG9ydGVkIChBUEkKKyAgICAgICAgICAgICAgICAgIC8vIGxldmVsIDE5IG9yIGhpZ2hlcikuCisgICAgICAgICAgICAgICAgICBpZiAoVkVSU0lPTi5TREtfSU5UID49IFZFUlNJT05fQ09ERVMuS0lUS0FUKSB7CisgICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbi5hZGRTdXBwcmVzc2VkKGlvRXhjZXB0aW9uKTsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAgICAgLnRyYW5zZm9ybUFzeW5jKHVudXNlZCAtPiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoZXhjZXB0aW9uKSwgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICB9CisgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGV4Y2VwdGlvbik7CisgICAgfQorCisgICAgcmV0dXJuIHVwZGF0ZUZpbGVTdGF0dXMoCisgICAgICAgIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsCisgICAgICAgIGRhdGFGaWxlLAorICAgICAgICBhbGxvd2VkUmVhZGVycywKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gb25Eb3dubG9hZEZhaWxlZChEb3dubG9hZEV4Y2VwdGlvbiBleGNlcHRpb24pIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBGYWlsZWQgdG8gZG93bmxvYWQgZmlsZSAlcyIsIFRBRywgY2hlY2tzdW0pOworICAgIGlmIChleGNlcHRpb24KKyAgICAgICAgLmdldERvd25sb2FkUmVzdWx0Q29kZSgpCisgICAgICAgIC5lcXVhbHMoRG93bmxvYWRSZXN1bHRDb2RlLkRPV05MT0FERURfRklMRV9DSEVDS1NVTV9NSVNNQVRDSF9FUlJPUikpIHsKKyAgICAgIHJldHVybiB1cGRhdGVGaWxlU3RhdHVzKAorICAgICAgICAgIEZpbGVTdGF0dXMuQ09SUlVQVEVELAorICAgICAgICAgIGRhdGFGaWxlLAorICAgICAgICAgIGFsbG93ZWRSZWFkZXJzLAorICAgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgfQorICAgIHJldHVybiB1cGRhdGVGaWxlU3RhdHVzKAorICAgICAgICBGaWxlU3RhdHVzLkRPV05MT0FEX0ZBSUxFRCwKKyAgICAgICAgZGF0YUZpbGUsCisgICAgICAgIGFsbG93ZWRSZWFkZXJzLAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBoYW5kbGVEb3dubG9hZFRyYW5zZm9ybShVcmkgZG93bmxvYWRlZEZpbGVVcmkpIHRocm93cyBEb3dubG9hZEV4Y2VwdGlvbiB7CisgICAgaWYgKCFkYXRhRmlsZS5oYXNEb3dubG9hZFRyYW5zZm9ybXMoKSkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBVcmkgZmluYWxGaWxlVXJpID0gRmlsZU5hbWVVdGlsLmdldEZpbmFsRmlsZVVyaVdpdGhUZW1wRG93bmxvYWRlZEZpbGUoZG93bmxvYWRlZEZpbGVVcmkpOworICAgIGlmIChGaWxlR3JvdXBVdGlsLmhhc1ppcERvd25sb2FkVHJhbnNmb3JtKGRhdGFGaWxlKSkgeworICAgICAgYXBwbHlaaXBEb3dubG9hZFRyYW5zZm9ybXMoCisgICAgICAgICAgZXZlbnRMb2dnZXIsCisgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgZG93bmxvYWRlZEZpbGVVcmksCisgICAgICAgICAgZmluYWxGaWxlVXJpLAorICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgIGZpbGVHcm91cFZlcnNpb25OdW1iZXIsCisgICAgICAgICAgYnVpbGRJZCwKKyAgICAgICAgICB2YXJpYW50SWQsCisgICAgICAgICAgZGF0YUZpbGUuZ2V0RmlsZUlkKCkpOworICAgIH0gZWxzZSB7CisgICAgICBoYW5kbGVOb25aaXBEb3dubG9hZFRyYW5zZm9ybShkb3dubG9hZGVkRmlsZVVyaSwgZmluYWxGaWxlVXJpKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgaGFuZGxlTm9uWmlwRG93bmxvYWRUcmFuc2Zvcm0oVXJpIGRvd25sb2FkZWRGaWxlVXJpLCBVcmkgZmluYWxGaWxlVXJpKQorICAgICAgdGhyb3dzIERvd25sb2FkRXhjZXB0aW9uIHsKKyAgICBVcmkgZG93bmxvYWRGaWxlVXJpV2l0aFRyYW5zZm9ybTsKKyAgICB0cnkgeworICAgICAgZG93bmxvYWRGaWxlVXJpV2l0aFRyYW5zZm9ybSA9CisgICAgICAgICAgZG93bmxvYWRlZEZpbGVVcmkKKyAgICAgICAgICAgICAgLmJ1aWxkVXBvbigpCisgICAgICAgICAgICAgIC5lbmNvZGVkRnJhZ21lbnQoVHJhbnNmb3JtUHJvdG9zLnRvRW5jb2RlZEZyYWdtZW50KGRhdGFGaWxlLmdldERvd25sb2FkVHJhbnNmb3JtcygpKSkKKyAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgIExvZ1V0aWwuZShlLCAiJXM6IEV4Y2VwdGlvbiB3aGlsZSB0cnlpbmcgdG8gc2VyaWFsaXplIGRvd25sb2FkIHRyYW5zZm9ybSIsIFRBRyk7CisgICAgICB0aHJvdyBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5VTkFCTEVfVE9fU0VSSUFMSVpFX0RPV05MT0FEX1RSQU5TRk9STV9FUlJPUikKKyAgICAgICAgICAuc2V0Q2F1c2UoZSkKKyAgICAgICAgICAuYnVpbGQoKTsKKyAgICB9CisgICAgYXBwbHlEb3dubG9hZFRyYW5zZm9ybXMoCisgICAgICAgIGV2ZW50TG9nZ2VyLAorICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgZG93bmxvYWRGaWxlVXJpV2l0aFRyYW5zZm9ybSwKKyAgICAgICAgZmluYWxGaWxlVXJpLAorICAgICAgICBncm91cEtleSwKKyAgICAgICAgZmlsZUdyb3VwVmVyc2lvbk51bWJlciwKKyAgICAgICAgYnVpbGRJZCwKKyAgICAgICAgdmFyaWFudElkLAorICAgICAgICBkYXRhRmlsZSk7CisgICAgLy8gVmVyaWZ5IG9yaWdpbmFsIGNoZWNrc3VtIGlmIHByb3ZpZGVkLgorICAgIGlmIChkYXRhRmlsZS5nZXRDaGVja3N1bVR5cGUoKSAhPSBEYXRhRmlsZS5DaGVja3N1bVR5cGUuTk9ORQorICAgICAgICAmJiAhRmlsZVZhbGlkYXRvci52ZXJpZnlDaGVja3N1bShmaWxlU3RvcmFnZSwgZmluYWxGaWxlVXJpLCBjaGVja3N1bSkpIHsKKyAgICAgIExvZ1V0aWwuZSgiJXM6IEZpbmFsIGZpbGUgY2hlY2tzdW0gdmVyaWZpY2F0aW9uIGZhaWxlZC4gJXMuIiwgVEFHLCBmaW5hbEZpbGVVcmkpOworICAgICAgdGhyb3cgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuRklOQUxfRklMRV9DSEVDS1NVTV9NSVNNQVRDSF9FUlJPUikKKyAgICAgICAgICAuYnVpbGQoKTsKKyAgICB9CisgIH0KKworICBAVmlzaWJsZUZvclRlc3RpbmcKKyAgc3RhdGljIHZvaWQgYXBwbHlEb3dubG9hZFRyYW5zZm9ybXMoCisgICAgICBFdmVudExvZ2dlciBldmVudExvZ2dlciwKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsCisgICAgICBVcmkgc291cmNlLAorICAgICAgVXJpIHRhcmdldCwKKyAgICAgIEdyb3VwS2V5IGdyb3VwS2V5LAorICAgICAgaW50IGZpbGVHcm91cFZlcnNpb25OdW1iZXIsCisgICAgICBsb25nIGJ1aWxkSWQsCisgICAgICBTdHJpbmcgdmFyaWFudElkLAorICAgICAgRGF0YUZpbGUgZGF0YUZpbGUpCisgICAgICB0aHJvd3MgRG93bmxvYWRFeGNlcHRpb24geworCisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9IGZpbGVTdG9yYWdlLm9wZW4oc291cmNlLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IGZpbGVTdG9yYWdlLm9wZW4odGFyZ2V0LCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIEJ5dGVTdHJlYW1zLmNvcHkoaW4sIG91dCk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICBMb2dVdGlsLmUoaW9lLCAiJXM6IEZhaWxlZCB0byBhcHBseSBkb3dubG9hZCB0cmFuc2Zvcm0gZm9yIGZpbGUgJXMuIiwgVEFHLCBzb3VyY2UpOworICAgICAgdGhyb3cgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuRE9XTkxPQURfVFJBTlNGT1JNX0lPX0VSUk9SKQorICAgICAgICAgIC5zZXRDYXVzZShpb2UpCisgICAgICAgICAgLmJ1aWxkKCk7CisgICAgfQorICAgIHRyeSB7CisgICAgICBpZiAoRmlsZUdyb3VwVXRpbC5oYXNDb21wcmVzc0Rvd25sb2FkVHJhbnNmb3JtKGRhdGFGaWxlKSkgeworICAgICAgICBsb25nIGZ1bGxGaWxlU2l6ZSA9IGZpbGVTdG9yYWdlLmZpbGVTaXplKHRhcmdldCk7CisgICAgICAgIGxvbmcgZG93bmxvYWRlZEZpbGVTaXplID0gZmlsZVN0b3JhZ2UuZmlsZVNpemUoc291cmNlKTsKKyAgICAgICAgaWYgKGZ1bGxGaWxlU2l6ZSA+IGRvd25sb2FkZWRGaWxlU2l6ZSkgeworICAgICAgICAgIFZvaWQgZmlsZUdyb3VwU3RhdHMgPSBudWxsOworICAgICAgICAgIGV2ZW50TG9nZ2VyLmxvZ01kZE5ldHdvcmtTYXZpbmdzKAorICAgICAgICAgICAgICBmaWxlR3JvdXBTdGF0cywKKyAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgZnVsbEZpbGVTaXplLAorICAgICAgICAgICAgICBkb3dubG9hZGVkRmlsZVNpemUsCisgICAgICAgICAgICAgIGRhdGFGaWxlLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgICAvKiBkZWx0YUluZGV4ID0gKi8gMCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGZpbGVTdG9yYWdlLmRlbGV0ZUZpbGUoc291cmNlKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKKyAgICAgIC8vIElnbm9yZSBpZiBmYWlscyB0byBsb2cgZmlsZSBzaXplIG9yIGRlbGV0ZSB0aGUgdGVtcCBjb21wcmVzcyBmaWxlLCBhcyBpdCB3aWxsIGV2ZW50dWFsbHkKKyAgICAgIC8vIGJlIGdhcmJhZ2UgY29sbGVjdGVkLgorICAgICAgTG9nVXRpbC5kKGlvZSwgIiVzOiBGYWlsZWQgdG8gZ2V0IGZpbGUgc2l6ZSBvciBkZWxldGUgY29tcHJlc3MgZmlsZSAlcy4iLCBUQUcsIHNvdXJjZSk7CisgICAgfQorICB9CisKKyAgQFZpc2libGVGb3JUZXN0aW5nCisgIHN0YXRpYyB2b2lkIGFwcGx5WmlwRG93bmxvYWRUcmFuc2Zvcm1zKAorICAgICAgRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXIsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLAorICAgICAgVXJpIHNvdXJjZSwKKyAgICAgIFVyaSB0YXJnZXQsCisgICAgICBHcm91cEtleSBncm91cEtleSwKKyAgICAgIGludCBmaWxlR3JvdXBWZXJzaW9uTnVtYmVyLAorICAgICAgbG9uZyBidWlsZElkLAorICAgICAgU3RyaW5nIHZhcmlhbnRJZCwKKyAgICAgIFN0cmluZyBmaWxlSWQpCisgICAgICB0aHJvd3MgRG93bmxvYWRFeGNlcHRpb24geworCisgICAgdHJ5IHsKKyAgICAgIGZpbGVTdG9yYWdlLm9wZW4oc291cmNlLCBaaXBGb2xkZXJPcGVuZXIuY3JlYXRlKHRhcmdldCkpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgTG9nVXRpbC5lKGlvZSwgIiVzOiBGYWlsZWQgdG8gYXBwbHkgemlwIGRvd25sb2FkIHRyYW5zZm9ybSBmb3IgZmlsZSAlcy4iLCBUQUcsIHNvdXJjZSk7CisgICAgICB0aHJvdyBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5ET1dOTE9BRF9UUkFOU0ZPUk1fSU9fRVJST1IpCisgICAgICAgICAgLnNldENhdXNlKGlvZSkKKyAgICAgICAgICAuYnVpbGQoKTsKKyAgICB9CisgICAgdHJ5IHsKKyAgICAgIFZvaWQgZmlsZUdyb3VwU3RhdHMgPSBudWxsOworICAgICAgZXZlbnRMb2dnZXIubG9nTWRkTmV0d29ya1NhdmluZ3MoCisgICAgICAgICAgZmlsZUdyb3VwU3RhdHMsCisgICAgICAgICAgMCwKKyAgICAgICAgICBnZXRGaWxlT3JEaXJlY3RvcnlTaXplKGZpbGVTdG9yYWdlLCB0YXJnZXQpLAorICAgICAgICAgIGZpbGVTdG9yYWdlLmZpbGVTaXplKHNvdXJjZSksCisgICAgICAgICAgZmlsZUlkLAorICAgICAgICAgIDApOworICAgICAgLy8gRGVsZXRlIHRoZSB6aXAgZmlsZSBvbmx5IGlmIHVuemlwIHN1Y2Nlc3NmdWxseSB0byBhdm9pZCByZS1kb3dubG9hZAorICAgICAgZmlsZVN0b3JhZ2UuZGVsZXRlRmlsZShzb3VyY2UpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgeworICAgICAgLy8gSWdub3JlIGlmIGZhaWxzIHRvIGxvZyBmaWxlIHNpemUgb3IgZGVsZXRlIHRoZSB0ZW1wIHppcCBmaWxlLCBhcyBpdCB3aWxsIGV2ZW50dWFsbHkgYmUKKyAgICAgIC8vIGdhcmJhZ2UgY29sbGVjdGVkLgorICAgICAgTG9nVXRpbC5kKGlvZSwgIiVzOiBGYWlsZWQgdG8gZ2V0IGZpbGUgc2l6ZSBvciBkZWxldGUgemlwIGZpbGUgJXMuIiwgVEFHLCBzb3VyY2UpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGxvbmcgZ2V0RmlsZU9yRGlyZWN0b3J5U2l6ZShTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLCBVcmkgdXJpKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gZmlsZVN0b3JhZ2Uub3Blbih1cmksIFJlY3Vyc2l2ZVNpemVPcGVuZXIuY3JlYXRlKCkpOworICB9CisKKyAgLyoqIEdldCB7QGxpbmsgU2hhcmVkRmlsZX0gb3IgZmFpbCB3aXRoIHtAbGluayBEb3dubG9hZEV4Y2VwdGlvbn0uICovCisgIHByaXZhdGUgc3RhdGljIExpc3RlbmFibGVGdXR1cmU8U2hhcmVkRmlsZT4gZ2V0U2hhcmVkRmlsZU9yRmFpbCgKKyAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSwKKyAgICAgIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpIHsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChuZXdGaWxlS2V5KSwKKyAgICAgICAgc2hhcmVkRmlsZSAtPiB7CisgICAgICAgICAgLy8gQ2Fubm90IGZpbmQgdGhlIGZpbGUgbWV0YWRhdGEsIGZhaWwgdG8gdXBkYXRlIHRoZSBmaWxlIHN0YXR1cy4KKyAgICAgICAgICBpZiAoc2hhcmVkRmlsZSA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBUT0RPKGIvMTMxMTY2OTI1KTogTUREIGR1bXAgc2hvdWxkIG5vdCB1c2UgbGl0ZSBwcm90byB0b1N0cmluZy4KKyAgICAgICAgICAgIExvZ1V0aWwuZSgiJXM6IFNoYXJlZCBmaWxlIG5vdCBmb3VuZCwgbmV3RmlsZUtleSA9ICVzIiwgVEFHLCBuZXdGaWxlS2V5KTsKKyAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLlNIQVJFRF9GSUxFX05PVF9GT1VORF9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgICAgICAgIH0KKworICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUoc2hhcmVkRmlsZSk7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIE1heWJlIGRlbGV0ZSBvbi1kZXZpY2UgZmlsZSBhZnRlciBhIGNvbXBsZXRlZCBkb3dubG9hZCB3aGVuIGEgY2hlY2tzdW0gbWlzbWF0Y2ggb2NjdXJzLgorICAgKgorICAgKiA8cD5XaGVuIGEgY2hlY2tzdW0gbWlzbWF0Y2ggb2NjdXJzIGFmdGVyIGEgY29tcGxldGVkIGRvd25sb2FkLCBpdCdzIHBvc3NpYmxlIHRoYXQgdGhlIGRhdGEgaGFzCisgICAqIGJlZW4gY29ycnVwdGVkIG9uLWRpc2suIEluIHRoaXMgZXZlbnQsIHdlIHNob3VsZCBkZWxldGUgdGhlIG9uLWRpc2sgZmlsZSBzbyBpdCBjYW4gYmUKKyAgICogcmVkb3dubG9hZGVkIGFnYWluIGluIGEgbm9uLWNvcnJ1cHRlZCBzdGF0ZS4KKyAgICoKKyAgICogPHA+SG93ZXZlciwgaXQncyBhbHNvIHBvc3NpYmxlIHRoYXQgYSBiYWQgY29uZmlnIHdhcyBzZW50IHdpdGggYSB3cm9uZyBjaGVja3N1bS4gSW4gdGhpcyBldmVudCwKKyAgICogdGhlIG9uLWRpc2sgZmlsZSBtYXkgbm90IGJlIGNvcnJ1cHRlZCwgc28gZGVsZXRpbmcgaXQgY291bGQgbGVhZCB0byBhbiBpbmNyZWFzZSBpbiBuZXR3b3JrCisgICAqIGJhbmR3aWR0aCB1c2FnZS4KKyAgICoKKyAgICogPHA+SW4gb3JkZXIgdG8gYmFsYW5jZSB0aGUgdHdvIGNhc2VzLCBNREQgd2lsbCBzdGFydCB0byBkZWxldGUgdGhlIG9uLWRpc2sgZmlsZSwgYnV0IGFmdGVyIGEKKyAgICogY2VydGFpbiBudW1iZXIgb2YgcmV0cmllcywgdGhpcyBkZWxldGlvbiB3aWxsIGJlIHNraXBwZWQgdG8gcHJldmVudCB1bm5lY2Vzc2FyeSBuZXR3b3JrCisgICAqIGJhbmR3aWR0aCB1c2FnZS4KKyAgICoKKyAgICogPHA+VGhpcyBmdXR1cmUgbWF5IHJldHVybiBhIGZhaWxlZCBmdXR1cmUgd2l0aCBhbiBJT0V4Y2VwdGlvbiBpZiBhdHRlbXB0aW5nIHRvIGRlbGV0ZSB0aGUgZmlsZQorICAgKiBmYWlscy4KKyAgICovCisgIHN0YXRpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IG1heWJlRGVsZXRlRmlsZU9uQ2hlY2tzdW1NaXNtYXRjaCgKKyAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgIERhdGFGaWxlIGRhdGFGaWxlLAorICAgICAgQWxsb3dlZFJlYWRlcnMgYWxsb3dlZFJlYWRlcnMsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLAorICAgICAgVXJpIGZpbGVVcmksCisgICAgICBTdHJpbmcgY2hlY2tzdW0sCisgICAgICBFdmVudExvZ2dlciBldmVudExvZ2dlciwKKyAgICAgIEZsYWdzIGZsYWdzLAorICAgICAgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikgeworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9IFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGRhdGFGaWxlLCBhbGxvd2VkUmVhZGVycyk7CisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmUuZnJvbSgKKyAgICAgICAgICAgIGdldFNoYXJlZEZpbGVPckZhaWwoc2hhcmVkRmlsZXNNZXRhZGF0YSwgbmV3RmlsZUtleSwgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgIHNoYXJlZEZpbGUgLT4geworICAgICAgICAgICAgICBpZiAoc2hhcmVkRmlsZS5nZXRDaGVja3N1bU1pc21hdGNoUmV0cnlEb3dubG9hZENvdW50KCkKKyAgICAgICAgICAgICAgICAgID49IGZsYWdzLmRvd25sb2FkZXJNYXhSZXRyeU9uQ2hlY2tzdW1NaXNtYXRjaENvdW50KCkpIHsKKyAgICAgICAgICAgICAgICBMb2dVdGlsLmQoCisgICAgICAgICAgICAgICAgICAgICIlczogQ2hlY2tzdW0gbWlzbWF0Y2ggZGV0ZWN0ZWQgYnV0IHRoZSBoYXMgYWxyZWFkeSByZWFjaGVkIHJldHJ5IGxpbWl0ISIKKyAgICAgICAgICAgICAgICAgICAgICAgICsgIiBTa2lwcGluZyByZW1vdmFsIGZvciBmaWxlICVzIiwKKyAgICAgICAgICAgICAgICAgICAgVEFHLCBjaGVja3N1bSk7CisgICAgICAgICAgICAgICAgZXZlbnRMb2dnZXIubG9nRXZlbnRTYW1wbGVkKDApOworICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIExvZ1V0aWwuZCgKKyAgICAgICAgICAgICAgICAgICAgIiVzOiBSZW1vdmluZyBmaWxlIGFuZCBtYXJraW5nIGFzIGNvcnJ1cHRlZCBkdWUgdG8gY2hlY2tzdW0gbWlzbWF0Y2giLCBUQUcpOworICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZS5kZWxldGVGaWxlKGZpbGVVcmkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSBjb3JydXB0ZWQgZmlsZSBpcyBiZXN0IGVmZm9ydCwgdGhlIG5leHQgdGltZSBNREQgYXR0ZW1wdHMgdG8KKyAgICAgICAgICAgICAgICAgIC8vIGRvd25sb2FkLCB3ZSB3aWxsIHRyeSBhZ2FpbiB0byBkZWxldGUgdGhlIGZpbGUuIEZvciBub3csIGp1c3QgbG9nIHRoaXMgZXJyb3IuCisgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUoZSwgIiVzOiBGYWlsZWQgdG8gcmVtb3ZlIGNvcnJ1cHRlZCBmaWxlICVzIiwgVEFHLCBjaGVja3N1bSk7CisgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGUpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLyoqCisgICAqIEZpbmQgdGhlIGZpbGUgbWV0YWRhdGEgYW5kIHVwZGF0ZSB0aGUgZmlsZSBzdGF0dXMuIFRocm93cyB7QGxpbmsgRG93bmxvYWRFeGNlcHRpb259IGlmIHRoZSBmaWxlCisgICAqIHN0YXR1cyBmYWlsZWQgdG8gYmUgdXBkYXRlZC4KKyAgICovCisgIHN0YXRpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHVwZGF0ZUZpbGVTdGF0dXMoCisgICAgICBGaWxlU3RhdHVzIGZpbGVTdGF0dXMsCisgICAgICBEYXRhRmlsZSBkYXRhRmlsZSwKKyAgICAgIEFsbG93ZWRSZWFkZXJzIGFsbG93ZWRSZWFkZXJzLAorICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YSBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikgeworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9IFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGRhdGFGaWxlLCBhbGxvd2VkUmVhZGVycyk7CisKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKAorICAgICAgICAgICAgZ2V0U2hhcmVkRmlsZU9yRmFpbChzaGFyZWRGaWxlc01ldGFkYXRhLCBuZXdGaWxlS2V5LCBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKSkKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgc2hhcmVkRmlsZSAtPiB7CisgICAgICAgICAgICAgIFNoYXJlZEZpbGUuQnVpbGRlciBzaGFyZWRGaWxlQnVpbGRlciA9CisgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlLnRvQnVpbGRlcigpLnNldEZpbGVTdGF0dXMoZmlsZVN0YXR1cyk7CisgICAgICAgICAgICAgIGlmIChmaWxlU3RhdHVzLmVxdWFscyhGaWxlU3RhdHVzLkNPUlJVUFRFRCkpIHsKKyAgICAgICAgICAgICAgICAvLyBDb3JydXB0ZWQgc3RhdGUgaW5kaWNhdGVzIGEgY2hlY2tzdW0gbWlzbWF0Y2ggZmFpbHVyZSwgc28gaW5jcmVtZW50IHRoZSByZXRyeQorICAgICAgICAgICAgICAgIC8vIGRvd25sb2FkIGNvdW50LgorICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVCdWlsZGVyLnNldENoZWNrc3VtTWlzbWF0Y2hSZXRyeURvd25sb2FkQ291bnQoCisgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGUuZ2V0Q2hlY2tzdW1NaXNtYXRjaFJldHJ5RG93bmxvYWRDb3VudCgpICsgMSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgcmV0dXJuIHNoYXJlZEZpbGVzTWV0YWRhdGEud3JpdGUobmV3RmlsZUtleSwgc2hhcmVkRmlsZUJ1aWxkZXIuYnVpbGQoKSk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgd3JpdGVTdWNjZXNzIC0+IHsKKyAgICAgICAgICAgICAgaWYgKCF3cml0ZVN1Y2Nlc3MpIHsKKyAgICAgICAgICAgICAgICAvLyBUT0RPKGIvMTMxMTY2OTI1KTogTUREIGR1bXAgc2hvdWxkIG5vdCB1c2UgbGl0ZSBwcm90byB0b1N0cmluZy4KKyAgICAgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgICAgICIlczogVW5hYmxlIHRvIHdyaXRlIGJhY2sgZG93bmxvYWQgaW5mbyBmb3IgZmlsZSBlbnRyeSB3aXRoICVzIiwKKyAgICAgICAgICAgICAgICAgICAgVEFHLCBuZXdGaWxlS2V5KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLlVOQUJMRV9UT19VUERBVEVfRklMRV9TVEFURV9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXIvRmlsZU5hbWVVdGlsLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXIvRmlsZU5hbWVVdGlsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjA2NTcwYQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlci9GaWxlTmFtZVV0aWwuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kb3dubG9hZGVyOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworCisvKiogRGVsdGEgZmlsZSBuYW1lIHV0aWxpdHkgY2xhc3MuICovCitwdWJsaWMgY2xhc3MgRmlsZU5hbWVVdGlsIHsKKworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBOQU1FX1NFUEFSQVRPUiA9ICJfIjsKKworICAvKioKKyAgICogRm9yIGNhc2VzIHRoYXQgdGhlIGRvd25sb2FkZWQgZmlsZSBpcyBkaWZmZXJlbnQgdGhhbiB0aGUgZmluYWwgZmlsZSwgZ2VuZXJhdGUgYSB0ZW1wb3JhcnkgZmlsZQorICAgKiBmb3IgZG93bmxvYWQgYW5kIG5hbWUgaXQgd2l0aCBhIHN1ZmZpeCBvZiB0aGUgZG93bmxvYWRlZCBmaWxlIGNoZWNrc3VtIHRvIGF2b2lkIG5hbWluZworICAgKiBjb25mbGljdHMuCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRUZW1wRmlsZU5hbWVXaXRoRG93bmxvYWRlZEZpbGVDaGVja3N1bShTdHJpbmcgZmlsZU5hbWUsIFN0cmluZyBjaGVja3N1bSkgeworICAgIHJldHVybiBmaWxlTmFtZSArIE5BTUVfU0VQQVJBVE9SICsgY2hlY2tzdW07CisgIH0KKworICAvKiogR2V0IHRoZSBmaW5hbCBmaWxlIG5hbWUgYnkgcmVtb3ZpbmcgdGhlIHRlbXBvcmFyeSBkb3dubG9hZGVkIGZpbGUgc3VmZml4IGFzICJfY2hlY2tzdW0iLiAqLworICBwdWJsaWMgc3RhdGljIFVyaSBnZXRGaW5hbEZpbGVVcmlXaXRoVGVtcERvd25sb2FkZWRGaWxlKFVyaSBkb3dubG9hZGVkRmlsZVVyaSkgeworICAgIFN0cmluZyBzZXJpYWxpemVkRGVsdGFGaWxlVXJpID0gZG93bmxvYWRlZEZpbGVVcmkudG9TdHJpbmcoKTsKKyAgICByZXR1cm4gVXJpLnBhcnNlKAorICAgICAgICBzZXJpYWxpemVkRGVsdGFGaWxlVXJpLnN1YnN0cmluZygwLCBzZXJpYWxpemVkRGVsdGFGaWxlVXJpLmxhc3RJbmRleE9mKE5BTUVfU0VQQVJBVE9SKSkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXIvRmlsZVZhbGlkYXRvci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyL0ZpbGVWYWxpZGF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOTU0MDczCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyL0ZpbGVWYWxpZGF0b3IuamF2YQpAQCAtMCwwICsxLDE3OSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZG93bmxvYWRlcjsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbi5Eb3dubG9hZFJlc3VsdENvZGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWFkU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLkZpbGVHcm91cFV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IGphdmEuc2VjdXJpdHkuTm9TdWNoQWxnb3JpdGhtRXhjZXB0aW9uOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKiBVdGlsIGNsYXNzIHRoYXQgdmFsaWRhdGUgdGhlIGRvd25sb2FkZWQgZmlsZS4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBGaWxlVmFsaWRhdG9yIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJGaWxlVmFsaWRhdG9yIjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyW10gSEVYX0xPV0VSQ0FTRSA9IHsKKyAgICAnMCcsICcxJywgJzInLCAnMycsICc0JywgJzUnLCAnNicsICc3JywgJzgnLCAnOScsICdhJywgJ2InLCAnYycsICdkJywgJ2UnLCAnZicKKyAgfTsKKworICAvLyA8aW50ZXJuYWw+CisgIHByaXZhdGUgRmlsZVZhbGlkYXRvcigpIHt9CisKKyAgLyoqCisgICAqIFJldHVybnMgaWYgdGhlIGZpbGUgY2hlY2tzdW0gdmVyaWZpY2F0aW9uIHBhc3Nlcy4KKyAgICoKKyAgICogQHBhcmFtIGZpbGVVcmkgLSB0aGUgdXJpIG9mIHRoZSBmaWxlIHRvIGNhbGN1bGF0ZSBhIHNoYTEgaGFzaCBmb3IuCisgICAqIEBwYXJhbSBmaWxlQ2hlY2tzdW0gLSB0aGUgZXhwZWN0ZWQgZmlsZSBjaGVja3N1bQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBib29sZWFuIHZlcmlmeUNoZWNrc3VtKAorICAgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZSwgVXJpIGZpbGVVcmksIFN0cmluZyBmaWxlQ2hlY2tzdW0pIHsKKyAgICBTdHJpbmcgZGlnZXN0ID0gRmlsZVZhbGlkYXRvci5jb21wdXRlU2hhMURpZ2VzdChmaWxlU3RvcmFnZSwgZmlsZVVyaSk7CisgICAgcmV0dXJuIGRpZ2VzdC5lcXVhbHMoZmlsZUNoZWNrc3VtKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHNoYTEgaGFzaCBvZiBmaWxlLCBlbXB0eSBzdHJpbmcgaWYgdW5hYmxlIHRvIHJlYWQgZmlsZS4KKyAgICoKKyAgICogQHBhcmFtIHVyaSAtIHRoZSB1cmkgb2YgdGhlIGZpbGUgdG8gY2FsY3VsYXRlIGEgc2hhMSBoYXNoIGZvci4KKyAgICovCisgIC8vIFRPRE8oYi8xMzk0NzIyOTUpOiBjb252ZXJ0IHRoaXMgdG8gYSBNb2JTdG9yZSBPcGVuZXIuCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNvbXB1dGVTaGExRGlnZXN0KFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsIFVyaSB1cmkpIHsKKyAgICB0cnkgKElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gZmlsZVN0b3JhZ2Uub3Blbih1cmksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICByZXR1cm4gY29tcHV0ZURpZ2VzdChpbnB1dFN0cmVhbSwgIlNIQTEiKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBUT0RPKGIvMTE4MTM3NjcyKTogcmVjb25zaWRlciBvbiB0aGUgc3dhbGxvd2VkIGV4Y2VwdGlvbi4KKyAgICAgIExvZ1V0aWwuZSgiJXM6IEZhaWxlZCB0byBvcGVuIGZpbGUsIHVyaSA9ICVzIiwgVEFHLCB1cmkpOworICAgICAgcmV0dXJuICIiOworICAgIH0KKyAgfQorCisgIC8qKiBDb21wdXRlIHRoZSBTSEExIG9mIHRoZSBpbnB1dCBzdHJpbmcuICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGNvbXB1dGVTaGExRGlnZXN0KFN0cmluZyBpbnB1dCkgeworICAgIE1lc3NhZ2VEaWdlc3QgbWVzc2FnZURpZ2VzdCA9IGdldE1lc3NhZ2VEaWdlc3QoIlNIQTEiKTsKKyAgICBpZiAobWVzc2FnZURpZ2VzdCA9PSBudWxsKSB7CisgICAgICByZXR1cm4gIiI7CisgICAgfQorCisgICAgYnl0ZVtdIGJ5dGVzID0gaW5wdXQuZ2V0Qnl0ZXMoKTsKKyAgICBtZXNzYWdlRGlnZXN0LnVwZGF0ZShieXRlcywgMCwgYnl0ZXMubGVuZ3RoKTsKKyAgICByZXR1cm4gYnl0ZXNUb1N0cmluZ0xvd2VyY2FzZShtZXNzYWdlRGlnZXN0LmRpZ2VzdCgpKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHNoYTI1NiBoYXNoIG9mIGZpbGUsIGVtcHR5IHN0cmluZyBpZiB1bmFibGUgdG8gcmVhZCBmaWxlLgorICAgKgorICAgKiBAcGFyYW0gdXJpIC0gdGhlIHVyaSBvZiB0aGUgZmlsZSB0byBjYWxjdWxhdGUgYSBzaGEyNTYgaGFzaCBmb3IuCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBjb21wdXRlU2hhMjU2RGlnZXN0KFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsIFVyaSB1cmkpIHsKKyAgICB0cnkgKElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gZmlsZVN0b3JhZ2Uub3Blbih1cmksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICByZXR1cm4gY29tcHV0ZURpZ2VzdChpbnB1dFN0cmVhbSwgIlNIQS0yNTYiKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBUT0RPKGIvMTE4MTM3NjcyKTogcmVjb25zaWRlciBvbiB0aGUgc3dhbGxvd2VkIGV4Y2VwdGlvbi4KKyAgICAgIExvZ1V0aWwuZSgiJXM6IEZhaWxlZCB0byBvcGVuIGZpbGUsIHVyaSA9ICVzIiwgVEFHLCB1cmkpOworICAgICAgcmV0dXJuICIiOworICAgIH0KKyAgfQorCisgIC8vIENhbGxlciBpcyByZXNwb25zaWJsZSBmb3Igb3BlbmluZyBhbmQgY2xvc2luZyBzdHJlYW0uCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBjb21wdXRlRGlnZXN0KElucHV0U3RyZWFtIGlucHV0U3RyZWFtLCBTdHJpbmcgYWxnb3JpdGhtKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBNZXNzYWdlRGlnZXN0IG1lc3NhZ2VEaWdlc3QgPSBnZXRNZXNzYWdlRGlnZXN0KGFsZ29yaXRobSk7CisgICAgaWYgKG1lc3NhZ2VEaWdlc3QgPT0gbnVsbCkgeworICAgICAgcmV0dXJuICIiOworICAgIH0KKworICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlWzgxOTJdOworCisgICAgaW50IGJ5dGVDb3VudCA9IGlucHV0U3RyZWFtLnJlYWQoYnl0ZXMpOworICAgIHdoaWxlIChieXRlQ291bnQgIT0gLTEpIHsKKyAgICAgIG1lc3NhZ2VEaWdlc3QudXBkYXRlKGJ5dGVzLCAwLCBieXRlQ291bnQpOworICAgICAgYnl0ZUNvdW50ID0gaW5wdXRTdHJlYW0ucmVhZChieXRlcyk7CisgICAgfQorICAgIHJldHVybiBieXRlc1RvU3RyaW5nTG93ZXJjYXNlKG1lc3NhZ2VEaWdlc3QuZGlnZXN0KCkpOworICB9CisKKyAgLyoqCisgICAqIFRocm93cyB7QGxpbmsgRG93bmxvYWRFeGNlcHRpb259IGlmIHRoZSBkb3dubG9hZGVkIGZpbGUgZG9lc24ndCBleGlzdCwgb3IgdGhlIFNIQTEgaGFzaCBvZiB0aGUKKyAgICogZmlsZSBjaGVja3N1bSBkb2Vzbid0IG1hdGNoLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHZhbGlkYXRlRG93bmxvYWRlZEZpbGUoCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLCBEYXRhRmlsZSBkYXRhRmlsZSwgVXJpIGZpbGVVcmksIFN0cmluZyBjaGVja3N1bSkKKyAgICAgIHRocm93cyBEb3dubG9hZEV4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIGlmICghZmlsZVN0b3JhZ2UuZXhpc3RzKGZpbGVVcmkpKSB7CisgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICIlczogRG93bmxvYWRlZCBmaWxlICVzIGlzIG5vdCBwcmVzZW50IGF0ICVzIiwKKyAgICAgICAgICAgIFRBRywgRmlsZUdyb3VwVXRpbC5nZXRGaWxlQ2hlY2tzdW0oZGF0YUZpbGUpLCBmaWxlVXJpKTsKKyAgICAgICAgdGhyb3cgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5ET1dOTE9BREVEX0ZJTEVfTk9UX0ZPVU5EX0VSUk9SKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICB9CisgICAgICBpZiAoZGF0YUZpbGUuZ2V0Q2hlY2tzdW1UeXBlKCkgPT0gRGF0YUZpbGUuQ2hlY2tzdW1UeXBlLk5PTkUpIHsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgaWYgKCF2ZXJpZnlDaGVja3N1bShmaWxlU3RvcmFnZSwgZmlsZVVyaSwgY2hlY2tzdW0pKSB7CisgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICIlczogRG93bmxvYWRlZCBmaWxlIGF0IHVyaSA9ICVzLCBjaGVja3N1bSA9ICVzIHZlcmlmaWNhdGlvbiBmYWlsZWQiLAorICAgICAgICAgICAgVEFHLCBmaWxlVXJpLCBjaGVja3N1bSk7CisgICAgICAgIHRocm93IERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuRE9XTkxPQURFRF9GSUxFX0NIRUNLU1VNX01JU01BVENIX0VSUk9SKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICB9CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgIGUsCisgICAgICAgICAgIiVzOiBGYWlsZWQgdG8gdmFsaWRhdGUgZG93bmxvYWQgZmlsZSAlcyIsCisgICAgICAgICAgVEFHLAorICAgICAgICAgIEZpbGVHcm91cFV0aWwuZ2V0RmlsZUNoZWNrc3VtKGRhdGFGaWxlKSk7CisgICAgICB0aHJvdyBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5VTkFCTEVfVE9fVkFMSURBVEVfRE9XTkxPQURfRklMRV9FUlJPUikKKyAgICAgICAgICAuc2V0Q2F1c2UoZSkKKyAgICAgICAgICAuYnVpbGQoKTsKKyAgICB9CisgIH0KKworICBATnVsbGFibGUKKyAgcHJpdmF0ZSBzdGF0aWMgTWVzc2FnZURpZ2VzdCBnZXRNZXNzYWdlRGlnZXN0KFN0cmluZyBoYXNoQWxnb3JpdGhtKSB7CisgICAgdHJ5IHsKKyAgICAgIE1lc3NhZ2VEaWdlc3QgbWVzc2FnZURpZ2VzdCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoaGFzaEFsZ29yaXRobSk7CisgICAgICBpZiAobWVzc2FnZURpZ2VzdCAhPSBudWxsKSB7CisgICAgICAgIHJldHVybiBtZXNzYWdlRGlnZXN0OworICAgICAgfQorICAgIH0gY2F0Y2ggKE5vU3VjaEFsZ29yaXRobUV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBEbyBub3RoaW5nLgorICAgIH0KKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBieXRlc1RvU3RyaW5nTG93ZXJjYXNlKGJ5dGVbXSBieXRlcykgeworICAgIGNoYXJbXSBoZXhDaGFycyA9IG5ldyBjaGFyW2J5dGVzLmxlbmd0aCAqIDJdOworICAgIGludCBqID0gMDsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7CisgICAgICBpbnQgdiA9IGJ5dGVzW2ldICYgMHhGRjsKKyAgICAgIGhleENoYXJzW2orK10gPSBIRVhfTE9XRVJDQVNFW3YgPj4+IDRdOworICAgICAgaGV4Q2hhcnNbaisrXSA9IEhFWF9MT1dFUkNBU0VbdiAmIDB4MEZdOworICAgIH0KKyAgICByZXR1cm4gbmV3IFN0cmluZyhoZXhDaGFycyk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlci9NZGRGaWxlRG93bmxvYWRlci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyL01kZEZpbGVEb3dubG9hZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjFkZTg4YgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlci9NZGRGaWxlRG93bmxvYWRlci5qYXZhCkBAIC0wLDAgKzEsNDMzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kb3dubG9hZGVyOworCitpbXBvcnQgc3RhdGljIGphdmEubGFuZy5NYXRoLm1pbjsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLm9zLlN0YXRGczsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBhbmRyb2lkeC5hbm5vdGF0aW9uLlZpc2libGVGb3JUZXN0aW5nOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uLkRvd25sb2FkUmVzdWx0Q29kZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GaWxlU291cmNlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkZsYWdzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRDb25zdHJhaW50czsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuSW5saW5lRG93bmxvYWRQYXJhbXM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLkFwcGxpY2F0aW9uQ29udGV4dDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5hbm5vdGF0aW9ucy5TZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ2dpbmdTdGF0ZVN0b3JlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuRG93bmxvYWRQcm9ncmVzc01vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubW9uaXRvci5OZXR3b3JrVXNhZ2VNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5TdXBwbGllcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZsdWVudEZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VOZXR3b3JrUG9saWN5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRXh0cmFIdHRwSGVhZGVyOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uR3JvdXBLZXk7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworaW1wb3J0IGphdmF4LmluamVjdC5JbmplY3Q7CisKKy8qKgorICogUmVzcG9uc2libGUgZm9yIGRvd25sb2FkaW5nIGZpbGVzIGluIE1ERC4KKyAqCisgKiA8cD5Qcm92aWRlcyBtZXRob2RzIHRvIHN0YXJ0IGFuZCBzdG9wIGRvd25sb2FkaW5nIGEgZmlsZS4gVGhlIHN0b3AgbWV0aG9kIGNhbiBiZSBjYWxsZWQgaWYgdGhlCisgKiBmaWxlIGlzIG5vIGxvbmdlciBuZWVkZWQsIG9yIHRoZSBmaWxlIHdhcyBhbHJlYWR5IGRvd25sb2FkZWQgdG8gdGhlIGRldmljZS4KKyAqCisgKiA8cD5UaGlzIGNsYXNzIHN1cHBvcnRzIGJvdGggc3RhbmRhcmQgZG93bmxvYWRzIChvdmVyIGh0dHBzKSBvciBpbmxpbmUgZmlsZXMgKGZyb20gYSBCeXRlU3RyaW5nKSwKKyAqIHVzaW5nIHtAbGluayAjc3RhcnREb3dubG9hZGluZ30gYW5kIHtAbGluayAjc3RhcnRDb3B5aW5nfSwgcmVzcGVjdGl2ZWx5LgorICovCisvLyBUT0RPKGIvMTI5NDk3ODY3KTogQWRkIHRyYWNraW5nIGZvciBvbi1nb2luZyBkb3dubG9hZCB0byBkZWR1cCBkb3dubG9hZCByZXF1ZXN0IGZyb20KKy8vIEZpbGVEb3dubG9hZGVyLgorcHVibGljIGNsYXNzIE1kZEZpbGVEb3dubG9hZGVyIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIk1kZEZpbGVEb3dubG9hZGVyIjsKKworICAvLyBUaGVzZSBzaG91bGQgb25seSBiZSBhY2Nlc3NlZCB0aHJvdWdoIHRoZSBnZXR0ZXJzIGFuZCBuZXZlciBkaXJlY3RseS4KKyAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisgIHByaXZhdGUgZmluYWwgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGZpbGVEb3dubG9hZGVyU3VwcGxpZXI7CisgIHByaXZhdGUgZmluYWwgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHJpdmF0ZSBmaW5hbCBOZXR3b3JrVXNhZ2VNb25pdG9yIG5ldHdvcmtVc2FnZU1vbml0b3I7CisgIHByaXZhdGUgZmluYWwgT3B0aW9uYWw8RG93bmxvYWRQcm9ncmVzc01vbml0b3I+IGRvd25sb2FkTW9uaXRvck9wdGlvbmFsOworICBwcml2YXRlIGZpbmFsIExvZ2dpbmdTdGF0ZVN0b3JlIGxvZ2dpbmdTdGF0ZVN0b3JlOworICBwcml2YXRlIGZpbmFsIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CisgIHByaXZhdGUgZmluYWwgRmxhZ3MgZmxhZ3M7CisKKyAgLy8gQ2FjaGUgZm9yIGFsbCBvbi1nb2luZyBkb3dubG9hZHMuIFRoaXMgd2lsbCBiZSB1c2VkIHRvIGRlLWR1cCBkb3dubG9hZCByZXF1ZXN0cy4KKyAgLy8gTk9URTogY3VycmVudGx5IHdlIGFzc3VtZSB0aGF0IHRoaXMgbWFwIHdpbGwgb25seSBiZSBhY2Nlc3NlZCB0aHJvdWdoIHRoZQorICAvLyBTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLCBzbyB3ZSBkb24ndCBuZWVkIHN5bmNocm9uaXphdGlvbiBoZXJlLgorICBAVmlzaWJsZUZvclRlc3RpbmcKKyAgZmluYWwgSGFzaE1hcDxVcmksIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4+IGZpbGVVcmlUb0Rvd25sb2FkRnV0dXJlTWFwID0gbmV3IEhhc2hNYXA8PigpOworCisgIEBJbmplY3QKKyAgcHVibGljIE1kZEZpbGVEb3dubG9hZGVyKAorICAgICAgQEFwcGxpY2F0aW9uQ29udGV4dCBDb250ZXh0IGNvbnRleHQsCisgICAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllciwKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsCisgICAgICBOZXR3b3JrVXNhZ2VNb25pdG9yIG5ldHdvcmtVc2FnZU1vbml0b3IsCisgICAgICBPcHRpb25hbDxEb3dubG9hZFByb2dyZXNzTW9uaXRvcj4gZG93bmxvYWRNb25pdG9yLAorICAgICAgTG9nZ2luZ1N0YXRlU3RvcmUgbG9nZ2luZ1N0YXRlU3RvcmUsCisgICAgICBAU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciBFeGVjdXRvciBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLAorICAgICAgRmxhZ3MgZmxhZ3MpIHsKKyAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OworICAgIHRoaXMuZmlsZURvd25sb2FkZXJTdXBwbGllciA9IGZpbGVEb3dubG9hZGVyU3VwcGxpZXI7CisgICAgdGhpcy5maWxlU3RvcmFnZSA9IGZpbGVTdG9yYWdlOworICAgIHRoaXMubmV0d29ya1VzYWdlTW9uaXRvciA9IG5ldHdvcmtVc2FnZU1vbml0b3I7CisgICAgdGhpcy5kb3dubG9hZE1vbml0b3JPcHRpb25hbCA9IGRvd25sb2FkTW9uaXRvcjsKKyAgICB0aGlzLmxvZ2dpbmdTdGF0ZVN0b3JlID0gbG9nZ2luZ1N0YXRlU3RvcmU7CisgICAgdGhpcy5zZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yID0gc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKyAgICB0aGlzLmZsYWdzID0gZmxhZ3M7CisgIH0KKworICAvKioKKyAgICogU3RhcnQgZG93bmxvYWRpbmcgdGhlIGZpbGUuCisgICAqCisgICAqIEBwYXJhbSBncm91cEtleSBHcm91cEtleSB0aGF0IGNvbnRhaW5zIHRoZSBmaWxlIHRvIGRvd25sb2FkLgorICAgKiBAcGFyYW0gZmlsZUdyb3VwVmVyc2lvbk51bWJlciB2ZXJzaW9uIG51bWJlciBvZiB0aGUgZ3JvdXAgdGhhdCBjb250YWlucyB0aGUgZmlsZSB0byBkb3dubG9hZC4KKyAgICogQHBhcmFtIGJ1aWxkSWQgYnVpbGQgaWQgb2YgdGhlIGdyb3VwIHRoYXQgY29udGFpbnMgdGhlIGZpbGUgdG8gZG93bmxvYWQuCisgICAqIEBwYXJhbSBmaWxlVXJpIC0gdGhlIEZpbGUgVXJpIHRvIGRvd25sb2FkIHRoZSBmaWxlIGF0LgorICAgKiBAcGFyYW0gdXJsVG9Eb3dubG9hZCAtIFRoZSB1cmwgb2YgdGhlIGZpbGUgdG8gZG93bmxvYWQuCisgICAqIEBwYXJhbSBmaWxlU2l6ZSAtIHRoZSBleHBlY3RlZCBzaXplIG9mIHRoZSBmaWxlIHRvIGRvd25sb2FkLgorICAgKiBAcGFyYW0gZG93bmxvYWRDb25kaXRpb25zIC0gY29uZGl0aW9ucyB1bmRlciB3aGljaCB0aGlzIGZpbGUgc2hvdWxkIGJlIGRvd25sb2FkZWQuCisgICAqIEBwYXJhbSBjYWxsYmFjayAtIGNhbGxiYWNrIGNhbGxlZCB3aGVuIHRoZSBkb3dubG9hZCBlaXRoZXIgY29tcGxldGVzIG9yIGZhaWxzLgorICAgKiBAcGFyYW0gdHJhZmZpY1RhZyAtIFRhZyBmb3IgdGhlIG5ldHdvcmsgdHJhZmZpYyB0byBkb3dubG9hZCB0aGlzIGRhdGFGaWxlLgorICAgKiBAcGFyYW0gZXh0cmFIdHRwSGVhZGVycyAtIEV4dHJhIEhlYWRlcnMgZm9yIHRoaXMgcmVxdWVzdC4KKyAgICogQHJldHVybiAtIExpc3RlbmFibGVGdXR1cmUgcmVwcmVzZW50aW5nIHRoZSBkb3dubG9hZCByZXN1bHQgb2YgYSBmaWxlLgorICAgKi8KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gc3RhcnREb3dubG9hZGluZygKKyAgICAgIEdyb3VwS2V5IGdyb3VwS2V5LAorICAgICAgaW50IGZpbGVHcm91cFZlcnNpb25OdW1iZXIsCisgICAgICBsb25nIGJ1aWxkSWQsCisgICAgICBVcmkgZmlsZVVyaSwKKyAgICAgIFN0cmluZyB1cmxUb0Rvd25sb2FkLAorICAgICAgaW50IGZpbGVTaXplLAorICAgICAgQE51bGxhYmxlIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMsCisgICAgICBEb3dubG9hZGVyQ2FsbGJhY2sgY2FsbGJhY2ssCisgICAgICBpbnQgdHJhZmZpY1RhZywKKyAgICAgIExpc3Q8RXh0cmFIdHRwSGVhZGVyPiBleHRyYUh0dHBIZWFkZXJzKSB7CisgICAgaWYgKGZpbGVVcmlUb0Rvd25sb2FkRnV0dXJlTWFwLmNvbnRhaW5zS2V5KGZpbGVVcmkpKSB7CisgICAgICByZXR1cm4gZmlsZVVyaVRvRG93bmxvYWRGdXR1cmVNYXAuZ2V0KGZpbGVVcmkpOworICAgIH0KKyAgICByZXR1cm4gYWRkQ2FsbGJhY2tBbmRSZWdpc3RlcigKKyAgICAgICAgZmlsZVVyaSwKKyAgICAgICAgY2FsbGJhY2ssCisgICAgICAgIHN0YXJ0RG93bmxvYWRpbmdJbnRlcm5hbCgKKyAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgZmlsZUdyb3VwVmVyc2lvbk51bWJlciwKKyAgICAgICAgICAgIGJ1aWxkSWQsCisgICAgICAgICAgICBmaWxlVXJpLAorICAgICAgICAgICAgdXJsVG9Eb3dubG9hZCwKKyAgICAgICAgICAgIGZpbGVTaXplLAorICAgICAgICAgICAgZG93bmxvYWRDb25kaXRpb25zLAorICAgICAgICAgICAgdHJhZmZpY1RhZywKKyAgICAgICAgICAgIGV4dHJhSHR0cEhlYWRlcnMpKTsKKyAgfQorCisgIC8qKgorICAgKiBBZGRzIENhbGxiYWNrIHRvIGdpdmVuIEZ1dHVyZSBhbmQgUmVnaXN0ZXJzIGZ1dHVyZSBpbiBpbi1wcm9ncmVzcyBjYWNoZS4KKyAgICoKKyAgICogPHA+Q29udGFpbnMgc2hhcmVkIGxvZ2ljIG9mIGNvbm5lY3Rpbmcge0Bjb2RlIGNhbGxiYWNrfSB0byB7QGNvZGUgZG93bmxvYWRPckNvcHlGdXR1cmV9IGFuZAorICAgKiByZWdpc3RlcnMgZnV0dXJlIGluIHRoZSBpbnRlcm5hbCBpbi1wcm9ncmVzcyBjYWNoZS4gVGhpcyBjYWNoZSBhbGxvd3Mgc2ltaWxhciBkb3dubG9hZC9jb3B5CisgICAqIHJlcXVlc3RzIHRvIGJlIGRlZHVwZWQgaW5zdGVhZCBvZiBiZWluZyBwZXJmb3JtZWQgdHdpY2UuCisgICAqCisgICAqIDxwPk5PVEU6IHRoaXMgbWV0aG9kIGFzc3VtZXMgdGhlIGNhY2hlIGhhcyBhbHJlYWR5IGJlZW4gY2hlY2tlZCBmb3IgYW4gaW4tcHJvZ3Jlc3Mgb3BlcmF0aW9uCisgICAqIGFuZCBubyBpbi1wcm9ncmVzcyBvcGVyYXRpb24gZXhpc3RzIGZvciB7QGNvZGUgZmlsZVVyaX0uCisgICAqCisgICAqIEBwYXJhbSBmaWxlVXJpIHRoZSBkZXN0aW5hdGlvbiBvZiB0aGUgZG93bmxvYWQvY29weSAodXNlZCBhcyBLZXkgaW4gaW4tcHJvZ3Jlc3MgY2FjaGUpCisgICAqIEBwYXJhbSBjYWxsYmFjayB0aGUgY2FsbGJhY2sgdGhhdCBzaG91bGQgYmUgcnVuIGFmdGVyIHRoZSBnaXZlbiBkb3dubG9hZC9jb3B5IGZ1dHVyZQorICAgKiBAcGFyYW0gZG93bmxvYWRPckNvcHlGdXR1cmUgYSBMaXN0ZW5hYmxlRnV0dXJlIHRoYXQgd2lsbCBwZXJmb3JtIHRoZSBkb3dubG9hZC9jb3B5CisgICAqIEByZXR1cm4gYSBMaXN0ZW5hYmxlRnV0dXJlIHRoYXQgY2FsbHMgdGhlIGNvcnJlY3QgY2FsbGJhY2sgYWZ0ZXIge0Bjb2RlIGRvd25sb2FkT3JDb3B5RnV0dXJlCisgICAqICAgICBjb21wbGV0ZXN9CisgICAqLworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gYWRkQ2FsbGJhY2tBbmRSZWdpc3RlcigKKyAgICAgIFVyaSBmaWxlVXJpLCBEb3dubG9hZGVyQ2FsbGJhY2sgY2FsbGJhY2ssIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRPckNvcHlGdXR1cmUpIHsKKyAgICAvLyBVc2UgdHJhbnNmb3JtICYgY2F0Y2hpbmcgdG8gZW5zdXJlIHRoYXQgd2UgY29ycmVjdGx5IGNoYWluIGV2ZXJ5dGhpbmcuCisgICAgRmx1ZW50RnV0dXJlPFZvaWQ+IHRyYW5zZm9ybWVkRnV0dXJlID0KKyAgICAgICAgRmx1ZW50RnV0dXJlLmZyb20oZG93bmxvYWRPckNvcHlGdXR1cmUpCisgICAgICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgdm9pZEFyZyAtPiBjYWxsYmFjay5vbkRvd25sb2FkQ29tcGxldGUoZmlsZVVyaSksCisgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciAvKlJ1biBjYWxsYmFja3Mgb24gQFNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IqLykKKyAgICAgICAgICAgIC5jYXRjaGluZ0FzeW5jKAorICAgICAgICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgICAgIGUgLT4KKyAgICAgICAgICAgICAgICAgICAgRnV0dXJlcy50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLm9uRG93bmxvYWRGYWlsZWQoZSksCisgICAgICAgICAgICAgICAgICAgICAgICB2b2lkQXJnIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKSwKKyAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIC8qUnVuIGNhbGxiYWNrcyBvbiBAU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciovKTsKKworICAgIGZpbGVVcmlUb0Rvd25sb2FkRnV0dXJlTWFwLnB1dChmaWxlVXJpLCB0cmFuc2Zvcm1lZEZ1dHVyZSk7CisKKyAgICAvLyBXZSB3YW50IHRvIHJlbW92ZSB0aGUgdHJhbnNmb3JtZWRGdXR1cmUgZnJvbSB0aGUgY2FjaGUgd2hlbiB0aGUgdHJhbnNmb3JtZWRGdXR1cmUgZmluaXNoZXMuCisgICAgLy8gSG93ZXZlciB0aGVyZSBtYXkgYmUgYSByYWNlIGNvbmRpdGlvbiBhbmQgdHJhbnNmb3JtZWRGdXR1cmUgbWF5IGZpbmlzaCBiZWZvcmUgd2UgcHV0IGl0IGludG8KKyAgICAvLyB0aGUgY2FjaGUuCisgICAgLy8gVG8gcHJldmVudCB0aGlzIHJhY2UgY29uZGl0aW9uLCB3ZSBhZGQgYSBjYWxsYmFjayB0byB0cmFuc2Zvcm1lZEZ1dHVyZSB0byBtYWtlIHN1cmUgdGhlCisgICAgLy8gcmVtb3ZhbCBoYXBwZW5zIGFmdGVyIHRoZSBwdXR0aW5nIGl0IGluIHRoZSBtYXAuCisgICAgLy8gQSB0cmFuc2Zvcm0gd291bGQgbm90IHdvcmsgc2luY2Ugd2Ugd2FudCB0byBydW4gdGhlIHJlbW92YWwgZXZlbiB3aGVuIHRoZSB0cmFuc2Zvcm0gZmFpbGVkLgorICAgIHRyYW5zZm9ybWVkRnV0dXJlLmFkZExpc3RlbmVyKAorICAgICAgICAoKSAtPiBmaWxlVXJpVG9Eb3dubG9hZEZ1dHVyZU1hcC5yZW1vdmUoZmlsZVVyaSksIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworCisgICAgcmV0dXJuIHRyYW5zZm9ybWVkRnV0dXJlOworICB9CisKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHN0YXJ0RG93bmxvYWRpbmdJbnRlcm5hbCgKKyAgICAgIEdyb3VwS2V5IGdyb3VwS2V5LAorICAgICAgaW50IGZpbGVHcm91cFZlcnNpb25OdW1iZXIsCisgICAgICBsb25nIGJ1aWxkSWQsCisgICAgICBVcmkgZmlsZVVyaSwKKyAgICAgIFN0cmluZyB1cmxUb0Rvd25sb2FkLAorICAgICAgaW50IGZpbGVTaXplLAorICAgICAgQE51bGxhYmxlIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMsCisgICAgICBpbnQgdHJhZmZpY1RhZywKKyAgICAgIExpc3Q8RXh0cmFIdHRwSGVhZGVyPiBleHRyYUh0dHBIZWFkZXJzKSB7CisgICAgaWYgKHVybFRvRG93bmxvYWQuc3RhcnRzV2l0aCgiaHR0cCIpCisgICAgICAgICYmIGZsYWdzLmRvd25sb2FkZXJFbmZvcmNlSHR0cHMoKQorICAgICAgICAmJiAhdXJsVG9Eb3dubG9hZC5zdGFydHNXaXRoKCJodHRwcyIpKSB7CisgICAgICBMb2dVdGlsLmUoIiVzOiBGaWxlIHVybCA9ICVzIGlzIG5vdCBzZWN1cmUiLCBUQUcsIHVybFRvRG93bmxvYWQpOworICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5JTlNFQ1VSRV9VUkxfRVJST1IpCisgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICB9CisKKyAgICBsb25nIGN1cnJlbnRGaWxlU2l6ZSA9IDA7CisgICAgdHJ5IHsKKyAgICAgIGN1cnJlbnRGaWxlU2l6ZSA9IGZpbGVTdG9yYWdlLmZpbGVTaXplKGZpbGVVcmkpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFByb2NlZWQgd2l0aCAwIGFzIHRoZSBjdXJyZW50IGZpbGUgc2l6ZS4gSXQgaXMgb25seSB1c2VkIGZvciBkZWNpZGluZyB3aGV0aGVyIHdlIHNob3VsZAorICAgICAgLy8gZG93bmxvYWQgdGhlIGZpbGUgb3Igbm90LgorICAgIH0KKworICAgIHRyeSB7CisgICAgICBjaGVja1N0b3JhZ2VDb25zdHJhaW50cyhjb250ZXh0LCBmaWxlU2l6ZSAtIGN1cnJlbnRGaWxlU2l6ZSwgZG93bmxvYWRDb25kaXRpb25zLCBmbGFncyk7CisgICAgfSBjYXRjaCAoRG93bmxvYWRFeGNlcHRpb24gZSkgeworICAgICAgLy8gV3JhcCBleGNlcHRpb24gaW4gZnV0dXJlIHRvIGJyZWFrIGZ1dHVyZSBjaGFpbi4KKyAgICAgIExvZ1V0aWwuZSgiJXM6IE5vdCBlbm91Z2ggc3BhY2UgdG8gZG93bmxvYWQgZmlsZSAlcyIsIFRBRywgdXJsVG9Eb3dubG9hZCk7CisgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoZSk7CisgICAgfQorCisgICAgaWYgKGZsYWdzLmxvZ05ldHdvcmtTdGF0cygpKSB7CisgICAgICBuZXR3b3JrVXNhZ2VNb25pdG9yLm1vbml0b3JVcmkoCisgICAgICAgICAgZmlsZVVyaSwgZ3JvdXBLZXksIGJ1aWxkSWQsIGZpbGVHcm91cFZlcnNpb25OdW1iZXIsIGxvZ2dpbmdTdGF0ZVN0b3JlKTsKKyAgICB9IGVsc2UgeworICAgICAgTG9nVXRpbC53KCIlczogTmV0d29ya1VzYWdlTW9uaXRvciBpcyBkaXNhYmxlZCIsIFRBRyk7CisgICAgfQorCisgICAgaWYgKGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICBkb3dubG9hZE1vbml0b3JPcHRpb25hbC5nZXQoKS5tb25pdG9yVXJpKGZpbGVVcmksIGdyb3VwS2V5LmdldEdyb3VwTmFtZSgpKTsKKyAgICB9CisKKyAgICBEb3dubG9hZFJlcXVlc3QuQnVpbGRlciBkb3dubG9hZFJlcXVlc3RCdWlsZGVyID0KKyAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRGaWxlVXJpKGZpbGVVcmkpLnNldFVybFRvRG93bmxvYWQodXJsVG9Eb3dubG9hZCk7CisKKyAgICAvLyBUT0RPOiBjb25zaWRlciB0byBkbyB0aGlzIGNvbnZlcnNpb24gdXBzdHJlYW0gYW5kIHdlIGNhbiBwYXNzIGluIHRoZQorICAgIC8vICBEb3dubG9hZENvbnN0cmFpbnRzLgorICAgIGlmIChkb3dubG9hZENvbmRpdGlvbnMgIT0gbnVsbAorICAgICAgICAmJiBkb3dubG9hZENvbmRpdGlvbnMuZ2V0RGV2aWNlTmV0d29ya1BvbGljeSgpCisgICAgICAgICAgICA9PSBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKSB7CisgICAgICBkb3dubG9hZFJlcXVlc3RCdWlsZGVyLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGRvd25sb2FkUmVxdWVzdEJ1aWxkZXIuc2V0RG93bmxvYWRDb25zdHJhaW50cyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfVU5NRVRFUkVEKTsKKyAgICB9CisKKyAgICBpZiAodHJhZmZpY1RhZyA+IDApIHsKKyAgICAgIGRvd25sb2FkUmVxdWVzdEJ1aWxkZXIuc2V0VHJhZmZpY1RhZyh0cmFmZmljVGFnKTsKKyAgICB9CisKKyAgICBJbW11dGFibGVMaXN0LkJ1aWxkZXI8UGFpcjxTdHJpbmcsIFN0cmluZz4+IGhlYWRlckJ1aWxkZXIgPSBJbW11dGFibGVMaXN0LmJ1aWxkZXIoKTsKKyAgICBmb3IgKEV4dHJhSHR0cEhlYWRlciBoZWFkZXIgOiBleHRyYUh0dHBIZWFkZXJzKSB7CisgICAgICBoZWFkZXJCdWlsZGVyLmFkZChQYWlyLmNyZWF0ZShoZWFkZXIuZ2V0S2V5KCksIGhlYWRlci5nZXRWYWx1ZSgpKSk7CisgICAgfQorCisgICAgZG93bmxvYWRSZXF1ZXN0QnVpbGRlci5zZXRFeHRyYUh0dHBIZWFkZXJzKGhlYWRlckJ1aWxkZXIuYnVpbGQoKSk7CisKKyAgICByZXR1cm4gZmlsZURvd25sb2FkZXJTdXBwbGllci5nZXQoKS5zdGFydERvd25sb2FkaW5nKGRvd25sb2FkUmVxdWVzdEJ1aWxkZXIuYnVpbGQoKSk7CisgIH0KKworICAvKioKKyAgICogU3RhcnQgQ29weWluZyBhIGZpbGUgdG8gaW50ZXJuYWwgc3RvcmFnZQorICAgKgorICAgKiBAcGFyYW0gZmlsZVVyaSB0aGUgRmlsZSBVcmkgd2hlcmUgY29udGVudCBzaG91bGQgYmUgY29waWVkLgorICAgKiBAcGFyYW0gdXJsVG9Eb3dubG9hZCB0aGUgdXJsIHRvIGNvcHksIHNob3VsZCBiZSBpbmxpbmVmaWxlOiBzY2hlbWUuCisgICAqIEBwYXJhbSBmaWxlU2l6ZSB0aGUgc2l6ZSBvZiB0aGUgZmlsZSB0byBjb3B5LgorICAgKiBAcGFyYW0gZG93bmxvYWRDb25kaXRpb25zIGNvbmRpdGlvbnMgdW5kZXIgd2hpY2ggdGhpcyBmaWxlIHNob3VsZCBiZSBjb3BpZWQuCisgICAqIEBwYXJhbSBkb3dubG9hZGVyQ2FsbGJhY2sgY2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIGNvcHkgZWl0aGVyIGNvbXBsZXRlcyBvciBmYWlscy4KKyAgICogQHBhcmFtIGlubGluZUZpbGVTb3VyY2UgU291cmNlIG9mIGZpbGUgY29udGVudCB0byBjb3B5LgorICAgKiBAcmV0dXJuIExpc3RlbmFibGVGdXR1cmUgcmVwcmVzZW50aW5nIHRoZSByZXN1bHQgb2YgYSBmaWxlIGNvcHkuCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBzdGFydENvcHlpbmcoCisgICAgICBVcmkgZmlsZVVyaSwKKyAgICAgIFN0cmluZyB1cmxUb0Rvd25sb2FkLAorICAgICAgaW50IGZpbGVTaXplLAorICAgICAgQE51bGxhYmxlIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMsCisgICAgICBEb3dubG9hZGVyQ2FsbGJhY2sgZG93bmxvYWRlckNhbGxiYWNrLAorICAgICAgRmlsZVNvdXJjZSBpbmxpbmVGaWxlU291cmNlKSB7CisgICAgaWYgKGZpbGVVcmlUb0Rvd25sb2FkRnV0dXJlTWFwLmNvbnRhaW5zS2V5KGZpbGVVcmkpKSB7CisgICAgICByZXR1cm4gZmlsZVVyaVRvRG93bmxvYWRGdXR1cmVNYXAuZ2V0KGZpbGVVcmkpOworICAgIH0KKyAgICByZXR1cm4gYWRkQ2FsbGJhY2tBbmRSZWdpc3RlcigKKyAgICAgICAgZmlsZVVyaSwKKyAgICAgICAgZG93bmxvYWRlckNhbGxiYWNrLAorICAgICAgICBzdGFydENvcHlpbmdJbnRlcm5hbCgKKyAgICAgICAgICAgIGZpbGVVcmksIHVybFRvRG93bmxvYWQsIGZpbGVTaXplLCBkb3dubG9hZENvbmRpdGlvbnMsIGlubGluZUZpbGVTb3VyY2UpKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBzdGFydENvcHlpbmdJbnRlcm5hbCgKKyAgICAgIFVyaSBmaWxlVXJpLAorICAgICAgU3RyaW5nIHVybFRvQ29weSwKKyAgICAgIGludCBmaWxlU2l6ZSwKKyAgICAgIEBOdWxsYWJsZSBEb3dubG9hZENvbmRpdGlvbnMgZG93bmxvYWRDb25kaXRpb25zLAorICAgICAgRmlsZVNvdXJjZSBpbmxpbmVGaWxlU291cmNlKSB7CisKKyAgICB0cnkgeworICAgICAgY2hlY2tTdG9yYWdlQ29uc3RyYWludHMoY29udGV4dCwgZmlsZVNpemUsIGRvd25sb2FkQ29uZGl0aW9ucywgZmxhZ3MpOworICAgIH0gY2F0Y2ggKERvd25sb2FkRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIFdyYXAgZXhjZXB0aW9uIGluIGZ1dHVyZSB0byBicmVhayBmdXR1cmUgY2hhaW4uCisgICAgICBMb2dVdGlsLmUoIiVzOiBOb3QgZW5vdWdoIHNwYWNlIHRvIGRvd25sb2FkIGZpbGUgJXMiLCBUQUcsIHVybFRvQ29weSk7CisgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoZSk7CisgICAgfQorCisgICAgLy8gVE9ETyhiLzE3NzM2MTM0NCk6IE9ubHkgbW9uaXRvciBmaWxlIGlmIGRvd25sb2FkIGxpc3RlbmVyIGlzIHN1cHBvcnRlZAorCisgICAgRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIERvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKHVybFRvQ29weSkKKyAgICAgICAgICAgIC5zZXRGaWxlVXJpKGZpbGVVcmkpCisgICAgICAgICAgICAuc2V0SW5saW5lRG93bmxvYWRQYXJhbXNPcHRpb25hbCgKKyAgICAgICAgICAgICAgICBJbmxpbmVEb3dubG9hZFBhcmFtcy5uZXdCdWlsZGVyKCkuc2V0SW5saW5lRmlsZUNvbnRlbnQoaW5saW5lRmlsZVNvdXJjZSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gVXNlIGZpbGUgZG93bmxvYWQgc3VwcGxpZXIgdG8gcGVyZm9ybSBpbmxpbmUgZmlsZSBkb3dubG9hZAorICAgIHJldHVybiBmaWxlRG93bmxvYWRlclN1cHBsaWVyLmdldCgpLnN0YXJ0RG93bmxvYWRpbmcoZG93bmxvYWRSZXF1ZXN0KTsKKyAgfQorCisgIC8qKgorICAgKiBTdG9wIGRvd25sb2FkaW5nIHRoZSBmaWxlLgorICAgKgorICAgKiBAcGFyYW0gZmlsZVVyaSAtIHRoZSBGaWxlIFVyaSBvZiB0aGUgZmlsZSB0byBzdG9wIGRvd25sb2FkaW5nLgorICAgKi8KKyAgcHVibGljIHZvaWQgc3RvcERvd25sb2FkaW5nKFVyaSBmaWxlVXJpKSB7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBwZW5kaW5nRG93bmxvYWRGdXR1cmUgPSBmaWxlVXJpVG9Eb3dubG9hZEZ1dHVyZU1hcC5nZXQoZmlsZVVyaSk7CisgICAgaWYgKHBlbmRpbmdEb3dubG9hZEZ1dHVyZSAhPSBudWxsKSB7CisgICAgICBMb2dVdGlsLmQoIiVzOiBDYW5jZWwgZG93bmxvYWQgZmlsZSAlcyIsIFRBRywgZmlsZVVyaSk7CisgICAgICBmaWxlVXJpVG9Eb3dubG9hZEZ1dHVyZU1hcC5yZW1vdmUoZmlsZVVyaSk7CisgICAgICBwZW5kaW5nRG93bmxvYWRGdXR1cmUuY2FuY2VsKHRydWUpOworICAgIH0gZWxzZSB7CisgICAgICBMb2dVdGlsLncoIiVzOiBzdG9wRG93bmxvYWRpbmcgb24gbm9uLWV4aXN0ZW50IGRvd25sb2FkIiwgVEFHKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogQ2hlY2tzIGlmIHN0b3JhZ2UgY29uc3RyYWludHMgYXJlIGVuYWJsZWQgYW5kIGlmIHNvLCBwZXJmb3JtcyBzdG9yYWdlIGNoZWNrLgorICAgKgorICAgKiA8cD5JZiBsb3cgc3RvcmFnZSBlbmZvcmNlbWVudCBpcyBlbmFibGVkLCB0aGlzIG1ldGhvZCB3aWxsIGNoZWNrIGlmIGEgZmlsZSB3aXRoIHtAY29kZQorICAgKiBieXRlc05lZWRlZH0gY2FuIGJlIHN0b3JlZCBvbiBkaXNrIHdpdGhvdXQgaGl0dGluZyB0aGUgc3RvcmFnZSB0aHJlc2hvbGQgZGVmaW5lZCBpbiB7QGNvZGUKKyAgICogZG93bmxvYWRDb25kaXRpb25zfS4KKyAgICoKKyAgICogPHA+SWYgbG93IHN0b3JhZ2UgZW5mb3JjZW1lbnQgaXMgbm90IGVuYWJsZWQsIHRoaXMgbWV0aG9kIGlzIGEgbm8tb3AuCisgICAqCisgICAqIDxwPklmIHtAY29kZSBieXRlc05lZWRlZH0gZG9lcyBoaXQgdGhlIGdpdmVuIHN0b3JhZ2UgdGhyZXNob2xkLCBhIHtAbGluayBEb3dubG9hZEV4Y2VwdGlvbn0KKyAgICogd2lsbCBiZSB0aHJvd24gd2l0aCB0aGUge0Bjb2RlIERvd25sb2FkUmVzdWx0Q29kZS5MT1dfRElTS19FUlJPUn0gZXJyb3IgY29kZS4KKyAgICoKKyAgICogQHBhcmFtIGNvbnRleHQgQ29udGV4dCBpbiB3aGljaCBzdG9yYWdlIHNob3VsZCBiZSBjaGVja2VkCisgICAqIEBwYXJhbSBieXRlc05lZWRlZCBleHBlY3RlZCBzaXplIG9mIHRoZSBmaWxlIHRvIHN0b3JlIG9uIGRpc2sKKyAgICogQHBhcmFtIGRvd25sb2FkQ29uZGl0aW9ucyBjb25kaXRpb25zIHRoYXQgY29udGFpbiB0aGUgdHlwZSBvZiBzdG9yYWdlIHRocmVzaG9sZCB0byBjaGVjaworICAgKiBAdGhyb3dzIERvd25sb2FkRXhjZXB0aW9uIHdoZW4gc3RvcmluZyBhIGZpbGUgd2l0aCB0aGUgZ2l2ZW4gc2l6ZSB3b3VsZCBoaXQgdGhlIGdpdmVuIHN0b3JhZ2UKKyAgICogICAgIHRocmVzaG9sZHMKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgdm9pZCBjaGVja1N0b3JhZ2VDb25zdHJhaW50cygKKyAgICAgIENvbnRleHQgY29udGV4dCwKKyAgICAgIGxvbmcgYnl0ZXNOZWVkZWQsCisgICAgICBATnVsbGFibGUgRG93bmxvYWRDb25kaXRpb25zIGRvd25sb2FkQ29uZGl0aW9ucywKKyAgICAgIEZsYWdzIGZsYWdzKQorICAgICAgdGhyb3dzIERvd25sb2FkRXhjZXB0aW9uIHsKKyAgICBpZiAoZmxhZ3MuZW5mb3JjZUxvd1N0b3JhZ2VCZWhhdmlvcigpCisgICAgICAgICYmICFzaG91bGREb3dubG9hZChjb250ZXh0LCBieXRlc05lZWRlZCwgZG93bmxvYWRDb25kaXRpb25zLCBmbGFncykpIHsKKyAgICAgIHRocm93IERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLkxPV19ESVNLX0VSUk9SKQorICAgICAgICAgIC5idWlsZCgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBUaGlzIGNhbGN1bGF0ZXMgaWYgdGhlIGZpbGUgc2hvdWxkIGJlIGRvd25sb2FkZWQuIEl0IGNoZWNrcyB0aGF0IGFmdGVyIGRvd25sb2FkIHlvdSBoYXZlIGF0CisgICAqIGxlYXN0IGEgY2VydGFpbiBmcmFjdGlvbiBvZiBmcmVlIHNwYWNlIG9yIGFuIGFic29sdXRlIG1pbmltdW0gc3BhY2Ugc3RpbGwgYXZhaWxhYmxlLgorICAgKgorICAgKiA8cD5UaGlzIGlzIGluIHBhcml0eSB3aXRoIHdoYXQgdGhlIERvd25sb2FkQXBpIGRvZXMtIDxpbnRlcm5hbD4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gc2hvdWxkRG93bmxvYWQoCisgICAgICBDb250ZXh0IGNvbnRleHQsCisgICAgICBsb25nIGJ5dGVzTmVlZGVkLAorICAgICAgQE51bGxhYmxlIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMsCisgICAgICBGbGFncyBmbGFncykgeworICAgIFN0YXRGcyBzdGF0cyA9IG5ldyBTdGF0RnMoY29udGV4dC5nZXRGaWxlc0RpcigpLmdldEFic29sdXRlUGF0aCgpKTsKKworICAgIGxvbmcgdG90YWxCeXRlcyA9IChsb25nKSBzdGF0cy5nZXRCbG9ja0NvdW50KCkgKiBzdGF0cy5nZXRCbG9ja1NpemUoKTsKKyAgICBsb25nIGZyZWVCeXRlcyA9IChsb25nKSBzdGF0cy5nZXRBdmFpbGFibGVCbG9ja3MoKSAqIHN0YXRzLmdldEJsb2NrU2l6ZSgpOworCisgICAgZG91YmxlIHJlbWFpbmluZ0J5dGVzQWZ0ZXJEb3dubG9hZCA9IGZyZWVCeXRlcyAtIGJ5dGVzTmVlZGVkOworCisgICAgZG91YmxlIG1pbkJ5dGVzID0KKyAgICAgICAgbWluKHRvdGFsQnl0ZXMgKiBmbGFncy5mcmFjdGlvbkZyZWVTcGFjZUFmdGVyRG93bmxvYWQoKSwgZmxhZ3MuYWJzRnJlZVNwYWNlQWZ0ZXJEb3dubG9hZCgpKTsKKworICAgIGlmIChkb3dubG9hZENvbmRpdGlvbnMgIT0gbnVsbCkgeworICAgICAgc3dpdGNoIChkb3dubG9hZENvbmRpdGlvbnMuZ2V0RGV2aWNlU3RvcmFnZVBvbGljeSgpKSB7CisgICAgICAgIGNhc2UgQkxPQ0tfRE9XTkxPQURfTE9XRVJfVEhSRVNIT0xEOgorICAgICAgICAgIG1pbkJ5dGVzID0KKyAgICAgICAgICAgICAgbWluKAorICAgICAgICAgICAgICAgICAgdG90YWxCeXRlcyAqIGZsYWdzLmZyYWN0aW9uRnJlZVNwYWNlQWZ0ZXJEb3dubG9hZCgpLAorICAgICAgICAgICAgICAgICAgZmxhZ3MuYWJzRnJlZVNwYWNlQWZ0ZXJEb3dubG9hZExvd1N0b3JhZ2VBbGxvd2VkKCkpOworICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgRVhUUkVNRUxZX0xPV19USFJFU0hPTEQ6CisgICAgICAgICAgbWluQnl0ZXMgPQorICAgICAgICAgICAgICBtaW4oCisgICAgICAgICAgICAgICAgICB0b3RhbEJ5dGVzICogZmxhZ3MuZnJhY3Rpb25GcmVlU3BhY2VBZnRlckRvd25sb2FkKCksCisgICAgICAgICAgICAgICAgICBmbGFncy5hYnNGcmVlU3BhY2VBZnRlckRvd25sb2FkRXh0cmVtZWx5TG93U3RvcmFnZUFsbG93ZWQoKSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgLy8gZmFsbHRocm91Z2guCisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHJlbWFpbmluZ0J5dGVzQWZ0ZXJEb3dubG9hZCA+IG1pbkJ5dGVzOworICB9CisKKyAgLyoqIEludGVyZmFjZSBjYWxsZWQgYnkgdGhlIGRvd25sb2FkZXIgd2hlbiBkb3dubG9hZCBlaXRoZXIgY29tcGxldGVzIG9yIGZhaWxzLiAqLworICBwdWJsaWMgc3RhdGljIGludGVyZmFjZSBEb3dubG9hZGVyQ2FsbGJhY2sgeworICAgIC8qKiBDYWxsZWQgb24gZG93bmxvYWQgY29tcGxldGUuICovCisgICAgLy8gVE9ETyhiLzEyMzQyNDU0Nik6IENvbnNpZGVyIHRvIGRyb3AgZmlsZVVyaS4KKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IG9uRG93bmxvYWRDb21wbGV0ZShVcmkgZmlsZVVyaSk7CisKKyAgICAvKiogQ2FsbGVkIG9uIGRvd25sb2FkIGZhaWxlZC4gKi8KKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IG9uRG93bmxvYWRGYWlsZWQoRG93bmxvYWRFeGNlcHRpb24gZXhjZXB0aW9uKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyL1ppcEZvbGRlck9wZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyL1ppcEZvbGRlck9wZW5lci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVjYTIxZWEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXIvWmlwRm9sZGVyT3BlbmVyLmphdmEKQEAgLTAsMCArMSw4NyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZG93bmxvYWRlcjsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuUmVhZFN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuV3JpdGVTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uaW8uQnl0ZVN0cmVhbXM7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuemlwLlppcEVudHJ5OworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC56aXAuWmlwSW5wdXRTdHJlYW07CisKKy8qKgorICogQW4gb3BlbmVyIHRha2VzIGluIGFuIG91dHB1dCBmb2xkZXIgVVJJIGFuZCBleHBhbmRzIGFsbCByZXNvdXJjZXMgaW4gdGhlIHppcCBpbnB1dCBzdHJlYW0gdG8gdGhlCisgKiBmb2xkZXIuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBaaXBGb2xkZXJPcGVuZXIgaW1wbGVtZW50cyBPcGVuZXI8Vm9pZD4geworCisgIHByaXZhdGUgZmluYWwgVXJpIHRhcmdldEZvbGRlclVyaTsKKyAgcHJpdmF0ZSBmaW5hbCBTYWZlclppcFV0aWxzIHppcFV0aWxzOworCisgIHByaXZhdGUgWmlwRm9sZGVyT3BlbmVyKFVyaSB0YXJnZXRGb2xkZXJVcmkpIHsKKyAgICB0aGlzLnRhcmdldEZvbGRlclVyaSA9IHRhcmdldEZvbGRlclVyaTsKKyAgICB0aGlzLnppcFV0aWxzID0gbmV3IFNhZmVyWmlwVXRpbHMoKSB7fTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgWmlwRm9sZGVyT3BlbmVyIGNyZWF0ZShVcmkgdGFyZ2V0Rm9sZGVyVXJpKSB7CisgICAgcmV0dXJuIG5ldyBaaXBGb2xkZXJPcGVuZXIodGFyZ2V0Rm9sZGVyVXJpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgVm9pZCBvcGVuKE9wZW5Db250ZXh0IG9wZW5Db250ZXh0KSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UgPSBvcGVuQ29udGV4dC5zdG9yYWdlKCk7CisgICAgdHJ5IChaaXBJbnB1dFN0cmVhbSB6aXBJbnB1dFN0cmVhbSA9CisgICAgICAgIG5ldyBaaXBJbnB1dFN0cmVhbShSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLndpdGhCdWZmZXJlZElvKCkub3BlbihvcGVuQ29udGV4dCkpKSB7CisgICAgICAvLyBJdGVyYXRlIGFsbCBlbnRyaWVzIGFuZCB3cml0ZSB0byB0YXJnZXQgVVJJIG9uZSBieSBvbmUKKyAgICAgIFppcEVudHJ5IHppcEVudHJ5OworICAgICAgd2hpbGUgKCh6aXBFbnRyeSA9IHppcElucHV0U3RyZWFtLmdldE5leHRFbnRyeSgpKSAhPSBudWxsKSB7CisgICAgICAgIFN0cmluZyBwYXRoID0gemlwVXRpbHMuZ2V0VmFsaWRhdGVkTmFtZSh6aXBFbnRyeSk7CisgICAgICAgIFVyaSB1cmkgPSB0YXJnZXRGb2xkZXJVcmkuYnVpbGRVcG9uKCkuYXBwZW5kUGF0aChwYXRoKS5idWlsZCgpOworICAgICAgICBpZiAoemlwRW50cnkuaXNEaXJlY3RvcnkoKSkgeworICAgICAgICAgIGZpbGVTdG9yYWdlLmNyZWF0ZURpcmVjdG9yeSh1cmkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IGZpbGVTdG9yYWdlLm9wZW4odXJpLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgICAgICAgIEJ5dGVTdHJlYW1zLmNvcHkoemlwSW5wdXRTdHJlYW0sIG91dCk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CisgICAgICAvLyBDbGVhbnVwIHRoZSB0YXJnZXQgZGlyZWN0b3J5IGlmIGFueSBlcnJvciBvY2N1cnJlZC4KKyAgICAgIGZpbGVTdG9yYWdlLmRlbGV0ZVJlY3Vyc2l2ZWx5KHRhcmdldEZvbGRlclVyaSk7CisgICAgICB0aHJvdyBpb2U7CisgICAgfQorICAgIHJldHVybiBudWxsOworICB9CisKKyAgLyoqIFV0aWxpdGllcyBmb3Igc2FmZWx5IGFjY2Vzc2luZyBaaXBFbnRyeSBBUElzLiAqLworICBwcml2YXRlIGludGVyZmFjZSBTYWZlclppcFV0aWxzIHsKKyAgICAvKioKKyAgICAgKiBSZXR1cm4gdGhlIG5hbWUgb2YgYSBaaXBFbnRyeSBhZnRlciB2ZXJpZnlpbmcgdGhhdCBpdCBkb2VzIG5vdCBleHBsb2l0IGFueSBwYXRoIHRyYXZlcnNhbAorICAgICAqIGF0dGFja3MuCisgICAgICoKKyAgICAgKiBAdGhyb3dzIFppcEV4Y2VwdGlvbiBpZiB7QGNvZGUgemlwRW50cnl9IGNvbnRhaW5zIGFueSBwb3NzaWJsZSBwYXRoIHRyYXZlcnNhbCBjaGFyYWN0ZXJzLgorICAgICAqLworICAgIGRlZmF1bHQgU3RyaW5nIGdldFZhbGlkYXRlZE5hbWUoWmlwRW50cnkgZW50cnkpIHRocm93cyBaaXBFeGNlcHRpb24geworICAgICAgcmV0dXJuIGVudHJ5LmdldE5hbWUoKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZXhwZXJpbWVudGF0aW9uL0JVSUxEIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9leHBlcmltZW50YXRpb24vQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmZhNmZjOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZXhwZXJpbWVudGF0aW9uL0JVSUxECkBAIC0wLDAgKzEsNDIgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsKKyAgICAgICAgIi8vdmlzaWJpbGl0eTpwdWJsaWMiLAorICAgIF0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJEb3dubG9hZFN0YWdlTWFuYWdlciIsCisgICAgc3JjcyA9IFsiRG93bmxvYWRTdGFnZU1hbmFnZXIuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2Vycm9ycHJvbmVfZXJyb3JfcHJvbmVfYW5ub3RhdGlvbnMiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk5vT3BEb3dubG9hZFN0YWdlTWFuYWdlciIsCisgICAgc3JjcyA9IFsiTm9PcERvd25sb2FkU3RhZ2VNYW5hZ2VyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOkRvd25sb2FkU3RhZ2VNYW5hZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZXJyb3Jwcm9uZV9lcnJvcl9wcm9uZV9hbm5vdGF0aW9ucyIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZXhwZXJpbWVudGF0aW9uL0Rvd25sb2FkU3RhZ2VNYW5hZ2VyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2V4cGVyaW1lbnRhdGlvbi9Eb3dubG9hZFN0YWdlTWFuYWdlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiOTE0NzIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2V4cGVyaW1lbnRhdGlvbi9Eb3dubG9hZFN0YWdlTWFuYWdlci5qYXZhCkBAIC0wLDAgKzEsNTQgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmV4cGVyaW1lbnRhdGlvbjsKKworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DaGVja1JldHVyblZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworCisvKiogUmVzcG9uc2libGUgZm9yIGF0dGFjaGluZyBleHRlcm5hbCBleHBlcmltZW50IGlkcyB0byBsb2cgc291cmNlcy4gKi8KK0BDaGVja1JldHVyblZhbHVlCitwdWJsaWMgaW50ZXJmYWNlIERvd25sb2FkU3RhZ2VNYW5hZ2VyIHsKKworICAvKioKKyAgICogQ2xlYXIgYWxsIHNldCBleHBlcmltZW50IGlkcyBmcm9tIHBoZW5vdHlwZS4KKyAgICoKKyAgICogPHA+Tm90ZTogdGhpcyBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgYW55IG1ldGFkYXRhIGlzIGNsZWFyZWQgc2luY2UgdGhpcyByZWFkcyBmcm9tIG1ldGFkYXRhIHRvCisgICAqIGxlYXJuIHdoaWNoIGJ1aWxkcyB0byBjbGVhci4KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gY2xlYXJBbGwoKTsKKworICAvKioKKyAgICogRm9yIGVhY2ggZmlsZSBncm91cDogaWYgdGhlcmUgYXJlIG5vIGFjdGl2ZSB2ZXJzaW9ucyBvZiB0aGUgYnVpbGQsIGFsbCBleHBlcmltZW50IGlkcyBhcmUKKyAgICogcmVtb3ZlZCBmcm9tIHBoZW5vdHlwZS4gSWYgdGhlcmUgYXJlIGFjdGl2ZSB2ZXJzaW9ucyBvZiB0aGUgYnVpbGQgKHdoaWNoIGNhbiBoYXBwZW4gaWYgdGhlcmUKKyAgICogYXJlIG11bHRpcGxlIHZhcmlhbnRzL2FjY291bnRzKSwgdGhpcyB3aWxsIHVwZGF0ZSB0aGUgZXhwZXJpbWVudCBpZHMgdG8gcmVmbGVjdCB0aGUgY3VycmVudAorICAgKiBzdGF0ZSBnaXZlbiB0aGF0IGFuIGluc3RhbmNlIG9mIHRoZSBidWlsZCB3YXMgcmVtb3ZlZC4KKyAgICoKKyAgICogQHBhcmFtIGZpbGVHcm91cHNUb0NsZWFyIHRoZSBmaWxlIGdyb3VwcyB0byByZW1vdmUgZXhwZXJpbWVudCBpZHMKKyAgICogQHJldHVybiBhIGZ1dHVyZSBzaWduYWxsaW5nIGNvbXBsZXRpb24gb2YgdGhlIHRhc2sKKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gY2xlYXJFeHBlcmltZW50SWRzRm9yQnVpbGRzSWZOb25lQWN0aXZlKAorICAgICAgQ29sbGVjdGlvbjxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGZpbGVHcm91cHNUb0NsZWFyKTsKKworICAvKioKKyAgICogUHJvcGFnYXRlcyB0aGUgZXhwZXJpbWVudCBpZHMgZm9yIHtAY29kZSBncm91cE5hbWV9IHRvIHBoZW5vdHlwZS4gSWYgdGhlcmUgYXJlIG11bHRpcGxlIGFjdGl2ZQorICAgKiBidWlsZHMgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgYWxsIGV4cGVyaW1lbnQgaWRzIHdpbGwgYmUgcHJvcGFnYXRlZC4KKyAgICoKKyAgICogPHA+QW55IGZhaWx1cmVzIGVuY291bnRlcmVkIHdpbGwgYmUgcHJvcGFnYXRlZCB0byB0aGUgcmV0dXJuZWQgZnV0dXJlLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiB1cGRhdGVFeHBlcmltZW50SWRzKFN0cmluZyBncm91cE5hbWUpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9leHBlcmltZW50YXRpb24vTm9PcERvd25sb2FkU3RhZ2VNYW5hZ2VyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2V4cGVyaW1lbnRhdGlvbi9Ob09wRG93bmxvYWRTdGFnZU1hbmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iNDU1M2UxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9leHBlcmltZW50YXRpb24vTm9PcERvd25sb2FkU3RhZ2VNYW5hZ2VyLmphdmEKQEAgLTAsMCArMSw1MSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZXhwZXJpbWVudGF0aW9uOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmU7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmVycm9ycHJvbmUuYW5ub3RhdGlvbnMuQ2hlY2tSZXR1cm5WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbDsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKKworLyoqIEltcGxlbWVudGF0aW9uIG9mIERvd25sb2FkU3RhZ2VNYW5hZ2VyIHRoYXQgZG9lcyBub3RoaW5nLiAqLworQENoZWNrUmV0dXJuVmFsdWUKK3B1YmxpYyBmaW5hbCBjbGFzcyBOb09wRG93bmxvYWRTdGFnZU1hbmFnZXIgaW1wbGVtZW50cyBEb3dubG9hZFN0YWdlTWFuYWdlciB7CisKKyAgLyoqIENsZWFyIGFsbCBzZXQgZXhwZXJpbWVudCBpZHMgZnJvbSBwaGVub3R5cGUuICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjbGVhckFsbCgpIHsKKyAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNsZWFyRXhwZXJpbWVudElkc0ZvckJ1aWxkc0lmTm9uZUFjdGl2ZSgKKyAgICAgIENvbGxlY3Rpb248RGF0YUZpbGVHcm91cEludGVybmFsPiBmaWxlR3JvdXBzVG9DbGVhcikgeworICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgIH0KKworICAvKioKKyAgICogUHJvcGFnYXRlcyB0aGUgZXhwZXJpbWVudCBpZHMgZm9yIHtAY29kZSBncm91cE5hbWV9IHRvIHBoZW5vdHlwZS4gSWYgdGhlcmUgYXJlIG11bHRpcGxlIGFjdGl2ZQorICAgKiBidWlsZHMgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgYWxsIGV4cGVyaW1lbnQgaWRzIHdpbGwgYmUgcHJvcGFnYXRlZC4KKyAgICoKKyAgICogPHA+QW55IGZhaWx1cmVzIGVuY291bnRlcmVkIHdpbGwgYmUgcHJvcGFnYXRlZCB0byB0aGUgcmV0dXJuZWQgZnV0dXJlLgorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHVwZGF0ZUV4cGVyaW1lbnRJZHMoU3RyaW5nIGdyb3VwTmFtZSkgeworICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZWE5NTUwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL0JVSUxECkBAIC0wLDAgKzEsMTY4IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9saWJyYXJ5IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiTG9nVXRpbCIsCisgICAgc3JjcyA9IFsiTG9nVXRpbC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2Vycm9ycHJvbmVfZXJyb3JfcHJvbmVfYW5ub3RhdGlvbnMiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkV2ZW50TG9nZ2VyIiwKKyAgICBzcmNzID0gWyJFdmVudExvZ2dlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX2F1dG9fdmFsdWUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk5vT3BFdmVudExvZ2dlciIsCisgICAgc3JjcyA9IFsiTm9PcEV2ZW50TG9nZ2VyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOkV2ZW50TG9nZ2VyIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJGaWxlR3JvdXBTdGF0c0xvZ2dlciIsCisgICAgc3JjcyA9IFsiRmlsZUdyb3VwU3RhdHNMb2dnZXIuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6RXZlbnRMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkZpbGVHcm91cE1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvYW5ub3RhdGlvbnM6U2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nOmNvbmN1cnJlbnQiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGphdmF4X2luamVjdCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiRG93bmxvYWRTdGF0ZUxvZ2dlciIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkRvd25sb2FkU3RhdGVMb2dnZXIuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOkV2ZW50TG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGFuZHJvaWR4X2Fubm90YXRpb25fYW5ub3RhdGlvbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9lcnJvcnByb25lX2Vycm9yX3Byb25lX2Fubm90YXRpb25zIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJNZGRFdmVudExvZ2dlciIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIk1kZEV2ZW50TG9nZ2VyLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpFdmVudExvZ2dlciIsCisgICAgICAgICI6TG9nU2FtcGxlciIsCisgICAgICAgICI6TG9nVXRpbCIsCisgICAgICAgICI6TG9nZ2luZ1N0YXRlU3RvcmUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3RyYWNpbmc6Y29uY3VycmVudCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiU3RvcmFnZUxvZ2dlciIsCisgICAgc3JjcyA9IFsiU3RvcmFnZUxvZ2dlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpFdmVudExvZ2dlciIsCisgICAgICAgICI6TG9nVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6U2lsZW50RmVlZGJhY2siLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Fubm90YXRpb25zIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpBcHBsaWNhdGlvbkNvbnRleHQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TWRkQ29uc3RhbnRzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpNZGRFeGNlcHRpb25zIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpTaGFyZWRGaWxlTWFuYWdlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6U2hhcmVkRmlsZXNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvYW5ub3RhdGlvbnM6U2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOkZpbGVHcm91cFV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3RyYWNpbmc6Y29uY3VycmVudCIsCisgICAgICAgICJAY29tX2dvb2dsZV9hdXRvX3ZhbHVlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBqYXZheF9pbmplY3QiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk5ldHdvcmtMb2dnZXIiLAorICAgIHNyY3MgPSBbIk5ldHdvcmtMb2dnZXIuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6RXZlbnRMb2dnZXIiLAorICAgICAgICAiOkxvZ2dpbmdTdGF0ZVN0b3JlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYW5ub3RhdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkFwcGxpY2F0aW9uQ29udGV4dCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nOmNvbmN1cnJlbnQiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGphdmF4X2luamVjdCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiTG9nZ2luZ1N0YXRlU3RvcmUiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJMb2dnaW5nU3RhdGVTdG9yZS5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJMb2dTYW1wbGVyIiwKKyAgICBzcmNzID0gWyJMb2dTYW1wbGVyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOkxvZ1V0aWwiLAorICAgICAgICAiOkxvZ2dpbmdTdGF0ZVN0b3JlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZzpjb25jdXJyZW50IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2Vycm9ycHJvbmVfZXJyb3JfcHJvbmVfYW5ub3RhdGlvbnMiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk5vT3BMb2dnaW5nU3RhdGUiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJOb09wTG9nZ2luZ1N0YXRlLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpMb2dnaW5nU3RhdGVTdG9yZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL0Rvd25sb2FkU3RhdGVMb2dnZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9Eb3dubG9hZFN0YXRlTG9nZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYThmMzg4ZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9Eb3dubG9hZFN0YXRlTG9nZ2VyLmphdmEKQEAgLTAsMCArMSwxMjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmc7CisKK2ltcG9ydCBhbmRyb2lkeC5hbm5vdGF0aW9uLlZpc2libGVGb3JUZXN0aW5nOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DaGVja1JldHVyblZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworCisvKiogSGVscGVyIGxvZ2dlciB0byBsb2cgdGhlIGV2ZW50cyBhc3NvY2lhdGVkIHdpdGggYW4gTUREIERvd25sb2FkIG9yIEltcG9ydCBvcGVyYXRpb24uICovCitAQ2hlY2tSZXR1cm5WYWx1ZQorcHVibGljIGZpbmFsIGNsYXNzIERvd25sb2FkU3RhdGVMb2dnZXIgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIkZpbGVHcm91cFN0YXR1c0xvZ2dlciI7CisKKyAgQFZpc2libGVGb3JUZXN0aW5nCisgIGVudW0gT3BlcmF0aW9uIHsKKyAgICBET1dOTE9BRCwKKyAgICBJTVBPUlQsCisgIH07CisKKyAgcHJpdmF0ZSBmaW5hbCBFdmVudExvZ2dlciBldmVudExvZ2dlcjsKKyAgcHJpdmF0ZSBmaW5hbCBPcGVyYXRpb24gb3BlcmF0aW9uOworCisgIHByaXZhdGUgRG93bmxvYWRTdGF0ZUxvZ2dlcihFdmVudExvZ2dlciBldmVudExvZ2dlciwgT3BlcmF0aW9uIG9wZXJhdGlvbikgeworICAgIHRoaXMuZXZlbnRMb2dnZXIgPSBldmVudExvZ2dlcjsKKyAgICB0aGlzLm9wZXJhdGlvbiA9IG9wZXJhdGlvbjsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgRG93bmxvYWRTdGF0ZUxvZ2dlciBmb3JEb3dubG9hZChFdmVudExvZ2dlciBldmVudExvZ2dlcikgeworICAgIHJldHVybiBuZXcgRG93bmxvYWRTdGF0ZUxvZ2dlcihldmVudExvZ2dlciwgT3BlcmF0aW9uLkRPV05MT0FEKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgRG93bmxvYWRTdGF0ZUxvZ2dlciBmb3JJbXBvcnQoRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXIpIHsKKyAgICByZXR1cm4gbmV3IERvd25sb2FkU3RhdGVMb2dnZXIoZXZlbnRMb2dnZXIsIE9wZXJhdGlvbi5JTVBPUlQpOworICB9CisKKyAgcHVibGljIHZvaWQgbG9nU3RhcnRlZChEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwKSB7CisgICAgc3dpdGNoIChvcGVyYXRpb24pIHsKKyAgICAgIGNhc2UgRE9XTkxPQUQ6CisgICAgICAgIGxvZ0V2ZW50V2l0aERhdGFGaWxlR3JvdXAoMCwgZmlsZUdyb3VwKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIElNUE9SVDoKKyAgICAgICAgbG9nRXZlbnRXaXRoRGF0YUZpbGVHcm91cCgwLCBmaWxlR3JvdXApOworICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBsb2dQZW5kaW5nKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXApIHsKKyAgICBzd2l0Y2ggKG9wZXJhdGlvbikgeworICAgICAgY2FzZSBET1dOTE9BRDoKKyAgICAgICAgbG9nRXZlbnRXaXRoRGF0YUZpbGVHcm91cCgwLCBmaWxlR3JvdXApOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSU1QT1JUOgorICAgICAgICBsb2dFdmVudFdpdGhEYXRhRmlsZUdyb3VwKDAsIGZpbGVHcm91cCk7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgIHB1YmxpYyB2b2lkIGxvZ0ZhaWxlZChEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwKSB7CisgICAgc3dpdGNoIChvcGVyYXRpb24pIHsKKyAgICAgIGNhc2UgRE9XTkxPQUQ6CisgICAgICAgIGxvZ0V2ZW50V2l0aERhdGFGaWxlR3JvdXAoMCwgZmlsZUdyb3VwKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIElNUE9SVDoKKyAgICAgICAgbG9nRXZlbnRXaXRoRGF0YUZpbGVHcm91cCgwLCBmaWxlR3JvdXApOworICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKworICBwdWJsaWMgdm9pZCBsb2dDb21wbGV0ZShEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwKSB7CisgICAgc3dpdGNoIChvcGVyYXRpb24pIHsKKyAgICAgIGNhc2UgRE9XTkxPQUQ6CisgICAgICAgIGxvZ0V2ZW50V2l0aERhdGFGaWxlR3JvdXAoMCwgZmlsZUdyb3VwKTsKKyAgICAgICAgbG9nRG93bmxvYWRMYXRlbmN5KGZpbGVHcm91cCk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBJTVBPUlQ6CisgICAgICAgIGxvZ0V2ZW50V2l0aERhdGFGaWxlR3JvdXAoMCwgZmlsZUdyb3VwKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSB2b2lkIGxvZ0Rvd25sb2FkTGF0ZW5jeShEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwKSB7CisgICAgLy8gVGhpcyBvcGVyYXRpb24gb25seSBtYWtlcyBzZW5zZSBmb3IgZG93bmxvYWQgb3BlcmF0aW9uLCBleGl0IGVhcmx5IGlmIGl0J3Mgbm90IHRoZSBkb3dubG9hZAorICAgIC8vIG9wZXJhdGlvbi4KKyAgICBpZiAob3BlcmF0aW9uICE9IE9wZXJhdGlvbi5ET1dOTE9BRCkgeworICAgICAgcmV0dXJuOworICAgIH0KKworICAgIFZvaWQgZmlsZUdyb3VwRGV0YWlscyA9IG51bGw7CisKKyAgICBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcgYm9va2tlZXBpbmcgPSBmaWxlR3JvdXAuZ2V0Qm9va2tlZXBpbmcoKTsKKyAgICBsb25nIG5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXAgPSBib29ra2VlcGluZy5nZXRHcm91cE5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXAoKTsKKyAgICBsb25nIGRvd25sb2FkU3RhcnRlZFRpbWVzdGFtcCA9IGJvb2trZWVwaW5nLmdldEdyb3VwRG93bmxvYWRTdGFydGVkVGltZXN0YW1wSW5NaWxsaXMoKTsKKyAgICBsb25nIGRvd25sb2FkQ29tcGxldGVUaW1lc3RhbXAgPSBib29ra2VlcGluZy5nZXRHcm91cERvd25sb2FkZWRUaW1lc3RhbXBJbk1pbGxpcygpOworCisgICAgVm9pZCBkb3dubG9hZExhdGVuY3kgPSBudWxsOworCisgICAgZXZlbnRMb2dnZXIubG9nTWRkRG93bmxvYWRMYXRlbmN5KGZpbGVHcm91cERldGFpbHMsIGRvd25sb2FkTGF0ZW5jeSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgbG9nRXZlbnRXaXRoRGF0YUZpbGVHcm91cChpbnQgY29kZSwgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCkgeworICAgIGV2ZW50TG9nZ2VyLmxvZ0V2ZW50U2FtcGxlZCgKKyAgICAgICAgY29kZSwKKyAgICAgICAgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpLAorICAgICAgICBmaWxlR3JvdXAuZ2V0RmlsZUdyb3VwVmVyc2lvbk51bWJlcigpLAorICAgICAgICBmaWxlR3JvdXAuZ2V0QnVpbGRJZCgpLAorICAgICAgICBmaWxlR3JvdXAuZ2V0VmFyaWFudElkKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvRXZlbnRMb2dnZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9FdmVudExvZ2dlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxZWQyNzYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvRXZlbnRMb2dnZXIuamF2YQpAQCAtMCwwICsxLDExNyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZzsKKworaW1wb3J0IGNvbS5nb29nbGUuYXV0by52YWx1ZS5BdXRvVmFsdWU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFzeW5jQ2FsbGFibGU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKiBJbnRlcmZhY2UgZm9yIHJlbW90ZSBsb2dnaW5nLiAqLworcHVibGljIGludGVyZmFjZSBFdmVudExvZ2dlciB7CisKKyAgLyoqIExvZyBhbiBtZGQgZXZlbnQgKi8KKyAgdm9pZCBsb2dFdmVudFNhbXBsZWQoaW50IGV2ZW50Q29kZSk7CisKKyAgLyoqIExvZyBhbiBtZGQgZXZlbnQgd2l0aCBhbiBhc3NvY2lhdGVkIGZpbGUgZ3JvdXAuICovCisgIHZvaWQgbG9nRXZlbnRTYW1wbGVkKAorICAgICAgaW50IGV2ZW50Q29kZSwKKyAgICAgIFN0cmluZyBmaWxlR3JvdXBOYW1lLAorICAgICAgaW50IGZpbGVHcm91cFZlcnNpb25OdW1iZXIsCisgICAgICBsb25nIGJ1aWxkSWQsCisgICAgICBTdHJpbmcgdmFyaWFudElkKTsKKworICAvKioKKyAgICogTG9nIGFuIG1kZCBldmVudC4gVGhpcyBub3Qgc2FtcGxlZC4gQ2FsbGVyIHNob3VsZCBtYWtlIHN1cmUgdGhpcyBtZXRob2QgaXMgY2FsbGVkIGFmdGVyCisgICAqIHNhbXBsaW5nIGF0IHRoZSBwYXNzZWQgaW4gdmFsdWUgb2Ygc2FtcGxlIGludGVydmFsLgorICAgKi8KKyAgdm9pZCBsb2dFdmVudEFmdGVyU2FtcGxlKGludCBldmVudENvZGUsIGludCBzYW1wbGVJbnRlcnZhbCk7CisKKyAgLyoqCisgICAqIExvZyBtZGQgZmlsZSBncm91cCBzdGF0cy4gVGhlIGJ1aWxkRmlsZUdyb3VwU3RhdHMgY2FsbGFibGUgaXMgb25seSBjYWxsZWQgaWYgdGhlIGV2ZW50IGlzIGdvaW5nCisgICAqIHRvIGJlIGxvZ2dlZC4KKyAgICoKKyAgICogQHBhcmFtIGJ1aWxkRmlsZUdyb3VwU3RhdHMgY2FsbGFibGUgd2hpY2ggYnVpbGRzIGEgTGlzdCBvZiBGaWxlR3JvdXBTdGF0dXNXaXRoRGV0YWlscy4gRWFjaAorICAgKiAgICAgZmlsZSBncm91cCBzdGF0dXMgd2lsbCBiZSBsb2dnZWQgaW5kaXZpZHVhbGx5LgorICAgKiBAcmV0dXJuIGEgZnV0dXJlIHRoYXQgY29tcGxldGVzIHdoZW4gdGhlIGxvZ2dpbmcgd29yayBpcyBkb25lLiBUaGUgZnV0dXJlIHdpbGwgY29tcGxldGUgd2l0aCBhCisgICAqICAgICBmYWlsdXJlIGlmIHRoZSBjYWxsYWJsZSBmYWlscyBvciBpZiB0aGVyZSBpcyBhbiBlcnJvciB3aGVuIGxvZ2dpbmcuCisgICAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGxvZ01kZEZpbGVHcm91cFN0YXRzKAorICAgICAgQXN5bmNDYWxsYWJsZTxMaXN0PEZpbGVHcm91cFN0YXR1c1dpdGhEZXRhaWxzPj4gYnVpbGRGaWxlR3JvdXBTdGF0cyk7CisKKyAgLyoqIFNpbXBsZSB3cmFwcGVyIGNsYXNzIGZvciBNREQgZmlsZSBncm91cCBzdGF0cyBhbmQgZGV0YWlscy4gKi8KKyAgQEF1dG9WYWx1ZQorICBhYnN0cmFjdCBjbGFzcyBGaWxlR3JvdXBTdGF0dXNXaXRoRGV0YWlscyB7CisgICAgYWJzdHJhY3QgVm9pZCBmaWxlR3JvdXBTdGF0dXMoKTsKKworICAgIGFic3RyYWN0IFZvaWQgZmlsZUdyb3VwRGV0YWlscygpOworCisgICAgc3RhdGljIEZpbGVHcm91cFN0YXR1c1dpdGhEZXRhaWxzIGNyZWF0ZShWb2lkIGZpbGVHcm91cFN0YXR1cywgVm9pZCBmaWxlR3JvdXBEZXRhaWxzKSB7CisgICAgICByZXR1cm4gbmV3IEF1dG9WYWx1ZV9FdmVudExvZ2dlcl9GaWxlR3JvdXBTdGF0dXNXaXRoRGV0YWlscygKKyAgICAgICAgICBmaWxlR3JvdXBTdGF0dXMsIGZpbGVHcm91cERldGFpbHMpOworICAgIH0KKyAgfQorCisgIC8qKiBMb2cgbWRkIGFwaSBjYWxsIHN0YXRzLiAqLworICB2b2lkIGxvZ01kZEFwaUNhbGxTdGF0cyhWb2lkIGZpbGVHcm91cERldGFpbHMsIFZvaWQgYXBpQ2FsbFN0YXRzKTsKKworICAvKioKKyAgICogTG9nIG1kZCBzdG9yYWdlIHN0YXRzLiBUaGUgYnVpbGRNZGRTdG9yYWdlU3RhdHMgY2FsbGFibGUgaXMgb25seSBjYWxsZWQgaWYgdGhlIGV2ZW50IGlzIGdvaW5nCisgICAqIHRvIGJlIGxvZ2dlZC4KKyAgICoKKyAgICogQHBhcmFtIGJ1aWxkTWRkU3RvcmFnZVN0YXRzIGNhbGxhYmxlIHdoaWNoIGJ1aWxkcyB0aGUgVm9pZCB0byBsb2cuCisgICAqIEByZXR1cm4gYSBmdXR1cmUgdGhhdCBjb21wbGV0ZXMgd2hlbiB0aGUgbG9nZ2luZyB3b3JrIGlzIGRvbmUuIFRoZSBmdXR1cmUgd2lsbCBjb21wbGV0ZSB3aXRoIGEKKyAgICogICAgIGZhaWx1cmUgaWYgdGhlIGNhbGxhYmxlIGZhaWxzIG9yIGlmIHRoZXJlIGlzIGFuIGVycm9yIHdoZW4gbG9nZ2luZy4KKyAgICovCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gbG9nTWRkU3RvcmFnZVN0YXRzKEFzeW5jQ2FsbGFibGU8Vm9pZD4gYnVpbGRNZGRTdG9yYWdlU3RhdHMpOworCisgIC8qKgorICAgKiBMb2cgbWRkIG5ldHdvcmsgc3RhdHMuIFRoZSBidWlsZE1kZE5ldHdvcmtTdGF0cyBjYWxsYWJsZSBpcyBvbmx5IGNhbGxlZCBpZiB0aGUgZXZlbnQgaXMgZ29pbmcKKyAgICogdG8gYmUgbG9nZ2VkLgorICAgKgorICAgKiBAcGFyYW0gYnVpbGRNZGROZXR3b3JrU3RhdHMgY2FsbGFibGUgd2hpY2ggYnVpbGRzIHRoZSBWb2lkIHRvIGxvZy4KKyAgICogQHJldHVybiBhIGZ1dHVyZSB0aGF0IGNvbXBsZXRlcyB3aGVuIHRoZSBsb2dnaW5nIHdvcmsgaXMgZG9uZS4gVGhlIGZ1dHVyZSB3aWxsIGNvbXBsZXRlIHdpdGggYQorICAgKiAgICAgZmFpbHVyZSBpZiB0aGUgY2FsbGFibGUgZmFpbHMgb3IgaWYgdGhlcmUgaXMgYW4gZXJyb3Igd2hlbiBsb2dnaW5nLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBsb2dNZGROZXR3b3JrU3RhdHMoQXN5bmNDYWxsYWJsZTxWb2lkPiBidWlsZE1kZE5ldHdvcmtTdGF0cyk7CisKKyAgLyoqIExvZyB0aGUgbnVtYmVyIG9mIHVuYWNjb3VudGVkIGZpbGVzL21ldGFkYXRhIGRlbGV0ZWQgZHVyaW5nIG1haW50ZW5hbmNlICovCisgIHZvaWQgbG9nTWRkRGF0YURvd25sb2FkRmlsZUV4cGlyYXRpb25FdmVudChpbnQgZXZlbnRDb2RlLCBpbnQgY291bnQpOworCisgIC8qKiBMb2cgdGhlIG5ldHdvcmsgc2F2aW5ncyBvZiBNREQgZG93bmxvYWQgZmVhdHVyZXMgKi8KKyAgdm9pZCBsb2dNZGROZXR3b3JrU2F2aW5ncygKKyAgICAgIFZvaWQgZmlsZUdyb3VwRGV0YWlscywKKyAgICAgIGludCBjb2RlLAorICAgICAgbG9uZyBmdWxsRmlsZVNpemUsCisgICAgICBsb25nIGRvd25sb2FkZWRGaWxlU2l6ZSwKKyAgICAgIFN0cmluZyBmaWxlSWQsCisgICAgICBpbnQgZGVsdGFJbmRleCk7CisKKyAgLyoqIExvZyBtZGQgZG93bmxvYWQgcmVzdWx0IGV2ZW50cy4gKi8KKyAgdm9pZCBsb2dNZGREb3dubG9hZFJlc3VsdChpbnQgY29kZSwgVm9pZCBmaWxlR3JvdXBEZXRhaWxzKTsKKworICAvKiogTG9nIHN0YXRzIG9mIG1kZCB7QGNvZGUgZ2V0RmlsZUdyb3VwfSBhbmQge0Bjb2RlIGdldEZpbGVHcm91cEJ5RmlsdGVyfSBjYWxscy4gKi8KKyAgdm9pZCBsb2dNZGRRdWVyeVN0YXRzKFZvaWQgZmlsZUdyb3VwRGV0YWlscyk7CisKKyAgLyoqIExvZyBtZGQgc3RhdHMgb24gYW5kcm9pZCBzaGFyaW5nIGV2ZW50cy4gKi8KKyAgdm9pZCBsb2dNZGRBbmRyb2lkU2hhcmluZ0xvZyhWb2lkIGV2ZW50KTsKKworICAvKiogTG9nIG1kZCBkb3dubG9hZCBsYXRlbmN5LiAqLworICB2b2lkIGxvZ01kZERvd25sb2FkTGF0ZW5jeShWb2lkIGZpbGVHcm91cFN0YXRzLCBWb2lkIGRvd25sb2FkTGF0ZW5jeSk7CisKKyAgLyoqIExvZyBtZGQgdXNhZ2UgZXZlbnQuICovCisgIHZvaWQgbG9nTWRkVXNhZ2VFdmVudChWb2lkIGZpbGVHcm91cERldGFpbHMsIFZvaWQgdXNhZ2VFdmVudExvZyk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvRmlsZUdyb3VwU3RhdHNMb2dnZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9GaWxlR3JvdXBTdGF0c0xvZ2dlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4MDNjMzMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvRmlsZUdyb3VwU3RhdHNMb2dnZXIuamF2YQpAQCAtMCwwICsxLDk0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nOworCitpbXBvcnQgYW5kcm9pZC51dGlsLlBhaXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuRmlsZUdyb3VwTWFuYWdlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5GaWxlR3JvdXBzTWV0YWRhdGE7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuYW5ub3RhdGlvbnMuU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlByb3BhZ2F0ZWRGdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uR3JvdXBLZXk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZheC5pbmplY3QuSW5qZWN0OworCisvKioKKyAqIExvZyBNREQgZmlsZSBncm91cCBzdGF0cy4gRm9yIGVhY2ggZmlsZSBncm91cCwgaXQgd2lsbCBsb2cgdGhlIGZpbGUgZ3JvdXAgZGV0YWlscyBhbG9uZyB3aXRoIHRoZQorICogY3VycmVudCBzdGF0ZSBvZiB0aGUgZmlsZSBncm91cCAocGVuZGluZywgZG93bmxvYWRlZCBvciBzdGFsZSkuCisgKi8KK3B1YmxpYyBjbGFzcyBGaWxlR3JvdXBTdGF0c0xvZ2dlciB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJGaWxlR3JvdXBTdGF0c0xvZ2dlciI7CisgIHByaXZhdGUgZmluYWwgRmlsZUdyb3VwTWFuYWdlciBmaWxlR3JvdXBNYW5hZ2VyOworICBwcml2YXRlIGZpbmFsIEZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGE7CisgIHByaXZhdGUgZmluYWwgRXZlbnRMb2dnZXIgZXZlbnRMb2dnZXI7CisgIHByaXZhdGUgZmluYWwgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKworICBASW5qZWN0CisgIHB1YmxpYyBGaWxlR3JvdXBTdGF0c0xvZ2dlcigKKyAgICAgIEZpbGVHcm91cE1hbmFnZXIgZmlsZUdyb3VwTWFuYWdlciwKKyAgICAgIEZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGEsCisgICAgICBFdmVudExvZ2dlciBldmVudExvZ2dlciwKKyAgICAgIEBTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpIHsKKyAgICB0aGlzLmZpbGVHcm91cE1hbmFnZXIgPSBmaWxlR3JvdXBNYW5hZ2VyOworICAgIHRoaXMuZmlsZUdyb3Vwc01ldGFkYXRhID0gZmlsZUdyb3Vwc01ldGFkYXRhOworICAgIHRoaXMuZXZlbnRMb2dnZXIgPSBldmVudExvZ2dlcjsKKyAgICB0aGlzLnNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgPSBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworICB9CisKKyAgLy8gVE9ETyhiLzczNDkwNjg5KTogQWxzbyBsb2cgc3RhdHMgYWJvdXQgc3RhbGUgZ3JvdXBzLgorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBsb2coaW50IGRheXNTaW5jZUxhc3RMb2cpIHsKKyAgICByZXR1cm4gZXZlbnRMb2dnZXIubG9nTWRkRmlsZUdyb3VwU3RhdHMoKCkgLT4gYnVpbGRGaWxlR3JvdXBTdGF0dXNMaXN0KGRheXNTaW5jZUxhc3RMb2cpKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxMaXN0PEV2ZW50TG9nZ2VyLkZpbGVHcm91cFN0YXR1c1dpdGhEZXRhaWxzPj4gYnVpbGRGaWxlR3JvdXBTdGF0dXNMaXN0KAorICAgICAgaW50IGRheXNTaW5jZUxhc3RMb2cpIHsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpLAorICAgICAgICBkb3dubG9hZGVkQW5kUGVuZGluZ0dyb3VwcyAtPiB7CisgICAgICAgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPEV2ZW50TG9nZ2VyLkZpbGVHcm91cFN0YXR1c1dpdGhEZXRhaWxzPj4gZnV0dXJlcyA9CisgICAgICAgICAgICAgIG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgICAgIGZvciAoUGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPiBwYWlyIDogZG93bmxvYWRlZEFuZFBlbmRpbmdHcm91cHMpIHsKKyAgICAgICAgICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gcGFpci5maXJzdDsKKyAgICAgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gcGFpci5zZWNvbmQ7CisgICAgICAgICAgICBpZiAoZGF0YUZpbGVHcm91cCA9PSBudWxsKSB7CisgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBWb2lkIGZpbGVHcm91cERldGFpbHMgPSBudWxsOworCisgICAgICAgICAgICBmdXR1cmVzLmFkZCgKKyAgICAgICAgICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgIGJ1aWxkRmlsZUdyb3VwU3RhdHVzKGRhdGFGaWxlR3JvdXAsIGdyb3VwS2V5LCBkYXlzU2luY2VMYXN0TG9nKSwKKyAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwU3RhdHVzIC0+CisgICAgICAgICAgICAgICAgICAgICAgICBFdmVudExvZ2dlci5GaWxlR3JvdXBTdGF0dXNXaXRoRGV0YWlscy5jcmVhdGUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwU3RhdHVzLCBmaWxlR3JvdXBEZXRhaWxzKSwKKyAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gRnV0dXJlcy5hbGxBc0xpc3QoZnV0dXJlcyk7CisgICAgICAgIH0sCisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGJ1aWxkRmlsZUdyb3VwU3RhdHVzKAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAsIEdyb3VwS2V5IGdyb3VwS2V5LCBpbnQgZGF5c1NpbmNlTGFzdExvZykgeworICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL0xvZ1NhbXBsZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9Mb2dTYW1wbGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjEyZGVjNQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9Mb2dTYW1wbGVyLmphdmEKQEAgLTAsMCArMSwxMzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmc7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9ycy5kaXJlY3RFeGVjdXRvcjsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkZsYWdzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRyYWNpbmcuUHJvcGFnYXRlZEZsdWVudEZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DaGVja1JldHVyblZhbHVlOworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CisKKy8qKiBDbGFzcyByZXNwb25zaWJsZSBmb3Igc2FtcGxpbmcgZXZlbnRzLiAqLworQENoZWNrUmV0dXJuVmFsdWUKK3B1YmxpYyBmaW5hbCBjbGFzcyBMb2dTYW1wbGVyIHsKKworICBwcml2YXRlIGZpbmFsIEZsYWdzIGZsYWdzOworICBwcml2YXRlIGZpbmFsIFJhbmRvbSByYW5kb207CisKKyAgLyoqCisgICAqIENvbnN0cnVjdCB0aGUgbG9nIHNhbXBsZXIuCisgICAqCisgICAqIEBwYXJhbSBmbGFncyB1c2VkIHRvIGNoZWNrIHdoZXRoZXIgc3RhYmxlIHNhbXBsaW5nIGlzIGVuYWJsZWQuCisgICAqIEBwYXJhbSByYW5kb20gdXNlZCB0byBnZW5lcmF0ZSByYW5kb20gbnVtYmVycyBmb3IgZXZlbnQgYmFzZWQgc2FtcGxpbmcgb25seS4KKyAgICovCisgIHB1YmxpYyBMb2dTYW1wbGVyKEZsYWdzIGZsYWdzLCBSYW5kb20gcmFuZG9tKSB7CisgICAgdGhpcy5mbGFncyA9IGZsYWdzOworICAgIHRoaXMucmFuZG9tID0gcmFuZG9tOworICB9CisKKyAgLyoqCisgICAqIERldGVybWluZXMgd2hldGhlciB0aGUgZXZlbnQgc2hvdWxkIGJlIGxvZ2dlZC4gSWYgdGhlIGV2ZW50IHNob3VsZCBiZSBsb2dnZWQgaXQgcmV0dXJucyBhbgorICAgKiBpbnN0YW5jZSBvZiBWb2lkIHRoYXQgc2hvdWxkIGJlIGF0dGFjaGVkIHRvIHRoZSBsb2cgZXZlbnRzLgorICAgKgorICAgKiA8cD5JZiBzdGFibGUgc2FtcGxpbmcgaXMgZW5hYmxlZCwgdGhpcyBpcyBkZXRlcm1pbmlzdGljLiBJZiBzdGFibGUgc2FtcGxpbmcgaXMgZGlzYWJsZWQsIHRoZQorICAgKiByZXN1bHQgY2FuIGNoYW5nZSBvbiBlYWNoIGNhbGwgYmFzZWQgb24gdGhlIHByb3ZpZGVkIFJhbmRvbSBpbnN0YW5jZS4KKyAgICoKKyAgICogQHBhcmFtIHNhbXBsZUludGVydmFsIHRoZSBpbnZlcnNlIHNhbXBsaW5nIHJhdGUgdG8gdXNlLiBUaGlzIGlzIGNvbnRyb2xsZWQgYnkgZmxhZ3MgcGVyCisgICAqICAgICBldmVudC10eXBlLiBGb3Igc3RhYmxlIHNhbXBsaW5nIGl0J3MgZXhwZWN0ZWQgdGhhdCAxMDAgJSBzYW1wbGVJbnRlcnZhbCA9PSAwLgorICAgKiBAcGFyYW0gbG9nZ2luZ1N0YXRlU3RvcmUgdXNlZCB0byByZWFkIHBlcnNpc3RlZCByYW5kb20gbnVtYmVyIHdoZW4gc3RhYmxlIHNhbXBsaW5nIGlzIGVuYWJsZWQuCisgICAqICAgICBJZiBpdCBpcyBhYnNlbnQsIHN0YWJsZSBzYW1wbGluZyB3aWxsIG5vdCBiZSB1c2VkLgorICAgKiBAcmV0dXJuIGEgZnV0dXJlIG9mIGFuIG9wdGlvbmFsIG9mIFN0YWJsZVNhbXBsaW5nSW5mby4gVGhlIGZ1dHVyZSB3aWxsIHJlc29sdmUgdG8gYW4gYWJzZW50CisgICAqICAgICBPcHRpb25hbCBpZiB0aGUgZXZlbnQgc2hvdWxkIG5vdCBiZSBsb2dnZWQuIElmIHRoZSBldmVudCBzaG91bGQgYmUgbG9nZ2VkLCB0aGUgcmV0dXJuZWQKKyAgICogICAgIFZvaWQgc2hvdWxkIGJlIGF0dGFjaGVkIHRvIHRoZSBsb2cgZXZlbnQuCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxPcHRpb25hbDxWb2lkPj4gc2hvdWxkTG9nKAorICAgICAgbG9uZyBzYW1wbGVJbnRlcnZhbCwgT3B0aW9uYWw8TG9nZ2luZ1N0YXRlU3RvcmU+IGxvZ2dpbmdTdGF0ZVN0b3JlKSB7CisgICAgaWYgKHNhbXBsZUludGVydmFsID09IDBMKSB7CisgICAgICByZXR1cm4gaW1tZWRpYXRlRnV0dXJlKE9wdGlvbmFsLmFic2VudCgpKTsKKyAgICB9IGVsc2UgaWYgKHNhbXBsZUludGVydmFsIDwgMEwpIHsKKyAgICAgIExvZ1V0aWwuZSgiQmFkIHNhbXBsZSBpbnRlcnZhbCAobmVnYXRpdmUgbnVtYmVyKTogJWQiLCBzYW1wbGVJbnRlcnZhbCk7CisgICAgICByZXR1cm4gaW1tZWRpYXRlRnV0dXJlKE9wdGlvbmFsLmFic2VudCgpKTsKKyAgICB9IGVsc2UgaWYgKGZsYWdzLmVuYWJsZVJuZ0Jhc2VkRGV2aWNlU3RhYmxlU2FtcGxpbmcoKSAmJiBsb2dnaW5nU3RhdGVTdG9yZS5pc1ByZXNlbnQoKSkgeworICAgICAgcmV0dXJuIHNob3VsZExvZ0RldmljZVN0YWJsZShzYW1wbGVJbnRlcnZhbCwgbG9nZ2luZ1N0YXRlU3RvcmUuZ2V0KCkpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gc2hvdWxkTG9nUGVyRXZlbnQoc2FtcGxlSW50ZXJ2YWwpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHN0YW5kYXJkIHJhbmRvbSBldmVudCBiYXNlZCBzYW1wbGluZy4KKyAgICoKKyAgICogQHJldHVybiBpZiB0aGUgZXZlbnQgc2hvdWxkIGJlIHNhbXBsZWQsIHJldHVybnMgdGhlIFZvaWQgd2l0aCBzdGFibGVfc2FtcGxpbmdfdXNlZCA9IGZhbHNlLgorICAgKiAgICAgT3RoZXJ3aXNlLCByZXR1cm5zIGFuIGVtcHR5IE9wdGlvbmFsLgorICAgKi8KKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPE9wdGlvbmFsPFZvaWQ+PiBzaG91bGRMb2dQZXJFdmVudChsb25nIHNhbXBsZUludGVydmFsKSB7CisgICAgaWYgKHNob3VsZFNhbXBsZVBlckV2ZW50KHNhbXBsZUludGVydmFsKSkgeworICAgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShPcHRpb25hbC5hYnNlbnQoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUoT3B0aW9uYWwuYWJzZW50KCkpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgYm9vbGVhbiBzaG91bGRTYW1wbGVQZXJFdmVudChsb25nIHNhbXBsZUludGVydmFsKSB7CisgICAgaWYgKHNhbXBsZUludGVydmFsID09IDBMKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfSBlbHNlIGlmIChzYW1wbGVJbnRlcnZhbCA8IDBMKSB7CisgICAgICBMb2dVdGlsLmUoIkJhZCBzYW1wbGUgaW50ZXJ2YWwgKG5lZ2F0aXZlIG51bWJlcik6ICVkIiwgc2FtcGxlSW50ZXJ2YWwpOworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gaXNQYXJ0T2ZTYW1wbGUocmFuZG9tLm5leHRMb25nKCksIHNhbXBsZUludGVydmFsKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyBkZXZpY2Ugc3RhYmxlIHNhbXBsaW5nLgorICAgKgorICAgKiBAcmV0dXJuIGlmIHRoZSBldmVudCBzaG91bGQgYmUgc2FtcGxlZCwgcmV0dXJucyB0aGUgVm9pZCB3aXRoIHN0YWJsZV9zYW1wbGluZ191c2VkID0gdHJ1ZSBhbmQKKyAgICogICAgIGFsbCBvdGhlciBmaWVsZHMgcG9wdWxhdGVkLiBPdGhlcndpc2UsIHJldHVybnMgYW4gZW1wdHkgT3B0aW9uYWwuCisgICAqLworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8T3B0aW9uYWw8Vm9pZD4+IHNob3VsZExvZ0RldmljZVN0YWJsZSgKKyAgICAgIGxvbmcgc2FtcGxlSW50ZXJ2YWwsIExvZ2dpbmdTdGF0ZVN0b3JlIGxvZ2dpbmdTdGF0ZVN0b3JlKSB7CisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmUuZnJvbShsb2dnaW5nU3RhdGVTdG9yZS5nZXRTdGFibGVTYW1wbGluZ0luZm8oKSkKKyAgICAgICAgLnRyYW5zZm9ybSgKKyAgICAgICAgICAgIHNhbXBsaW5nSW5mbyAtPiB7CisgICAgICAgICAgICAgIGJvb2xlYW4gaW52YWxpZFNhbXBsaW5nUmF0ZVVzZWQgPSAoKDEwMCAlIHNhbXBsZUludGVydmFsKSAhPSAwKTsKKyAgICAgICAgICAgICAgaWYgKGludmFsaWRTYW1wbGluZ1JhdGVVc2VkKSB7CisgICAgICAgICAgICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICAgICAgICAgICAiQmFkIHNhbXBsZSBpbnRlcnZhbCAoMSBwZXJjZW50IGNvaG9ydCB3aWxsIG5vdCBsb2cpOiAlZCIsIHNhbXBsZUludGVydmFsKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIGlmICghaXNQYXJ0T2ZTYW1wbGUoc2FtcGxpbmdJbmZvLmdldFN0YWJsZUxvZ1NhbXBsaW5nU2FsdCgpLCBzYW1wbGVJbnRlcnZhbCkpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gT3B0aW9uYWwuYWJzZW50KCk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICByZXR1cm4gT3B0aW9uYWwuYWJzZW50KCk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgZGlyZWN0RXhlY3V0b3IoKSk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB3aGV0aGVyIHRoaXMgZGV2aWNlIGlzIHBhcnQgb2YgdGhlIHNhbXBsZSB3aXRoIHRoZSBnaXZlbiBzYW1wbGluZyByYXRlIGFuZCByYW5kb20KKyAgICogbnVtYmVyLgorICAgKi8KKyAgcHJpdmF0ZSBib29sZWFuIGlzUGFydE9mU2FtcGxlKGxvbmcgcmFuZG9tTnVtYmVyLCBsb25nIHNhbXBsZUludGVydmFsKSB7CisgICAgcmV0dXJuIHJhbmRvbU51bWJlciAlIHNhbXBsZUludGVydmFsID09IDA7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9Mb2dVdGlsLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvTG9nVXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJiYTdhYjMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvTG9nVXRpbC5qYXZhCkBAIC0wLDAgKzEsMjc2IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nOworCitpbXBvcnQgYW5kcm9pZC5hbm5vdGF0aW9uLlN1cHByZXNzTGludDsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DYW5JZ25vcmVSZXR1cm5WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmVycm9ycHJvbmUuYW5ub3RhdGlvbnMuRm9ybWF0TWV0aG9kOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5Gb3JtYXRTdHJpbmc7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuUmFuZG9tOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKiBVdGlsaXR5IGNsYXNzIGZvciBsb2dnaW5nIHdpdGggdGhlICJNREQiIHRhZy4gKi8KK0BDYW5JZ25vcmVSZXR1cm5WYWx1ZQorcHVibGljIGNsYXNzIExvZ1V0aWwgeworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiTUREIjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBSYW5kb20gcmFuZG9tID0gbmV3IFJhbmRvbSgpOworCisgIHB1YmxpYyBzdGF0aWMgaW50IGdldExvZ1ByaW9yaXR5KCkgeworICAgIGludCBsZXZlbCA9IExvZy5BU1NFUlQ7CisgICAgd2hpbGUgKGxldmVsID4gTG9nLlZFUkJPU0UpIHsKKyAgICAgIGlmICghTG9nLmlzTG9nZ2FibGUoVEFHLCBsZXZlbCAtIDEpKSB7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgbGV2ZWwtLTsKKyAgICB9CisgICAgcmV0dXJuIGxldmVsOworICB9CisKKyAgcHVibGljIHN0YXRpYyBpbnQgdihTdHJpbmcgbXNnKSB7CisgICAgaWYgKExvZy5pc0xvZ2dhYmxlKFRBRywgTG9nLlZFUkJPU0UpKSB7CisgICAgICByZXR1cm4gTG9nLnYoVEFHLCBtc2cpOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIEBGb3JtYXRNZXRob2QKKyAgcHVibGljIHN0YXRpYyBpbnQgdihARm9ybWF0U3RyaW5nIFN0cmluZyBmb3JtYXQsIE9iamVjdCBvYmowKSB7CisgICAgaWYgKExvZy5pc0xvZ2dhYmxlKFRBRywgTG9nLlZFUkJPU0UpKSB7CisgICAgICBTdHJpbmcgbXNnID0gZm9ybWF0KGZvcm1hdCwgb2JqMCk7CisgICAgICByZXR1cm4gTG9nLnYoVEFHLCBtc2cpOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIEBGb3JtYXRNZXRob2QKKyAgcHVibGljIHN0YXRpYyBpbnQgdihARm9ybWF0U3RyaW5nIFN0cmluZyBmb3JtYXQsIE9iamVjdCBvYmowLCBPYmplY3Qgb2JqMSkgeworICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5WRVJCT1NFKSkgeworICAgICAgU3RyaW5nIG1zZyA9IGZvcm1hdChmb3JtYXQsIG9iajAsIG9iajEpOworICAgICAgcmV0dXJuIExvZy52KFRBRywgbXNnKTsKKyAgICB9CisgICAgcmV0dXJuIDA7CisgIH0KKworICBARm9ybWF0TWV0aG9kCisgIHB1YmxpYyBzdGF0aWMgaW50IHYoQEZvcm1hdFN0cmluZyBTdHJpbmcgZm9ybWF0LCBPYmplY3QuLi4gcGFyYW1zKSB7CisgICAgaWYgKExvZy5pc0xvZ2dhYmxlKFRBRywgTG9nLlZFUkJPU0UpKSB7CisgICAgICBTdHJpbmcgbXNnID0gZm9ybWF0KGZvcm1hdCwgcGFyYW1zKTsKKyAgICAgIHJldHVybiBMb2cudihUQUcsIG1zZyk7CisgICAgfQorICAgIHJldHVybiAwOworICB9CisKKyAgcHVibGljIHN0YXRpYyBpbnQgZChTdHJpbmcgbXNnKSB7CisgICAgaWYgKExvZy5pc0xvZ2dhYmxlKFRBRywgTG9nLkRFQlVHKSkgeworICAgICAgcmV0dXJuIExvZy5kKFRBRywgbXNnKTsKKyAgICB9CisgICAgcmV0dXJuIDA7CisgIH0KKworICBARm9ybWF0TWV0aG9kCisgIHB1YmxpYyBzdGF0aWMgaW50IGQoQEZvcm1hdFN0cmluZyBTdHJpbmcgZm9ybWF0LCBPYmplY3Qgb2JqMCkgeworICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5ERUJVRykpIHsKKyAgICAgIFN0cmluZyBtc2cgPSBmb3JtYXQoZm9ybWF0LCBvYmowKTsKKyAgICAgIHJldHVybiBMb2cuZChUQUcsIG1zZyk7CisgICAgfQorICAgIHJldHVybiAwOworICB9CisKKyAgQEZvcm1hdE1ldGhvZAorICBwdWJsaWMgc3RhdGljIGludCBkKEBGb3JtYXRTdHJpbmcgU3RyaW5nIGZvcm1hdCwgT2JqZWN0IG9iajAsIE9iamVjdCBvYmoxKSB7CisgICAgaWYgKExvZy5pc0xvZ2dhYmxlKFRBRywgTG9nLkRFQlVHKSkgeworICAgICAgU3RyaW5nIG1zZyA9IGZvcm1hdChmb3JtYXQsIG9iajAsIG9iajEpOworICAgICAgcmV0dXJuIExvZy5kKFRBRywgbXNnKTsKKyAgICB9CisgICAgcmV0dXJuIDA7CisgIH0KKworICBARm9ybWF0TWV0aG9kCisgIHB1YmxpYyBzdGF0aWMgaW50IGQoQEZvcm1hdFN0cmluZyBTdHJpbmcgZm9ybWF0LCBPYmplY3QuLi4gcGFyYW1zKSB7CisgICAgaWYgKExvZy5pc0xvZ2dhYmxlKFRBRywgTG9nLkRFQlVHKSkgeworICAgICAgU3RyaW5nIG1zZyA9IGZvcm1hdChmb3JtYXQsIHBhcmFtcyk7CisgICAgICByZXR1cm4gTG9nLmQoVEFHLCBtc2cpOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIEBGb3JtYXRNZXRob2QKKyAgcHVibGljIHN0YXRpYyBpbnQgZChATnVsbGFibGUgVGhyb3dhYmxlIHRyLCBARm9ybWF0U3RyaW5nIFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBwYXJhbXMpIHsKKyAgICBpZiAoTG9nLmlzTG9nZ2FibGUoVEFHLCBMb2cuREVCVUcpKSB7CisgICAgICBTdHJpbmcgbXNnID0gZm9ybWF0KGZvcm1hdCwgcGFyYW1zKTsKKyAgICAgIHJldHVybiBMb2cuZChUQUcsIG1zZywgdHIpOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgaW50IGkoU3RyaW5nIG1zZykgeworICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5JTkZPKSkgeworICAgICAgcmV0dXJuIExvZy5pKFRBRywgbXNnKTsKKyAgICB9CisgICAgcmV0dXJuIDA7CisgIH0KKworICBARm9ybWF0TWV0aG9kCisgIHB1YmxpYyBzdGF0aWMgaW50IGkoQEZvcm1hdFN0cmluZyBTdHJpbmcgZm9ybWF0LCBPYmplY3Qgb2JqMCkgeworICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5JTkZPKSkgeworICAgICAgU3RyaW5nIG1zZyA9IGZvcm1hdChmb3JtYXQsIG9iajApOworICAgICAgcmV0dXJuIExvZy5pKFRBRywgbXNnKTsKKyAgICB9CisgICAgcmV0dXJuIDA7CisgIH0KKworICBARm9ybWF0TWV0aG9kCisgIHB1YmxpYyBzdGF0aWMgaW50IGkoQEZvcm1hdFN0cmluZyBTdHJpbmcgZm9ybWF0LCBPYmplY3Qgb2JqMCwgT2JqZWN0IG9iajEpIHsKKyAgICBpZiAoTG9nLmlzTG9nZ2FibGUoVEFHLCBMb2cuSU5GTykpIHsKKyAgICAgIFN0cmluZyBtc2cgPSBmb3JtYXQoZm9ybWF0LCBvYmowLCBvYmoxKTsKKyAgICAgIHJldHVybiBMb2cuaShUQUcsIG1zZyk7CisgICAgfQorICAgIHJldHVybiAwOworICB9CisKKyAgQEZvcm1hdE1ldGhvZAorICBwdWJsaWMgc3RhdGljIGludCBpKEBGb3JtYXRTdHJpbmcgU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIHBhcmFtcykgeworICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5JTkZPKSkgeworICAgICAgU3RyaW5nIG1zZyA9IGZvcm1hdChmb3JtYXQsIHBhcmFtcyk7CisgICAgICByZXR1cm4gTG9nLmkoVEFHLCBtc2cpOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgaW50IGUoU3RyaW5nIG1zZykgeworICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5FUlJPUikpIHsKKyAgICAgIHJldHVybiBMb2cuZShUQUcsIG1zZyk7CisgICAgfQorICAgIHJldHVybiAwOworICB9CisKKyAgQEZvcm1hdE1ldGhvZAorICBwdWJsaWMgc3RhdGljIGludCBlKEBGb3JtYXRTdHJpbmcgU3RyaW5nIGZvcm1hdCwgT2JqZWN0IG9iajApIHsKKyAgICBpZiAoTG9nLmlzTG9nZ2FibGUoVEFHLCBMb2cuRVJST1IpKSB7CisgICAgICBTdHJpbmcgbXNnID0gZm9ybWF0KGZvcm1hdCwgb2JqMCk7CisgICAgICByZXR1cm4gTG9nLmUoVEFHLCBtc2cpOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIEBGb3JtYXRNZXRob2QKKyAgcHVibGljIHN0YXRpYyBpbnQgZShARm9ybWF0U3RyaW5nIFN0cmluZyBmb3JtYXQsIE9iamVjdCBvYmowLCBPYmplY3Qgb2JqMSkgeworICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5FUlJPUikpIHsKKyAgICAgIFN0cmluZyBtc2cgPSBmb3JtYXQoZm9ybWF0LCBvYmowLCBvYmoxKTsKKyAgICAgIHJldHVybiBMb2cuZShUQUcsIG1zZyk7CisgICAgfQorICAgIHJldHVybiAwOworICB9CisKKyAgQEZvcm1hdE1ldGhvZAorICBwdWJsaWMgc3RhdGljIGludCBlKEBGb3JtYXRTdHJpbmcgU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIHBhcmFtcykgeworICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5FUlJPUikpIHsKKyAgICAgIFN0cmluZyBtc2cgPSBmb3JtYXQoZm9ybWF0LCBwYXJhbXMpOworICAgICAgcmV0dXJuIExvZy5lKFRBRywgbXNnKTsKKyAgICB9CisgICAgcmV0dXJuIDA7CisgIH0KKworICBAU3VwcHJlc3NMaW50KCJMb2dUYWdNaXNtYXRjaCIpCisgIHB1YmxpYyBzdGF0aWMgaW50IGUoQE51bGxhYmxlIFRocm93YWJsZSB0ciwgU3RyaW5nIG1zZykgeworICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5FUlJPUikpIHsKKyAgICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5ERUJVRykpIHsKKyAgICAgICAgcmV0dXJuIExvZy5lKFRBRywgbXNnLCB0cik7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBJZiBub3QgREVCVUcgbGV2ZWwsIG9ubHkgcHJpbnQgdGhlIHRocm93YWJsZSB0eXBlIGFuZCBtZXNzYWdlLgorICAgICAgICBtc2cgPSBtc2cgKyAiOiAiICsgdHI7CisgICAgICAgIHJldHVybiBMb2cuZShUQUcsIG1zZyk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiAwOworICB9CisKKyAgQEZvcm1hdE1ldGhvZAorICBwdWJsaWMgc3RhdGljIGludCBlKEBOdWxsYWJsZSBUaHJvd2FibGUgdHIsIEBGb3JtYXRTdHJpbmcgU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIHBhcmFtcykgeworICAgIHJldHVybiBMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5FUlJPUikgPyBlKHRyLCBmb3JtYXQoZm9ybWF0LCBwYXJhbXMpKSA6IDA7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGludCB3KFN0cmluZyBtc2cpIHsKKyAgICBpZiAoTG9nLmlzTG9nZ2FibGUoVEFHLCBMb2cuV0FSTikpIHsKKyAgICAgIHJldHVybiBMb2cudyhUQUcsIG1zZyk7CisgICAgfQorICAgIHJldHVybiAwOworICB9CisKKyAgQEZvcm1hdE1ldGhvZAorICBwdWJsaWMgc3RhdGljIGludCB3KEBGb3JtYXRTdHJpbmcgU3RyaW5nIGZvcm1hdCwgT2JqZWN0IG9iajApIHsKKyAgICBpZiAoTG9nLmlzTG9nZ2FibGUoVEFHLCBMb2cuV0FSTikpIHsKKyAgICAgIFN0cmluZyBtc2cgPSBmb3JtYXQoZm9ybWF0LCBvYmowKTsKKyAgICAgIHJldHVybiBMb2cudyhUQUcsIG1zZyk7CisgICAgfQorICAgIHJldHVybiAwOworICB9CisKKyAgQEZvcm1hdE1ldGhvZAorICBwdWJsaWMgc3RhdGljIGludCB3KEBGb3JtYXRTdHJpbmcgU3RyaW5nIGZvcm1hdCwgT2JqZWN0IG9iajAsIE9iamVjdCBvYmoxKSB7CisgICAgaWYgKExvZy5pc0xvZ2dhYmxlKFRBRywgTG9nLldBUk4pKSB7CisgICAgICBTdHJpbmcgbXNnID0gZm9ybWF0KGZvcm1hdCwgb2JqMCwgb2JqMSk7CisgICAgICByZXR1cm4gTG9nLncoVEFHLCBtc2cpOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIEBGb3JtYXRNZXRob2QKKyAgcHVibGljIHN0YXRpYyBpbnQgdyhARm9ybWF0U3RyaW5nIFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBwYXJhbXMpIHsKKyAgICBpZiAoTG9nLmlzTG9nZ2FibGUoVEFHLCBMb2cuV0FSTikpIHsKKyAgICAgIFN0cmluZyBtc2cgPSBmb3JtYXQoZm9ybWF0LCBwYXJhbXMpOworICAgICAgcmV0dXJuIExvZy53KFRBRywgbXNnKTsKKyAgICB9CisgICAgcmV0dXJuIDA7CisgIH0KKworICBAU3VwcHJlc3NMaW50KCJMb2dUYWdNaXNtYXRjaCIpCisgIEBGb3JtYXRNZXRob2QKKyAgcHVibGljIHN0YXRpYyBpbnQgdyhATnVsbGFibGUgVGhyb3dhYmxlIHRyLCBARm9ybWF0U3RyaW5nIFN0cmluZyBmb3JtYXQsIE9iamVjdC4uLiBwYXJhbXMpIHsKKyAgICBpZiAoTG9nLmlzTG9nZ2FibGUoVEFHLCBMb2cuV0FSTikpIHsKKyAgICAgIGlmIChMb2cuaXNMb2dnYWJsZShUQUcsIExvZy5ERUJVRykpIHsKKyAgICAgICAgU3RyaW5nIG1zZyA9IGZvcm1hdChmb3JtYXQsIHBhcmFtcyk7CisgICAgICAgIHJldHVybiBMb2cudyhUQUcsIG1zZywgdHIpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgLy8gSWYgbm90IERFQlVHIGxldmVsLCBvbmx5IHByaW50IHRoZSB0aHJvd2FibGUgdHlwZSBhbmQgbWVzc2FnZS4KKyAgICAgICAgU3RyaW5nIG1zZyA9IGZvcm1hdChmb3JtYXQsIHBhcmFtcykgKyAiOiAiICsgdHI7CisgICAgICAgIHJldHVybiBMb2cudyhUQUcsIG1zZyk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiAwOworICB9CisKKyAgQEZvcm1hdE1ldGhvZAorICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZm9ybWF0KEBGb3JtYXRTdHJpbmcgU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIGFyZ3MpIHsKKyAgICByZXR1cm4gU3RyaW5nLmZvcm1hdChMb2NhbGUuVVMsIGZvcm1hdCwgYXJncyk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gc2hvdWxkU2FtcGxlSW50ZXJ2YWwobG9uZyBzYW1wbGVJbnRlcnZhbCkgeworICAgIGlmIChzYW1wbGVJbnRlcnZhbCA8PSAwTCkgeworICAgICAgaWYgKHNhbXBsZUludGVydmFsIDwgMEwpIHsKKyAgICAgICAgTG9nVXRpbC5lKCJCYWQgc2FtcGxlIGludGVydmFsOiAlZCIsIHNhbXBsZUludGVydmFsKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIChyYW5kb20ubmV4dExvbmcoKSAlIHNhbXBsZUludGVydmFsKSA9PSAwOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgTG9nVXRpbCgpIHt9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvTG9nZ2luZ1N0YXRlU3RvcmUuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9Mb2dnaW5nU3RhdGVTdG9yZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFjODMxOGYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvTG9nZ2luZ1N0YXRlU3RvcmUuamF2YQpAQCAtMCwwICsxLDYyIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nOworCitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkZpbGVHcm91cExvZ2dpbmdTdGF0ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLlNhbXBsaW5nSW5mbzsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqIEludGVyZmFjZSBmb3Iga2VlcGluZyB0cmFjayBvZiBzdGF0ZSBuZWNlc3NhcnkgZm9yIGFjY3VyYXRlIGxvZ2dpbmcuICovCitwdWJsaWMgaW50ZXJmYWNlIExvZ2dpbmdTdGF0ZVN0b3JlIHsKKworICAvKioKKyAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGRheXMgc2luY2UgbWFpbnRlbmFuY2Ugd2FzIGxhc3QgcnVuIGFuZCB1cGRhdGVzIHRoZSB0aW1lc3RhbXAgZm9yIGZ1dHVyZQorICAgKiBjYWxscy4KKyAgICoKKyAgICogQHJldHVybiBhIGZ1dHVyZSByZXByZXNlbnRpbmcgdGhlIG51bWJlciBvZiBkYXlzIHNpbmNlIG1haW50ZW5hbmNlIHdhcyBsYXN0IHJ1bi4gSWYgdGhpcyBtZXRob2QKKyAgICogICAgIGhhc24ndCBzdWNjZWVkZWQgYmVmb3JlLCB0aGUgZnV0dXJlIHdpbGwgY29tcGxldGUgd2l0aCBhbiBhYnNlbnQgT3B0aW9uYWwuIFRoZSBmdXR1cmUgbWF5CisgICAqICAgICBjb21wbGV0ZSB3aXRoIChpbnZhbGlkKSBuZWdhdGl2ZSB2YWx1ZXMuIEZ1dHVyZSB3aWxsIGZhaWwgd2l0aCBJT0V4Y2VwdGlvbiBpZiB0aGVyZSB3YXMgYW4KKyAgICogICAgIGlzc3VlIHJlYWRpbmcgb3IgdXBkYXRpbmcgdGhlIHZhbHVlLgorICAgKi8KKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8T3B0aW9uYWw8SW50ZWdlcj4+IGdldEFuZFJlc2V0RGF5c1NpbmNlTGFzdE1haW50ZW5hbmNlKCk7CisKKyAgLyoqCisgICAqIEluY3JlbWVudCB0aGUgZGF0YSB1c2FnZSBzdGF0cyBmb3IgdGhlIGZpbGUgZ3JvdXAuIElmIHRoZXJlIGV4aXN0cyBhbiBlbnRyeSB3aGljaCBtYXRjaGVzIHRoZQorICAgKiBHcm91cEtleSwgdmVyc2lvbiBudW1iZXIgYW5kIGJ1aWxkIGlkLCB0aGVuIHRoZSBkYXRhIHVzYWdlIGZyb20gZGF0YVVzYWdlSW5jcmVtZW50cyB3aWxsIGJlCisgICAqIGFkZGVkIHRvIHRoYXQsIG90aGVyd2lzZSBhIG5ldyBlbnRyeSB3aWxsIGJlIGNyZWF0ZWQuCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBpbmNyZW1lbnREYXRhVXNhZ2UoRmlsZUdyb3VwTG9nZ2luZ1N0YXRlIGRhdGFVc2FnZUluY3JlbWVudHMpOworCisgIC8qKgorICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgdGhlIGRhdGEgdXNhZ2UgaW5jcmVtZW50cyBncm91cGVkIGJ5IEdyb3VwS2V5LCBidWlsZCBpZCBhbmQgdmVyc2lvbgorICAgKiBudW1iZXIuCisgICAqLworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxMaXN0PEZpbGVHcm91cExvZ2dpbmdTdGF0ZT4+IGdldEFuZFJlc2V0QWxsRGF0YVVzYWdlKCk7CisKKyAgLyoqIFJlc2V0cyBhbGwgTG9nZ2luZ1N0YXRlU3RvcmUgc3RhdGUuICovCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNsZWFyKCk7CisKKyAgLyoqCisgICAqIEdldHMgaW5mbyBuZWNlc3NhcnkgZm9yIHN0YWJsZSBzYW1wbGluZy4gQ2FsbGVycyBhcmUgcmVzcG9uc2libGUgZm9yIGVuc3VyaW5nIHRoYXQgc3RhYmxlCisgICAqIHNhbXBsaW5nIGlzIGVuYWJsZWQuCisgICAqCisgICAqIDxwPklmIHRoZSBzdGFibGUgc2FtcGxpbmcgcmFuZG9tIG51bWJlciBoYXNuJ3QgYmVlbiBwZXJzaXN0ZWQgeWV0LCB0aGlzIHdpbGwgcG9wdWxhdGUgaXQgYmVmb3JlCisgICAqIHJldHVybmluZy4KKyAgICovCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFNhbXBsaW5nSW5mbz4gZ2V0U3RhYmxlU2FtcGxpbmdJbmZvKCk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvTWRkRXZlbnRMb2dnZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9NZGRFdmVudExvZ2dlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyYjQ5ODQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvTWRkRXZlbnRMb2dnZXIuamF2YQpAQCAtMCwwICsxLDI3NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZzsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9ycy5kaXJlY3RFeGVjdXRvcjsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5JbnRlbnQ7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkludGVudEZpbHRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GbGFnczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Mb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5Qcm9wYWdhdGVkRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Bc3luY0NhbGxhYmxlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GbHVlbnRGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZUNhbGxiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqIEFzc2VtYmxlcyBkYXRhIGFuZCBsb2dzIHRoZW0gd2l0aCB1bmRlcmx5aW5nIHtAbGluayBMb2dnZXJ9LiAqLworcHVibGljIGZpbmFsIGNsYXNzIE1kZEV2ZW50TG9nZ2VyIGltcGxlbWVudHMgRXZlbnRMb2dnZXIgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiTWRkRXZlbnRMb2dnZXIiOworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIGZpbmFsIExvZ2dlciBsb2dnZXI7CisgIC8vIEEgcHJvY2VzcyB0aGF0IGhhcyBtZGkgZG93bmxvYWQgbW9kdWxlIGxvYWRlZCB3aWxsIGdldCByZXN0YXJ0ZWQgaWYgYSBuZXcgbW9kdWxlIHZlcnNpb24gaXMKKyAgLy8gaW5zdGFsbGVkLgorICBwcml2YXRlIGZpbmFsIGludCBtb2R1bGVWZXJzaW9uOworICBwcml2YXRlIGZpbmFsIFN0cmluZyBob3N0UGFja2FnZU5hbWU7CisgIHByaXZhdGUgZmluYWwgRmxhZ3MgZmxhZ3M7CisgIHByaXZhdGUgZmluYWwgTG9nU2FtcGxlciBsb2dTYW1wbGVyOworCisgIHByaXZhdGUgT3B0aW9uYWw8TG9nZ2luZ1N0YXRlU3RvcmU+IGxvZ2dpbmdTdGF0ZVN0b3JlID0gT3B0aW9uYWwuYWJzZW50KCk7CisKKyAgcHVibGljIE1kZEV2ZW50TG9nZ2VyKAorICAgICAgQ29udGV4dCBjb250ZXh0LCBMb2dnZXIgbG9nZ2VyLCBpbnQgbW9kdWxlVmVyc2lvbiwgTG9nU2FtcGxlciBsb2dTYW1wbGVyLCBGbGFncyBmbGFncykgeworICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CisgICAgdGhpcy5sb2dnZXIgPSBsb2dnZXI7CisgICAgdGhpcy5tb2R1bGVWZXJzaW9uID0gbW9kdWxlVmVyc2lvbjsKKyAgICB0aGlzLmhvc3RQYWNrYWdlTmFtZSA9IGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKTsKKyAgICB0aGlzLmxvZ1NhbXBsZXIgPSBsb2dTYW1wbGVyOworICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKKyAgfQorCisgIC8qKgorICAgKiBUaGlzIHNob3VsZCBiZSBjYWxsZWQgYmVmb3JlIE1kZEV2ZW50TG9nZ2VyIGlzIHVzZWQuIElmIGl0IGlzIG5vdCBjYWxsZWQgYmVmb3JlIE1kZEV2ZW50TG9nZ2VyCisgICAqIGlzIHVzZWQsIHN0YWJsZSBzYW1wbGluZyB3aWxsIG5vdCBiZSB1c2VkLgorICAgKgorICAgKiA8cD5Ob3RlKHJvaGl0c2F0KTogdGhpcyBpcyByZXF1aXJlZCBiZWNhdXNlIExvZ2dpbmdTdGF0ZVN0b3JlIGlzIGNvbnN0cnVjdGVkIHdpdGggYSBQRFMgaW4gdGhlCisgICAqIE1haW5NZGRMaWJNb2R1bGUuIE1kZEV2ZW50TG9nZ2VyIGlzIHJlcXVpcmVkIHRvIGNvbnN0cnVjdCB0aGUgTWFpbk1kZExpYk1vZHVsZS4KKyAgICoKKyAgICogQHBhcmFtIGxvZ2dpbmdTdGF0ZVN0b3JlIHRoZSBMb2dnaW5nU3RhdGVTdG9yZSB0aGF0IGNvbnRhaW5zIHRoZSBwZXJzaXN0ZWQgcmFuZG9tIG51bWJlciBmb3IKKyAgICogICAgIHN0YWJsZSBzYW1wbGluZy4KKyAgICovCisgIHB1YmxpYyB2b2lkIHNldExvZ2dpbmdTdGF0ZVN0b3JlKExvZ2dpbmdTdGF0ZVN0b3JlIGxvZ2dpbmdTdGF0ZVN0b3JlKSB7CisgICAgdGhpcy5sb2dnaW5nU3RhdGVTdG9yZSA9IE9wdGlvbmFsLm9mKGxvZ2dpbmdTdGF0ZVN0b3JlKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dFdmVudFNhbXBsZWQoaW50IGV2ZW50Q29kZSkge30KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nRXZlbnRTYW1wbGVkKAorICAgICAgaW50IGV2ZW50Q29kZSwKKyAgICAgIFN0cmluZyBmaWxlR3JvdXBOYW1lLAorICAgICAgaW50IGZpbGVHcm91cFZlcnNpb25OdW1iZXIsCisgICAgICBsb25nIGJ1aWxkSWQsCisgICAgICBTdHJpbmcgdmFyaWFudElkKSB7CisKKyAgICBWb2lkIGRhdGFEb3dubG9hZEZpbGVHcm91cFN0YXRzID0gbnVsbDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dFdmVudEFmdGVyU2FtcGxlKGludCBldmVudENvZGUsIGludCBzYW1wbGVJbnRlcnZhbCkgeworICAgIC8vIFRPRE8oYi8xMzgzOTI2NDApOiBkZWxldGUgdGhpcyBtZXRob2Qgb25jZSB0aGUgcGRzIG1pZ3JhdGlvbiBpcyBjb21wbGV0ZS4gSWYgaXQncyBuZWNlc3NhcnkKKyAgICAvLyBmb3Igb3RoZXIgdXNlIGNhc2VzLCB3ZSBjYW4gZXN0YWJsaXNoIGEgcGF0dGVybiB3aGVyZSB0aGlzIGNsYXNzIGlzIHN0aWxsIHJlc3BvbnNpYmxlIGZvcgorICAgIC8vIHNhbXBsaW5nLgorICAgIFZvaWQgbG9nRGF0YSA9IG51bGw7CisgICAgcHJvY2Vzc0FuZFNlbmRFdmVudFdpdGhvdXRTdGFibGVTYW1wbGluZyhldmVudENvZGUsIGxvZ0RhdGEsIHNhbXBsZUludGVydmFsKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dNZGRBcGlDYWxsU3RhdHMoVm9pZCBmaWxlR3JvdXBEZXRhaWxzLCBWb2lkIGFwaUNhbGxTdGF0cykgeworICAgIC8vIFRPRE8oYi8xNDQ2ODQ3NjMpOiB1cGRhdGUgdGhpcyB0byB1c2Ugc3RhYmxlIHNhbXBsaW5nLiBMZWF2aW5nIGl0IGFzIGlzIGZvciBub3cgc2luY2UgaXQgaXMKKyAgICAvLyBmYWlybHkgaGlnaCB2b2x1bWUuCisgICAgbG9uZyBzYW1wbGVJbnRlcnZhbCA9IGZsYWdzLmFwaUxvZ2dpbmdTYW1wbGVJbnRlcnZhbCgpOworICAgIGlmICghTG9nVXRpbC5zaG91bGRTYW1wbGVJbnRlcnZhbChzYW1wbGVJbnRlcnZhbCkpIHsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgVm9pZCBsb2dEYXRhID0gbnVsbDsKKyAgICBwcm9jZXNzQW5kU2VuZEV2ZW50V2l0aG91dFN0YWJsZVNhbXBsaW5nKDAsIGxvZ0RhdGEsIHNhbXBsZUludGVydmFsKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBsb2dNZGRGaWxlR3JvdXBTdGF0cygKKyAgICAgIEFzeW5jQ2FsbGFibGU8TGlzdDxFdmVudExvZ2dlci5GaWxlR3JvdXBTdGF0dXNXaXRoRGV0YWlscz4+IGJ1aWxkRmlsZUdyb3VwU3RhdHMpIHsKKyAgICByZXR1cm4gbGF6eVNhbXBsZUFuZFNlbmRMb2dFdmVudCgKKyAgICAgICAgMCwKKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICBidWlsZEZpbGVHcm91cFN0YXRzLmNhbGwoKSwKKyAgICAgICAgICAgICAgICBmaWxlR3JvdXBTdGF0dXNBbmREZXRhaWxzTGlzdCAtPiB7CisgICAgICAgICAgICAgICAgICBMaXN0PFZvaWQ+IGFsbEljaW5nTG9nRGF0YSA9IG5ldyBBcnJheUxpc3Q8PigpOworCisgICAgICAgICAgICAgICAgICBmb3IgKEZpbGVHcm91cFN0YXR1c1dpdGhEZXRhaWxzIGZpbGVHcm91cFN0YXR1c0FuZERldGFpbHMgOgorICAgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cFN0YXR1c0FuZERldGFpbHNMaXN0KSB7CisgICAgICAgICAgICAgICAgICAgIGFsbEljaW5nTG9nRGF0YS5hZGQobnVsbCk7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICByZXR1cm4gYWxsSWNpbmdMb2dEYXRhOworICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgZGlyZWN0RXhlY3V0b3IoKSksCisgICAgICAgIGZsYWdzLmdyb3VwU3RhdHNMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gbG9nTWRkU3RvcmFnZVN0YXRzKEFzeW5jQ2FsbGFibGU8Vm9pZD4gYnVpbGRTdG9yYWdlU3RhdHMpIHsKKyAgICByZXR1cm4gbGF6eVNhbXBsZUFuZFNlbmRMb2dFdmVudCgKKyAgICAgICAgMCwKKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICBidWlsZFN0b3JhZ2VTdGF0cy5jYWxsKCksIHN0b3JhZ2VTdGF0cyAtPiBBcnJheXMuYXNMaXN0KCksIGRpcmVjdEV4ZWN1dG9yKCkpLAorICAgICAgICBmbGFncy5zdG9yYWdlU3RhdHNMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gbG9nTWRkTmV0d29ya1N0YXRzKEFzeW5jQ2FsbGFibGU8Vm9pZD4gYnVpbGROZXR3b3JrU3RhdHMpIHsKKyAgICByZXR1cm4gbGF6eVNhbXBsZUFuZFNlbmRMb2dFdmVudCgKKyAgICAgICAgMCwKKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICBidWlsZE5ldHdvcmtTdGF0cy5jYWxsKCksIG5ldHdvcmtTdGF0cyAtPiBBcnJheXMuYXNMaXN0KCksIGRpcmVjdEV4ZWN1dG9yKCkpLAorICAgICAgICBmbGFncy5uZXR3b3JrU3RhdHNMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nTWRkRGF0YURvd25sb2FkRmlsZUV4cGlyYXRpb25FdmVudChpbnQgZXZlbnRDb2RlLCBpbnQgY291bnQpIHsKKyAgICBWb2lkIGxvZ0RhdGEgPSBudWxsOworICAgIHNhbXBsZUFuZFNlbmRMb2dFdmVudCgwLCBsb2dEYXRhLCBmbGFncy5tZGREZWZhdWx0U2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nTWRkTmV0d29ya1NhdmluZ3MoCisgICAgICBWb2lkIGZpbGVHcm91cERldGFpbHMsCisgICAgICBpbnQgY29kZSwKKyAgICAgIGxvbmcgZnVsbEZpbGVTaXplLAorICAgICAgbG9uZyBkb3dubG9hZGVkRmlsZVNpemUsCisgICAgICBTdHJpbmcgZmlsZUlkLAorICAgICAgaW50IGRlbHRhSW5kZXgpIHsKKyAgICBWb2lkIGxvZ0RhdGEgPSBudWxsOworCisgICAgc2FtcGxlQW5kU2VuZExvZ0V2ZW50KDAsIGxvZ0RhdGEsIGZsYWdzLm1kZERlZmF1bHRTYW1wbGVJbnRlcnZhbCgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dNZGRRdWVyeVN0YXRzKFZvaWQgZmlsZUdyb3VwRGV0YWlscykgeworICAgIFZvaWQgbG9nRGF0YSA9IG51bGw7CisKKyAgICBzYW1wbGVBbmRTZW5kTG9nRXZlbnQoMCwgbG9nRGF0YSwgZmxhZ3MubWRkRGVmYXVsdFNhbXBsZUludGVydmFsKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGxvZ01kZERvd25sb2FkTGF0ZW5jeShWb2lkIGZpbGVHcm91cERldGFpbHMsIFZvaWQgZG93bmxvYWRMYXRlbmN5KSB7CisgICAgVm9pZCBsb2dEYXRhID0gbnVsbDsKKworICAgIHNhbXBsZUFuZFNlbmRMb2dFdmVudCgwLCBsb2dEYXRhLCBmbGFncy5tZGREZWZhdWx0U2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nTWRkRG93bmxvYWRSZXN1bHQoaW50IGNvZGUsIFZvaWQgZmlsZUdyb3VwRGV0YWlscykgeworICAgIFZvaWQgbG9nRGF0YSA9IG51bGw7CisKKyAgICBzYW1wbGVBbmRTZW5kTG9nRXZlbnQoMCwgbG9nRGF0YSwgZmxhZ3MubWRkRGVmYXVsdFNhbXBsZUludGVydmFsKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGxvZ01kZEFuZHJvaWRTaGFyaW5nTG9nKFZvaWQgZXZlbnQpIHsKKyAgICAvLyBUT0RPKGIvMTQ0Njg0NzYzKTogY29uc2lkZXIgbW92aW5nIHRoaXMgdG8gc3RhYmxlIHNhbXBsaW5nIGRlcGVuZGluZyBvbiBmcmVxdWVuY3kgb2YgZXZlbnRzLgorICAgIGxvbmcgc2FtcGxlSW50ZXJ2YWwgPSBmbGFncy5tZGRBbmRyb2lkU2hhcmluZ1NhbXBsZUludGVydmFsKCk7CisgICAgaWYgKCFMb2dVdGlsLnNob3VsZFNhbXBsZUludGVydmFsKHNhbXBsZUludGVydmFsKSkgeworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBWb2lkIGxvZ0RhdGEgPSBudWxsOworICAgIHByb2Nlc3NBbmRTZW5kRXZlbnRXaXRob3V0U3RhYmxlU2FtcGxpbmcoMCwgbG9nRGF0YSwgc2FtcGxlSW50ZXJ2YWwpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGxvZ01kZFVzYWdlRXZlbnQoVm9pZCBmaWxlR3JvdXBEZXRhaWxzLCBWb2lkIHVzYWdlRXZlbnRMb2cpIHsKKyAgICBWb2lkIGxvZ0RhdGEgPSBudWxsOworCisgICAgc2FtcGxlQW5kU2VuZExvZ0V2ZW50KDAsIGxvZ0RhdGEsIGZsYWdzLm1kZERlZmF1bHRTYW1wbGVJbnRlcnZhbCgpKTsKKyAgfQorCisgIC8qKgorICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGxvZyBldmVudCB3aWxsIGJlIGEgcGFydCBvZiB0aGUgc2FtcGxlLCBhbmQgaWYgc28gY2FsbHMge0Bjb2RlCisgICAqIGJ1aWxkU3RhdHN9IHRvIGNvbnN0cnVjdCB0aGUgbG9nIGV2ZW50LiBUaGlzIGlzIGxpa2Uge0BsaW5rIHNhbXBsZUFuZFNlbmRMb2dFdmVudH0gYnV0CisgICAqIGNvbnN0cnVjdHMgdGhlIGxvZyBldmVudCBsYXp5LiBUaGlzIGlzIHVzZWZ1bCBpZiBjb25zdHJ1Y3RpbmcgdGhlIGxvZyBldmVudCBpcyBleHBlbnNpdmUuCisgICAqLworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gbGF6eVNhbXBsZUFuZFNlbmRMb2dFdmVudCgKKyAgICAgIGludCBldmVudENvZGUsIEFzeW5jQ2FsbGFibGU8TGlzdDxWb2lkPj4gYnVpbGRTdGF0cywgaW50IHNhbXBsZUludGVydmFsKSB7CisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBsb2dTYW1wbGVyLnNob3VsZExvZyhzYW1wbGVJbnRlcnZhbCwgbG9nZ2luZ1N0YXRlU3RvcmUpLAorICAgICAgICBzYW1wbGluZ0luZm9PcHRpb25hbCAtPiB7CisgICAgICAgICAgaWYgKCFzYW1wbGluZ0luZm9PcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICByZXR1cm4gRmx1ZW50RnV0dXJlLmZyb20oYnVpbGRTdGF0cy5jYWxsKCkpCisgICAgICAgICAgICAgIC50cmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICBpY2luZ0xvZ0RhdGFMaXN0IC0+IHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGljaW5nTG9nRGF0YUxpc3QgIT0gbnVsbCkgeworICAgICAgICAgICAgICAgICAgICAgIGZvciAoVm9pZCBpY2luZ0xvZ0RhdGEgOiBpY2luZ0xvZ0RhdGFMaXN0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzQW5kU2VuZEV2ZW50KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Q29kZSwgbnVsbCwgc2FtcGxlSW50ZXJ2YWwsIHNhbXBsaW5nSW5mb09wdGlvbmFsLmdldCgpKTsKKyAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgZGlyZWN0RXhlY3V0b3IoKSk7CisgICAgICAgIH0sCisgICAgICAgIGRpcmVjdEV4ZWN1dG9yKCkpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHNhbXBsZUFuZFNlbmRMb2dFdmVudChpbnQgZXZlbnRDb2RlLCBWb2lkIGxvZ0RhdGEsIGxvbmcgc2FtcGxlSW50ZXJ2YWwpIHsKKyAgICBQcm9wYWdhdGVkRnV0dXJlcy5hZGRDYWxsYmFjaygKKyAgICAgICAgbG9nU2FtcGxlci5zaG91bGRMb2coc2FtcGxlSW50ZXJ2YWwsIGxvZ2dpbmdTdGF0ZVN0b3JlKSwKKyAgICAgICAgbmV3IEZ1dHVyZUNhbGxiYWNrPE9wdGlvbmFsPFZvaWQ+PigpIHsKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoT3B0aW9uYWw8Vm9pZD4gc3RhYmxlU2FtcGxpbmdJbmZvKSB7CisgICAgICAgICAgICBpZiAoc3RhYmxlU2FtcGxpbmdJbmZvLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICAgIHByb2Nlc3NBbmRTZW5kRXZlbnQoZXZlbnRDb2RlLCBsb2dEYXRhLCBzYW1wbGVJbnRlcnZhbCwgc3RhYmxlU2FtcGxpbmdJbmZvLmdldCgpKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgdm9pZCBvbkZhaWx1cmUoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgIExvZ1V0aWwuZSh0LCAiJXM6IGZhaWx1cmUgd2hlbiBzYW1wbGluZyBsb2chIiwgVEFHKTsKKyAgICAgICAgICB9CisgICAgICAgIH0sCisgICAgICAgIGRpcmVjdEV4ZWN1dG9yKCkpOworICB9CisKKyAgLyoqIEFkZHMgYWxsIHRyYW5zZm9ybXMgY29tbW9uIHRvIGFsbCBsb2dzIGFuZCBzZW5kcyB0aGUgZXZlbnQgdG8gTG9nZ2VyLiAqLworICBwcml2YXRlIHZvaWQgcHJvY2Vzc0FuZFNlbmRFdmVudFdpdGhvdXRTdGFibGVTYW1wbGluZygKKyAgICAgIGludCBldmVudENvZGUsIFZvaWQgbG9nRGF0YSwgbG9uZyBzYW1wbGVJbnRlcnZhbCkgeworICAgIHByb2Nlc3NBbmRTZW5kRXZlbnQoZXZlbnRDb2RlLCBsb2dEYXRhLCBzYW1wbGVJbnRlcnZhbCwgbnVsbCk7CisgIH0KKworICAvKiogQWRkcyBhbGwgdHJhbnNmb3JtcyBjb21tb24gdG8gYWxsIGxvZ3MgYW5kIHNlbmRzIHRoZSBldmVudCB0byBMb2dnZXIuICovCisgIHByaXZhdGUgdm9pZCBwcm9jZXNzQW5kU2VuZEV2ZW50KAorICAgICAgaW50IGV2ZW50Q29kZSwgVm9pZCBsb2dEYXRhLCBsb25nIHNhbXBsZUludGVydmFsLCBWb2lkIHN0YWJsZVNhbXBsaW5nSW5mbykge30KKworICAvKiogUmV0dXJucyB3aGV0aGVyIHRoZSBkZXZpY2UgaXMgaW4gbG93IHN0b3JhZ2Ugc3RhdGUuICovCisgIHByaXZhdGUgc3RhdGljIGJvb2xlYW4gaXNEZXZpY2VTdG9yYWdlTG93KENvbnRleHQgY29udGV4dCkgeworICAgIC8vIENoZWNrIGlmIHRoZSBzeXN0ZW0gc2F5cyBzdG9yYWdlIGlzIGxvdywgYnkgcmVhZGluZyB0aGUgc3RpY2t5IGludGVudC4KKyAgICByZXR1cm4gY29udGV4dC5yZWdpc3RlclJlY2VpdmVyKG51bGwsIG5ldyBJbnRlbnRGaWx0ZXIoSW50ZW50LkFDVElPTl9ERVZJQ0VfU1RPUkFHRV9MT1cpKQorICAgICAgICAhPSBudWxsOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvTmV0d29ya0xvZ2dlci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL05ldHdvcmtMb2dnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZjJhYzFmCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL05ldHdvcmtMb2dnZXIuamF2YQpAQCAtMCwwICsxLDc3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuYW5ub3RhdGlvbnMuSW5zdGFuY2VJZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5BcHBsaWNhdGlvbkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5Qcm9wYWdhdGVkRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRmlsZUdyb3VwTG9nZ2luZ1N0YXRlOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmF4LmluamVjdC5JbmplY3Q7CisKKy8qKgorICogTG9nIE1ERCBuZXR3b3JrIHN0YXRzIGF0IGRhaWx5IG1haW50ZW5hbmNlLiBGb3IgZWFjaCBmaWxlIGdyb3VwLCBpdCB3aWxsIGxvZyB0aGUgdG90YWwgYnl0ZXMKKyAqIGRvd25sb2FkZWQgb24gV2lmaSBhbmQgQ2VsbHVsYXIgYW5kIGFsc28gdG90YWwgYnl0ZXMgZG93bmxvYWRlZCBieSBNREQgb24gV2lmaSBhbmQgQ2VsbHVsYXIuCisgKi8KK3B1YmxpYyBjbGFzcyBOZXR3b3JrTG9nZ2VyIHsKKworICBwcml2YXRlIGZpbmFsIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyOworICBwcml2YXRlIGZpbmFsIEZsYWdzIGZsYWdzOworICBwcml2YXRlIGZpbmFsIExvZ2dpbmdTdGF0ZVN0b3JlIGxvZ2dpbmdTdGF0ZVN0b3JlOworCisgIEBJbmplY3QKKyAgcHVibGljIE5ldHdvcmtMb2dnZXIoCisgICAgICBAQXBwbGljYXRpb25Db250ZXh0IENvbnRleHQgY29udGV4dCwKKyAgICAgIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyLAorICAgICAgQEluc3RhbmNlSWQgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkT3B0aW9uYWwsCisgICAgICBGbGFncyBmbGFncywKKyAgICAgIExvZ2dpbmdTdGF0ZVN0b3JlIGxvZ2dpbmdTdGF0ZVN0b3JlKSB7CisgICAgdGhpcy5ldmVudExvZ2dlciA9IGV2ZW50TG9nZ2VyOworICAgIHRoaXMuZmxhZ3MgPSBmbGFnczsKKyAgICB0aGlzLmxvZ2dpbmdTdGF0ZVN0b3JlID0gbG9nZ2luZ1N0YXRlU3RvcmU7CisgIH0KKworICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBsb2coKSB7CisgICAgaWYgKCFmbGFncy5sb2dOZXR3b3JrU3RhdHMoKSkgeworICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICB9CisKKyAgICAvLyBDbGVhciB0aGUgYWNjdW11bGF0ZWQgbmV0d29yayB1c2FnZSBldmVuIGlmIHRoZSBkZXZpY2UgaXNuJ3QgbG9nZ2luZywgb3RoZXJ3aXNlIHdpdGggMSUKKyAgICAvLyBzYW1wbGluZywgd2UgY291bGQgcG90ZW50aWFsbHkgbG9nIG5ldHdvcmsgdXNhZ2UgZm9yIHVwIHRvIDEwMCBkYXlzLgorICAgIExpc3RlbmFibGVGdXR1cmU8TGlzdDxGaWxlR3JvdXBMb2dnaW5nU3RhdGU+PiBhbGxEYXRhVXNhZ2VGdXR1cmUgPQorICAgICAgICBsb2dnaW5nU3RhdGVTdG9yZS5nZXRBbmRSZXNldEFsbERhdGFVc2FnZSgpOworCisgICAgcmV0dXJuIGV2ZW50TG9nZ2VyLmxvZ01kZE5ldHdvcmtTdGF0cygKKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICBhbGxEYXRhVXNhZ2VGdXR1cmUsIHRoaXM6OmJ1aWxkTmV0d29ya1N0YXRzLCBkaXJlY3RFeGVjdXRvcigpKSk7CisgIH0KKworICBwcml2YXRlIFZvaWQgYnVpbGROZXR3b3JrU3RhdHMoTGlzdDxGaWxlR3JvdXBMb2dnaW5nU3RhdGU+IGFsbERhdGFVc2FnZSkgeworICAgIGxvbmcgdG90YWxNZGRXaWZpQ291bnQgPSAwOworICAgIGxvbmcgdG90YWxNZGRDZWxsdWxhckNvdW50ID0gMDsKKyAgICBWb2lkIG5ldHdvcmtTdGF0c0J1aWxkZXIgPSBudWxsOworCisgICAgcmV0dXJuIG5ldHdvcmtTdGF0c0J1aWxkZXI7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9Ob09wRXZlbnRMb2dnZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZy9Ob09wRXZlbnRMb2dnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YmY2ZWJjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL05vT3BFdmVudExvZ2dlci5qYXZhCkBAIC0wLDAgKzEsODYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmc7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZTsKKworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Bc3luY0NhbGxhYmxlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKiogTm8tT3AgRXZlbnRMb2dnZXIgaW1wbGVtZW50YXRpb24uICovCitwdWJsaWMgZmluYWwgY2xhc3MgTm9PcEV2ZW50TG9nZ2VyIGltcGxlbWVudHMgRXZlbnRMb2dnZXIgeworCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dFdmVudFNhbXBsZWQoaW50IGV2ZW50Q29kZSkge30KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nRXZlbnRTYW1wbGVkKAorICAgICAgaW50IGV2ZW50Q29kZSwKKyAgICAgIFN0cmluZyBmaWxlR3JvdXBOYW1lLAorICAgICAgaW50IGZpbGVHcm91cFZlcnNpb25OdW1iZXIsCisgICAgICBsb25nIGJ1aWxkSWQsCisgICAgICBTdHJpbmcgdmFyaWFudElkKSB7fQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dFdmVudEFmdGVyU2FtcGxlKGludCBldmVudENvZGUsIGludCBzYW1wbGVJbnRlcnZhbCkge30KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gbG9nTWRkRmlsZUdyb3VwU3RhdHMoCisgICAgICBBc3luY0NhbGxhYmxlPExpc3Q8RXZlbnRMb2dnZXIuRmlsZUdyb3VwU3RhdHVzV2l0aERldGFpbHM+PiBidWlsZEZpbGVHcm91cFN0YXRzKSB7CisgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dNZGRBcGlDYWxsU3RhdHMoVm9pZCBmaWxlR3JvdXBEZXRhaWxzLCBWb2lkIGFwaUNhbGxTdGF0cykge30KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gbG9nTWRkU3RvcmFnZVN0YXRzKEFzeW5jQ2FsbGFibGU8Vm9pZD4gYnVpbGRNZGRTdG9yYWdlU3RhdHMpIHsKKyAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGxvZ01kZE5ldHdvcmtTdGF0cyhBc3luY0NhbGxhYmxlPFZvaWQ+IGJ1aWxkTWRkTmV0d29ya1N0YXRzKSB7CisgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dNZGREYXRhRG93bmxvYWRGaWxlRXhwaXJhdGlvbkV2ZW50KGludCBldmVudENvZGUsIGludCBjb3VudCkge30KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nTWRkTmV0d29ya1NhdmluZ3MoCisgICAgICBWb2lkIGZpbGVHcm91cERldGFpbHMsCisgICAgICBpbnQgY29kZSwKKyAgICAgIGxvbmcgZnVsbEZpbGVTaXplLAorICAgICAgbG9uZyBkb3dubG9hZGVkRmlsZVNpemUsCisgICAgICBTdHJpbmcgZmlsZUlkLAorICAgICAgaW50IGRlbHRhSW5kZXgpIHt9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGxvZ01kZERvd25sb2FkUmVzdWx0KGludCBjb2RlLCBWb2lkIGZpbGVHcm91cERldGFpbHMpIHt9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGxvZ01kZFF1ZXJ5U3RhdHMoVm9pZCBmaWxlR3JvdXBEZXRhaWxzKSB7fQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dNZGRBbmRyb2lkU2hhcmluZ0xvZyhWb2lkIGV2ZW50KSB7fQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dNZGREb3dubG9hZExhdGVuY3koVm9pZCBmaWxlR3JvdXBTdGF0cywgVm9pZCBkb3dubG9hZExhdGVuY3kpIHt9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGxvZ01kZFVzYWdlRXZlbnQoVm9pZCBmaWxlR3JvdXBEZXRhaWxzLCBWb2lkIHVzYWdlRXZlbnRMb2cpIHt9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvTm9PcExvZ2dpbmdTdGF0ZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL05vT3BMb2dnaW5nU3RhdGUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kNjRmNzRjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL05vT3BMb2dnaW5nU3RhdGUuamF2YQpAQCAtMCwwICsxLDU3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZTsKKworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRmlsZUdyb3VwTG9nZ2luZ1N0YXRlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uU2FtcGxpbmdJbmZvOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKiogTG9nZ2luZ1N0YXRlU3RvcmUgdGhhdCByZXR1cm5zIGVtcHR5IG9yIHZvaWQgZm9yIGFsbCBvcGVyYXRpb25zLiAqLworcHVibGljIGZpbmFsIGNsYXNzIE5vT3BMb2dnaW5nU3RhdGUgaW1wbGVtZW50cyBMb2dnaW5nU3RhdGVTdG9yZSB7CisKKyAgcHVibGljIE5vT3BMb2dnaW5nU3RhdGUoKSB7fQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxPcHRpb25hbDxJbnRlZ2VyPj4gZ2V0QW5kUmVzZXREYXlzU2luY2VMYXN0TWFpbnRlbmFuY2UoKSB7CisgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShPcHRpb25hbC5hYnNlbnQoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gaW5jcmVtZW50RGF0YVVzYWdlKEZpbGVHcm91cExvZ2dpbmdTdGF0ZSB1bnVzZWQpIHsKKyAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPExpc3Q8RmlsZUdyb3VwTG9nZ2luZ1N0YXRlPj4gZ2V0QW5kUmVzZXRBbGxEYXRhVXNhZ2UoKSB7CisgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShJbW11dGFibGVMaXN0Lm9mKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNsZWFyKCkgeworICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8U2FtcGxpbmdJbmZvPiBnZXRTdGFibGVTYW1wbGluZ0luZm8oKSB7CisgICAgcmV0dXJuIGltbWVkaWF0ZUZ1dHVyZShTYW1wbGluZ0luZm8uZ2V0RGVmYXVsdEluc3RhbmNlKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvU3RvcmFnZUxvZ2dlci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL1N0b3JhZ2VMb2dnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MzA3OTQxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL1N0b3JhZ2VMb2dnZXIuamF2YQpAQCAtMCwwICsxLDMxMSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZzsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZGRDb25zdGFudHMuU1BMSVRfQ0hBUjsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlNpbGVudEZlZWRiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmFubm90YXRpb25zLkluc3RhbmNlSWQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLkFwcGxpY2F0aW9uQ29udGV4dDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5GaWxlR3JvdXBzTWV0YWRhdGE7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWRkQ29uc3RhbnRzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLlNoYXJlZEZpbGVNYW5hZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLlNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLlNoYXJlZEZpbGVzTWV0YWRhdGE7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuYW5ub3RhdGlvbnMuU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLkZpbGVHcm91cFV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5Qcm9wYWdhdGVkRmx1ZW50RnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRyYWNpbmcuUHJvcGFnYXRlZEZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5hdXRvLnZhbHVlLkF1dG9WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuUHJlY29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN0cmluZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZsdWVudEZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uR3JvdXBLZXk7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5OZXdGaWxlS2V5OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5TZXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0xvbmc7CitpbXBvcnQgamF2YXguaW5qZWN0LkluamVjdDsKKworLyoqCisgKiBMb2cgTUREIHN0b3JhZ2Ugc3RhdHMgYXQgZGFpbHkgbWFpbnRlbmFuY2UuIEZvciBlYWNoIGZpbGUgZ3JvdXAsIGl0IHdpbGwgbG9nIHRoZSB0b3RhbCBieXRlcyB1c2VkCisgKiBvbiBkaXNrIGZvciB0aGF0IGZpbGUgZ3JvdXAgYW5kIHRoZSBieXRlcyB1c2VkIGJ5IHRoZSBkb3dubG9hZGVkIGdyb3VwLgorICovCitwdWJsaWMgY2xhc3MgU3RvcmFnZUxvZ2dlciB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiU3RvcmFnZUxvZ2dlciI7CisgIHByaXZhdGUgZmluYWwgRmlsZUdyb3Vwc01ldGFkYXRhIGZpbGVHcm91cHNNZXRhZGF0YTsKKyAgcHJpdmF0ZSBmaW5hbCBTaGFyZWRGaWxlTWFuYWdlciBzaGFyZWRGaWxlTWFuYWdlcjsKKyAgcHJpdmF0ZSBmaW5hbCBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIGZpbmFsIEV2ZW50TG9nZ2VyIGV2ZW50TG9nZ2VyOworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dDsKKyAgcHJpdmF0ZSBmaW5hbCBTaWxlbnRGZWVkYmFjayBzaWxlbnRGZWVkYmFjazsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQ7CisgIHByaXZhdGUgZmluYWwgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKworICAvKiogU3RvcmUgdGhlIHN0b3JhZ2Ugc3RhdHMgZm9yIGEgZmlsZSBncm91cC4gKi8KKyAgc3RhdGljIGNsYXNzIEdyb3VwU3RvcmFnZSB7CisgICAgLy8gVGhlIHN1bSBvZiBhbGwgb24tZGlzayBmaWxlIHNpemVzIG9mIHRoZSBmaWxlcyBiZWxvbmdpbmcgdG8gdGhpcyBmaWxlIGdyb3VwLCBpbiBieXRlcy4KKyAgICBwdWJsaWMgbG9uZyB0b3RhbEJ5dGVzVXNlZDsKKworICAgIC8vIFRoZSBzdW0gb2YgYWxsIG9uLWRpc2sgaW5saW5lIGZpbGUgc2l6ZXMgb2YgdGhlIGZpbGVzIGJlbG9uZ2luZyB0byB0aGlzIGZpbGUgZ3JvdXAsIGluIGJ5dGVzLgorICAgIHB1YmxpYyBsb25nIHRvdGFsSW5saW5lQnl0ZXNVc2VkOworCisgICAgLy8gVGhlIHN1bSBvZiBhbGwgb24tZGlzayBmaWxlIHNpemVzIG9mIHRoaXMgZG93bmxvYWRlZCBmaWxlIGdyb3VwIGluIGJ5dGVzLgorICAgIHB1YmxpYyBsb25nIGRvd25sb2FkZWRHcm91cEJ5dGVzVXNlZDsKKworICAgIC8vIFRoZSBzdW0gb2YgYWxsIG9uLWRpc2sgaW5saW5lIGZpbGVzIHNpemVzIG9mIHRoaXMgZG93bmxvYWRlZCBmaWxlIGdyb3VwIGluIGJ5dGVzLgorICAgIHB1YmxpYyBsb25nIGRvd25sb2FkZWRHcm91cElubGluZUJ5dGVzVXNlZDsKKworICAgIC8vIFRoZSB0b3RhbCBudW1iZXIgb2YgZmlsZXMgaW4gdGhlIGdyb3VwLgorICAgIHB1YmxpYyBpbnQgdG90YWxGaWxlQ291bnQ7CisKKyAgICAvLyBUaGUgbnVtYmVyIG9mIGlubGluZSBmaWxlcyBpbiB0aGUgZ3JvdXAuCisgICAgcHVibGljIGludCB0b3RhbElubGluZUZpbGVDb3VudDsKKyAgfQorCisgIEBJbmplY3QKKyAgcHVibGljIFN0b3JhZ2VMb2dnZXIoCisgICAgICBAQXBwbGljYXRpb25Db250ZXh0IENvbnRleHQgY29udGV4dCwKKyAgICAgIEZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGEsCisgICAgICBTaGFyZWRGaWxlTWFuYWdlciBzaGFyZWRGaWxlTWFuYWdlciwKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsCisgICAgICBFdmVudExvZ2dlciBldmVudExvZ2dlciwKKyAgICAgIFNpbGVudEZlZWRiYWNrIHNpbGVudEZlZWRiYWNrLAorICAgICAgQEluc3RhbmNlSWQgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkLAorICAgICAgQFNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgRXhlY3V0b3Igc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcikgeworICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CisgICAgdGhpcy5maWxlR3JvdXBzTWV0YWRhdGEgPSBmaWxlR3JvdXBzTWV0YWRhdGE7CisgICAgdGhpcy5zaGFyZWRGaWxlTWFuYWdlciA9IHNoYXJlZEZpbGVNYW5hZ2VyOworICAgIHRoaXMuZmlsZVN0b3JhZ2UgPSBmaWxlU3RvcmFnZTsKKyAgICB0aGlzLmV2ZW50TG9nZ2VyID0gZXZlbnRMb2dnZXI7CisgICAgdGhpcy5zaWxlbnRGZWVkYmFjayA9IHNpbGVudEZlZWRiYWNrOworICAgIHRoaXMuaW5zdGFuY2VJZCA9IGluc3RhbmNlSWQ7CisgICAgdGhpcy5zZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yID0gc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKKyAgfQorCisgIC8vIFRPRE8oYi82NDc2NDY0OCk6IENvbWJpbmUgdGhpcyB3aXRoIE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuY3JlYXRlR3JvdXBLZXkKKyAgcHJpdmF0ZSBzdGF0aWMgR3JvdXBLZXkgY3JlYXRlR3JvdXBLZXkoRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCkgeworICAgIEdyb3VwS2V5LkJ1aWxkZXIgZ3JvdXBLZXkgPSBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisKKyAgICBpZiAoU3RyaW5ncy5pc051bGxPckVtcHR5KGZpbGVHcm91cC5nZXRPd25lclBhY2thZ2UoKSkpIHsKKyAgICAgIGdyb3VwS2V5LnNldE93bmVyUGFja2FnZShNZGRDb25zdGFudHMuR01TX1BBQ0tBR0UpOworICAgIH0gZWxzZSB7CisgICAgICBncm91cEtleS5zZXRPd25lclBhY2thZ2UoZmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKTsKKyAgICB9CisKKyAgICByZXR1cm4gZ3JvdXBLZXkuYnVpbGQoKTsKKyAgfQorCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGxvZ1N0b3JhZ2VTdGF0cyhpbnQgZGF5c1NpbmNlTGFzdExvZykgeworICAgIHJldHVybiBldmVudExvZ2dlci5sb2dNZGRTdG9yYWdlU3RhdHMoKCkgLT4gYnVpbGRTdG9yYWdlU3RhdHNJY2luZ0xvZ0RhdGEoZGF5c1NpbmNlTGFzdExvZykpOworICB9CisKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGJ1aWxkU3RvcmFnZVN0YXRzSWNpbmdMb2dEYXRhKGludCBkYXlzU2luY2VMYXN0TG9nKSB7CisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmUuZnJvbShmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgYWxsR3JvdXBzIC0+CisgICAgICAgICAgICAgICAgUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxTdGFsZUdyb3VwcygpLAorICAgICAgICAgICAgICAgICAgICBzdGFsZUdyb3VwcyAtPgorICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRTdG9yYWdlU3RhdHNJbnRlcm5hbChhbGxHcm91cHMsIHN0YWxlR3JvdXBzLCBkYXlzU2luY2VMYXN0TG9nKSwKKyAgICAgICAgICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciksCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBidWlsZFN0b3JhZ2VTdGF0c0ludGVybmFsKAorICAgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBhbGxLZXlzQW5kR3JvdXBQYWlycywKKyAgICAgIExpc3Q8RGF0YUZpbGVHcm91cEludGVybmFsPiBzdGFsZUdyb3VwcywKKyAgICAgIGludCBkYXlzU2luY2VMYXN0TG9nKSB7CisKKyAgICBMaXN0PEdyb3VwS2V5QW5kRGF0YUZpbGVHcm91cEludGVybmFsPiBhbGxLZXlzQW5kR3JvdXBzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgZm9yIChQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGdyb3VwS2V5QW5kR3JvdXAgOiBhbGxLZXlzQW5kR3JvdXBQYWlycykgeworICAgICAgYWxsS2V5c0FuZEdyb3Vwcy5hZGQoCisgICAgICAgICAgR3JvdXBLZXlBbmREYXRhRmlsZUdyb3VwSW50ZXJuYWwuY3JlYXRlKGdyb3VwS2V5QW5kR3JvdXAuZmlyc3QsIGdyb3VwS2V5QW5kR3JvdXAuc2Vjb25kKSk7CisgICAgfQorCisgICAgLy8gQWRkaW5nIHN0YWxlR3JvdXBzIHRvIGFsbEdyb3Vwcy4KKyAgICBmb3IgKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgOiBzdGFsZUdyb3VwcykgeworICAgICAgYWxsS2V5c0FuZEdyb3Vwcy5hZGQoCisgICAgICAgICAgR3JvdXBLZXlBbmREYXRhRmlsZUdyb3VwSW50ZXJuYWwuY3JlYXRlKGNyZWF0ZUdyb3VwS2V5KGZpbGVHcm91cCksIGZpbGVHcm91cCkpOworICAgIH0KKworICAgIE1hcDxTdHJpbmcsIEdyb3VwU3RvcmFnZT4gZ3JvdXBLZXlUb0dyb3VwU3RvcmFnZSA9IG5ldyBIYXNoTWFwPD4oKTsKKyAgICBNYXA8U3RyaW5nLCBTZXQ8TmV3RmlsZUtleT4+IGdyb3VwS2V5VG9GaWxlS2V5cyA9IG5ldyBIYXNoTWFwPD4oKTsKKyAgICBNYXA8U3RyaW5nLCBTZXQ8TmV3RmlsZUtleT4+IGRvd25sb2FkZWRHcm91cEtleVRvRmlsZUtleXMgPSBuZXcgSGFzaE1hcDw+KCk7CisgICAgTWFwPFN0cmluZywgRGF0YUZpbGVHcm91cEludGVybmFsPiBkb3dubG9hZGVkR3JvdXBLZXlUb0RhdGFGaWxlR3JvdXAgPSBuZXcgSGFzaE1hcDw+KCk7CisKKyAgICBTZXQ8TmV3RmlsZUtleT4gYWxsRmlsZUtleXMgPSBuZXcgSGFzaFNldDw+KCk7CisgICAgLy8gT3VyIGJ5dGVzIGNvdW50ZXIgaGFzIHRvIGJlIHdyYXBwZWQgaW4gYW4gT2JqZWN0IGJlY2F1c2UgdmFyaWFibGVzIGNhcHR1cmVkIGJ5IGxhbWJkYQorICAgIC8vIGV4cHJlc3Npb25zIG5lZWQgdG8gYmUgImVmZmVjdGl2ZWx5IGZpbmFsIiAtIG1lYW5pbmcgdGhleSBuZXZlciBhcHBlYXIgb24gdGhlIGxlZnQtaGFuZCBzaWRlCisgICAgLy8gb2YgYW4gYXNzaWdubWVudCBzdGF0ZW1lbnQuIEFzIHN1Y2gsIHdlIHVzZSBBdG9taWNMb25nLgorICAgIEF0b21pY0xvbmcgdG90YWxNZGRCeXRlc1VzZWQgPSBuZXcgQXRvbWljTG9uZygwTCk7CisKKyAgICBMaXN0PExpc3RlbmFibGVGdXR1cmU8Vm9pZD4+IGZ1dHVyZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBmb3IgKEdyb3VwS2V5QW5kRGF0YUZpbGVHcm91cEludGVybmFsIGdyb3VwS2V5QW5kR3JvdXAgOiBhbGxLZXlzQW5kR3JvdXBzKSB7CisKKyAgICAgIFNldDxOZXdGaWxlS2V5PiBmaWxlS2V5cyA9CisgICAgICAgICAgc2FmZUdldEZpbGVLZXlzKAorICAgICAgICAgICAgICBncm91cEtleVRvRmlsZUtleXMsIGdldEdyb3VwV2l0aE93bmVyUGFja2FnZUtleShncm91cEtleUFuZEdyb3VwLmdyb3VwS2V5KCkpKTsKKworICAgICAgR3JvdXBTdG9yYWdlIGdyb3VwU3RvcmFnZSA9CisgICAgICAgICAgc2FmZUdldEdyb3VwU3RvcmFnZSgKKyAgICAgICAgICAgICAgZ3JvdXBLZXlUb0dyb3VwU3RvcmFnZSwgZ2V0R3JvdXBXaXRoT3duZXJQYWNrYWdlS2V5KGdyb3VwS2V5QW5kR3JvdXAuZ3JvdXBLZXkoKSkpOworCisgICAgICBTZXQ8TmV3RmlsZUtleT4gZG93bmxvYWRlZEZpbGVLZXlzSW5pdCA9IG51bGw7CisKKyAgICAgIGlmIChncm91cEtleUFuZEdyb3VwLmdyb3VwS2V5KCkuZ2V0RG93bmxvYWRlZCgpKSB7CisgICAgICAgIGRvd25sb2FkZWRGaWxlS2V5c0luaXQgPQorICAgICAgICAgICAgc2FmZUdldEZpbGVLZXlzKAorICAgICAgICAgICAgICAgIGRvd25sb2FkZWRHcm91cEtleVRvRmlsZUtleXMsCisgICAgICAgICAgICAgICAgZ2V0R3JvdXBXaXRoT3duZXJQYWNrYWdlS2V5KGdyb3VwS2V5QW5kR3JvdXAuZ3JvdXBLZXkoKSkpOworICAgICAgICBkb3dubG9hZGVkR3JvdXBLZXlUb0RhdGFGaWxlR3JvdXAucHV0KAorICAgICAgICAgICAgZ2V0R3JvdXBXaXRoT3duZXJQYWNrYWdlS2V5KGdyb3VwS2V5QW5kR3JvdXAuZ3JvdXBLZXkoKSksCisgICAgICAgICAgICBncm91cEtleUFuZEdyb3VwLmRhdGFGaWxlR3JvdXBJbnRlcm5hbCgpKTsKKyAgICAgIH0KKworICAgICAgLy8gVmFyaWFibGVzIGNhcHR1cmVkIGJ5IGxhbWJkYXMgbXVzdCBiZSBlZmZlY3RpdmVseSBmaW5hbC4KKyAgICAgIFNldDxOZXdGaWxlS2V5PiBkb3dubG9hZGVkRmlsZUtleXMgPSBkb3dubG9hZGVkRmlsZUtleXNJbml0OworICAgICAgaW50IHRvdGFsRmlsZUNvdW50ID0gZ3JvdXBLZXlBbmRHcm91cC5kYXRhRmlsZUdyb3VwSW50ZXJuYWwoKS5nZXRGaWxlQ291bnQoKTsKKyAgICAgIGZvciAoRGF0YUZpbGUgZGF0YUZpbGUgOiBncm91cEtleUFuZEdyb3VwLmRhdGFGaWxlR3JvdXBJbnRlcm5hbCgpLmdldEZpbGVMaXN0KCkpIHsKKyAgICAgICAgYm9vbGVhbiBpc0lubGluZUZpbGUgPSBGaWxlR3JvdXBVdGlsLmlzSW5saW5lRmlsZShkYXRhRmlsZSk7CisKKyAgICAgICAgTmV3RmlsZUtleSBmaWxlS2V5ID0KKyAgICAgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgICAgIGRhdGFGaWxlLCBncm91cEtleUFuZEdyb3VwLmRhdGFGaWxlR3JvdXBJbnRlcm5hbCgpLmdldEFsbG93ZWRSZWFkZXJzRW51bSgpKTsKKyAgICAgICAgZnV0dXJlcy5hZGQoCisgICAgICAgICAgICBGdXR1cmVzLnRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICBjb21wdXRlRmlsZVNpemUoZmlsZUtleSksCisgICAgICAgICAgICAgICAgZmlsZVNpemUgLT4geworICAgICAgICAgICAgICAgICAgaWYgKCFhbGxGaWxlS2V5cy5jb250YWlucyhmaWxlS2V5KSkgeworICAgICAgICAgICAgICAgICAgICB0b3RhbE1kZEJ5dGVzVXNlZC5nZXRBbmRBZGQoZmlsZVNpemUpOworICAgICAgICAgICAgICAgICAgICBhbGxGaWxlS2V5cy5hZGQoZmlsZUtleSk7CisgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgcHJvY2Vzc2VkIHRoaXMgZmlsZUtleSBiZWZvcmUuCisgICAgICAgICAgICAgICAgICBpZiAoIWZpbGVLZXlzLmNvbnRhaW5zKGZpbGVLZXkpKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChpc0lubGluZUZpbGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICBncm91cFN0b3JhZ2UudG90YWxJbmxpbmVCeXRlc1VzZWQgKz0gZmlsZVNpemU7CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBncm91cFN0b3JhZ2UudG90YWxCeXRlc1VzZWQgKz0gZmlsZVNpemU7CisgICAgICAgICAgICAgICAgICAgIGZpbGVLZXlzLmFkZChmaWxlS2V5KTsKKyAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgaWYgKGdyb3VwS2V5QW5kR3JvdXAuZ3JvdXBLZXkoKS5nZXREb3dubG9hZGVkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgLy8gTm90ZTogTnVsbG5lc3MgY2hlY2tlciBpcyBub3Qgc21hcnQgZW5vdWdoIHRvIGZpZ3VyZSBvdXQgdGhhdAorICAgICAgICAgICAgICAgICAgICAvLyBkb3dubG9hZGVkRmlsZUtleXMgaXMgbmV2ZXIgbnVsbC4KKyAgICAgICAgICAgICAgICAgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwoZG93bmxvYWRlZEZpbGVLZXlzKTsKKyAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBwcm9jZXNzZWQgdGhpcyBmaWxlS2V5IGJlZm9yZS4KKyAgICAgICAgICAgICAgICAgICAgaWYgKCFkb3dubG9hZGVkRmlsZUtleXMuY29udGFpbnMoZmlsZUtleSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNJbmxpbmVGaWxlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBncm91cFN0b3JhZ2UuZG93bmxvYWRlZEdyb3VwSW5saW5lQnl0ZXNVc2VkICs9IGZpbGVTaXplOworICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBTdG9yYWdlLnRvdGFsSW5saW5lRmlsZUNvdW50ICs9IDE7CisgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBTdG9yYWdlLmRvd25sb2FkZWRHcm91cEJ5dGVzVXNlZCArPSBmaWxlU2l6ZTsKKyAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZGVkRmlsZUtleXMuYWRkKGZpbGVLZXkpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpKTsKKyAgICAgIH0KKyAgICAgIGdyb3VwU3RvcmFnZS50b3RhbEZpbGVDb3VudCA9IHRvdGFsRmlsZUNvdW50OworICAgIH0KKworICAgIHJldHVybiBGdXR1cmVzLndoZW5BbGxDb21wbGV0ZShmdXR1cmVzKQorICAgICAgICAuY2FsbCgKKyAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgVm9pZCBzdG9yYWdlU3RhdHNCdWlsZGVyID0gbnVsbDsKKyAgICAgICAgICAgICAgcmV0dXJuIHN0b3JhZ2VTdGF0c0J1aWxkZXI7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIFN0cmluZyBnZXRHcm91cFdpdGhPd25lclBhY2thZ2VLZXkoR3JvdXBLZXkgZ3JvdXBLZXkpIHsKKyAgICByZXR1cm4gbmV3IFN0cmluZ0J1aWxkZXIoZ3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCkpCisgICAgICAgIC5hcHBlbmQoU1BMSVRfQ0hBUikKKyAgICAgICAgLmFwcGVuZChncm91cEtleS5nZXRPd25lclBhY2thZ2UoKSkKKyAgICAgICAgLnRvU3RyaW5nKCk7CisgIH0KKworICBwcml2YXRlIFNldDxOZXdGaWxlS2V5PiBzYWZlR2V0RmlsZUtleXMoCisgICAgICBNYXA8U3RyaW5nLCBTZXQ8TmV3RmlsZUtleT4+IGdyb3VwTmFtZVRvRmlsZUtleXMsIFN0cmluZyBncm91cE5hbWUpIHsKKyAgICBTZXQ8TmV3RmlsZUtleT4gZmlsZUtleXMgPSBncm91cE5hbWVUb0ZpbGVLZXlzLmdldChncm91cE5hbWUpOworICAgIGlmIChmaWxlS2V5cyA9PSBudWxsKSB7CisgICAgICBncm91cE5hbWVUb0ZpbGVLZXlzLnB1dChncm91cE5hbWUsIG5ldyBIYXNoU2V0PD4oKSk7CisgICAgICBmaWxlS2V5cyA9IGdyb3VwTmFtZVRvRmlsZUtleXMuZ2V0KGdyb3VwTmFtZSk7CisgICAgfQorICAgIHJldHVybiBmaWxlS2V5czsKKyAgfQorCisgIHByaXZhdGUgR3JvdXBTdG9yYWdlIHNhZmVHZXRHcm91cFN0b3JhZ2UoCisgICAgICBNYXA8U3RyaW5nLCBHcm91cFN0b3JhZ2U+IGdyb3VwTmFtZVRvU3RhdHMsIFN0cmluZyBncm91cE5hbWUpIHsKKyAgICBHcm91cFN0b3JhZ2UgZ3JvdXBTdG9yYWdlID0gZ3JvdXBOYW1lVG9TdGF0cy5nZXQoZ3JvdXBOYW1lKTsKKyAgICBpZiAoZ3JvdXBTdG9yYWdlID09IG51bGwpIHsKKyAgICAgIGdyb3VwTmFtZVRvU3RhdHMucHV0KGdyb3VwTmFtZSwgbmV3IEdyb3VwU3RvcmFnZSgpKTsKKyAgICAgIGdyb3VwU3RvcmFnZSA9IGdyb3VwTmFtZVRvU3RhdHMuZ2V0KGdyb3VwTmFtZSk7CisgICAgfQorICAgIHJldHVybiBncm91cFN0b3JhZ2U7CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8TG9uZz4gY29tcHV0ZUZpbGVTaXplKE5ld0ZpbGVLZXkgbmV3RmlsZUtleSkgeworICAgIHJldHVybiBGbHVlbnRGdXR1cmUuZnJvbShzaGFyZWRGaWxlTWFuYWdlci5nZXRPbkRldmljZVVyaShuZXdGaWxlS2V5KSkKKyAgICAgICAgLmNhdGNoaW5nQXN5bmMoCisgICAgICAgICAgICBTaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgIGUgLT4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCksCisgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKQorICAgICAgICAudHJhbnNmb3JtKAorICAgICAgICAgICAgZmlsZVVyaSAtPiB7CisgICAgICAgICAgICAgIGlmIChmaWxlVXJpICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVTdG9yYWdlLmZpbGVTaXplKGZpbGVVcmkpOworICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZShlLCAiJXM6IEZhaWxlZCB0byBjYWxsIG1vYnN0b3JlIGZpbGVTaXplIG9uIHVyaSAlcyEiLCBUQUcsIGZpbGVVcmkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICByZXR1cm4gMEw7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICBAQXV0b1ZhbHVlCisgIGFic3RyYWN0IHN0YXRpYyBjbGFzcyBHcm91cEtleUFuZERhdGFGaWxlR3JvdXBJbnRlcm5hbCB7CisgICAgc3RhdGljIEdyb3VwS2V5QW5kRGF0YUZpbGVHcm91cEludGVybmFsIGNyZWF0ZSgKKyAgICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwSW50ZXJuYWwpIHsKKyAgICAgIHJldHVybiBuZXcgQXV0b1ZhbHVlX1N0b3JhZ2VMb2dnZXJfR3JvdXBLZXlBbmREYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgZ3JvdXBLZXksIGRhdGFGaWxlR3JvdXBJbnRlcm5hbCk7CisgICAgfQorCisgICAgYWJzdHJhY3QgR3JvdXBLZXkgZ3JvdXBLZXkoKTsKKworICAgIGFic3RyYWN0IERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwSW50ZXJuYWwoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL3Rlc3RpbmcvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvdGVzdGluZy9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YmY5NTEwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL3Rlc3RpbmcvQlVJTEQKQEAgLTAsMCArMSwzMSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkZha2VFdmVudExvZ2dlciIsCisgICAgdGVzdG9ubHkgPSAxLAorICAgIHNyY3MgPSBbIkZha2VFdmVudExvZ2dlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkV2ZW50TG9nZ2VyIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL3Rlc3RpbmcvRmFrZUV2ZW50TG9nZ2VyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmcvdGVzdGluZy9GYWtlRXZlbnRMb2dnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMmRiYTI5Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nL3Rlc3RpbmcvRmFrZUV2ZW50TG9nZ2VyLmphdmEKQEAgLTAsMCArMSwxMjYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcudGVzdGluZzsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmU7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkV2ZW50TG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuRXZlbnRMb2dnZXIuRmlsZUdyb3VwU3RhdHVzV2l0aERldGFpbHM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5BcnJheUxpc3RNdWx0aW1hcDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQXN5bmNDYWxsYWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKiogRmFrZSBpbXBsZW1lbnRhdGlvbiBvZiB7QGxpbmsgRXZlbnRMb2dnZXJ9IGZvciB1c2UgaW4gdGVzdHMuICovCitwdWJsaWMgZmluYWwgY2xhc3MgRmFrZUV2ZW50TG9nZ2VyIGltcGxlbWVudHMgRXZlbnRMb2dnZXIgeworCisgIHByaXZhdGUgZmluYWwgQXJyYXlMaXN0PEludGVnZXI+IGxvZ2dlZENvZGVzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgIHByaXZhdGUgZmluYWwgQXJyYXlMaXN0TXVsdGltYXA8Vm9pZCwgVm9pZD4gbG9nZ2VkTGF0ZW5jaWVzID0gQXJyYXlMaXN0TXVsdGltYXAuY3JlYXRlKCk7CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGxvZ0V2ZW50U2FtcGxlZChpbnQgZXZlbnRDb2RlKSB7CisgICAgbG9nZ2VkQ29kZXMuYWRkKGV2ZW50Q29kZSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nRXZlbnRTYW1wbGVkKAorICAgICAgaW50IGV2ZW50Q29kZSwKKyAgICAgIFN0cmluZyBmaWxlR3JvdXBOYW1lLAorICAgICAgaW50IGZpbGVHcm91cFZlcnNpb25OdW1iZXIsCisgICAgICBsb25nIGJ1aWxkSWQsCisgICAgICBTdHJpbmcgdmFyaWFudElkKSB7CisgICAgbG9nZ2VkQ29kZXMuYWRkKGV2ZW50Q29kZSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nRXZlbnRBZnRlclNhbXBsZShpbnQgZXZlbnRDb2RlLCBpbnQgc2FtcGxlSW50ZXJ2YWwpIHsKKyAgICBsb2dnZWRDb2Rlcy5hZGQoZXZlbnRDb2RlKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBsb2dNZGRGaWxlR3JvdXBTdGF0cygKKyAgICAgIEFzeW5jQ2FsbGFibGU8TGlzdDxGaWxlR3JvdXBTdGF0dXNXaXRoRGV0YWlscz4+IGJ1aWxkRmlsZUdyb3VwU3RhdHMpIHsKKyAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlRoaXMgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCBpbiB0aGUgZmFrZSB5ZXQuIikpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGxvZ01kZEFwaUNhbGxTdGF0cyhWb2lkIGZpbGVHcm91cERldGFpbHMsIFZvaWQgYXBpQ2FsbFN0YXRzKSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJUaGlzIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQgaW4gdGhlIGZha2UgeWV0LiIpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGxvZ01kZFN0b3JhZ2VTdGF0cyhBc3luY0NhbGxhYmxlPFZvaWQ+IGJ1aWxkTWRkU3RvcmFnZVN0YXRzKSB7CisgICAgcmV0dXJuIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJUaGlzIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQgaW4gdGhlIGZha2UgeWV0LiIpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBsb2dNZGROZXR3b3JrU3RhdHMoQXN5bmNDYWxsYWJsZTxWb2lkPiBidWlsZE1kZE5ldHdvcmtTdGF0cykgeworICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgIG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkIGluIHRoZSBmYWtlIHlldC4iKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nTWRkRGF0YURvd25sb2FkRmlsZUV4cGlyYXRpb25FdmVudChpbnQgZXZlbnRDb2RlLCBpbnQgY291bnQpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlRoaXMgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCBpbiB0aGUgZmFrZSB5ZXQuIik7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nTWRkTmV0d29ya1NhdmluZ3MoCisgICAgICBWb2lkIGZpbGVHcm91cERldGFpbHMsCisgICAgICBpbnQgY29kZSwKKyAgICAgIGxvbmcgZnVsbEZpbGVTaXplLAorICAgICAgbG9uZyBkb3dubG9hZGVkRmlsZVNpemUsCisgICAgICBTdHJpbmcgZmlsZUlkLAorICAgICAgaW50IGRlbHRhSW5kZXgpIHsKKyAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oIlRoaXMgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCBpbiB0aGUgZmFrZSB5ZXQuIik7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nTWRkRG93bmxvYWRSZXN1bHQoaW50IGNvZGUsIFZvaWQgZmlsZUdyb3VwRGV0YWlscykgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkIGluIHRoZSBmYWtlIHlldC4iKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dNZGRRdWVyeVN0YXRzKFZvaWQgZmlsZUdyb3VwRGV0YWlscykgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkIGluIHRoZSBmYWtlIHlldC4iKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2dNZGRBbmRyb2lkU2hhcmluZ0xvZyhWb2lkIGV2ZW50KSB7CisgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJUaGlzIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQgaW4gdGhlIGZha2UgeWV0LiIpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGxvZ01kZERvd25sb2FkTGF0ZW5jeShWb2lkIGZpbGVHcm91cFN0YXRzLCBWb2lkIGRvd25sb2FkTGF0ZW5jeSkgeworICAgIGxvZ2dlZExhdGVuY2llcy5wdXQoZmlsZUdyb3VwU3RhdHMsIGRvd25sb2FkTGF0ZW5jeSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgbG9nTWRkVXNhZ2VFdmVudChWb2lkIGZpbGVHcm91cERldGFpbHMsIFZvaWQgdXNhZ2VFdmVudExvZykgeworICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkIGluIHRoZSBmYWtlIHlldC4iKTsKKyAgfQorCisgIHB1YmxpYyBMaXN0PEludGVnZXI+IGdldExvZ2dlZENvZGVzKCkgeworICAgIHJldHVybiBsb2dnZWRDb2RlczsKKyAgfQorCisgIHB1YmxpYyBBcnJheUxpc3RNdWx0aW1hcDxWb2lkLCBWb2lkPiBnZXRMb2dnZWRMYXRlbmNpZXMoKSB7CisgICAgcmV0dXJuIGxvZ2dlZExhdGVuY2llczsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90by9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG8vQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDZmMGM5ZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG8vQlVJTEQKQEAgLTAsMCArMSwzNCBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworcHJvdG9fbGlicmFyeSgKKyAgICBuYW1lID0gIm1ldGFkYXRhX3Byb3RvIiwKKyAgICBzcmNzID0gWyJtZXRhZGF0YS5wcm90byJdLAorICAgIGNjX2FwaV92ZXJzaW9uID0gMiwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1fcHJvdG8iLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzphbnlfcHJvdG8iLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzp0aW1lc3RhbXBfcHJvdG8iLAorICAgIF0sCisgICAgYWx3YXlzbGluayA9IDEsCispCisKK2phdmFfbGl0ZV9wcm90b19saWJyYXJ5KAorICAgIG5hbWUgPSAibWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICBkZXBzID0gWyI6bWV0YWRhdGFfcHJvdG8iXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG8vbWV0YWRhdGEucHJvdG8gYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvL21ldGFkYXRhLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNhYjhhMGYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvL21ldGFkYXRhLnByb3RvCkBAIC0wLDAgKzEsNjczIEBACisvLyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisvLworLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisvLyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisvLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKy8vCisvLyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorLy8KKy8vIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKy8vIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisvLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKy8vIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKy8vIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorLy8gVGhlIG1haW4gcHVycG9zZSBvZiBtaXJyb3JpbmcgZXh0ZXJuYWwgcHJvdG9zIGhlcmUgaXMgdG8gc2VwYXJhdGUgQVBJIGFuZAorLy8gc3RvcmFnZSBwcm90b3MuIFRoZSBzYW1lIHRhZyBudW1iZXJzIGFyZSB1c2VkIGZvciBtYWtpbmcgbWlncmF0aW9uIHdvcmsuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIG1kaS5kb3dubG9hZC5pbnRlcm5hbDsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvYW55LnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wcm90byI7CitpbXBvcnQgInByb3RvL3RyYW5zZm9ybS5wcm90byI7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwiOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIk1ldGFkYXRhUHJvdG8iOworCisvLyBNaXJyb3JzIG1kaS5kb3dubG9hZC5FeHRyYUh0dHBIZWFkZXIKKy8vCisvLyBIVFRQIGhlYWRlcnMgYXJlIGRlc2NyaWJlZCBpbiBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNzIzMCNzZWN0aW9uLTMuMgorLy8gYXMga2V5OnZhbHVlLCB3aGVyZSB0aGUgdmFsdWUgbWF5IGhhdmUgYSB3aGl0ZXNwYWNlIG9uIGVhY2ggZW5kLgorbWVzc2FnZSBFeHRyYUh0dHBIZWFkZXIgeworICBvcHRpb25hbCBzdHJpbmcga2V5ID0gMTsKKyAgb3B0aW9uYWwgc3RyaW5nIHZhbHVlID0gMjsKK30KKworLy8gVGhpcyBwcm90byBpcyB1c2VkIHRvIHN0b3JlIGZpbGUgZ3JvdXAgbWV0YWRhdGEgb24gZGlzayBmb3IgaW50ZXJuYWwgdXNlLiBJdAorLy8gY29uc2lzdHMgb2YgYWxsIGZpZWxkcyBtaXJyb3JlZCBmcm9tIERhdGFGaWxlR3JvdXAgYW5kIGFuIGV4dHJhIGZpZWxkIGZvcgorLy8gYm9va2tlZXBpbmcuCisvLworLy8gVGhlIHRhZyBudW1iZXIgb2YgZXh0cmEgZmllbGRzIHNob3VsZCBzdGFydCBmcm9tIDEwMDAgdG8gcmVzZXJ2ZSByb29tIGZvcgorLy8gZ3Jvd2luZyBEYXRhRmlsZUdyb3VwLgorLy8KKy8vIE5leHQgaWQ6IDEwMDAKK21lc3NhZ2UgRGF0YUZpbGVHcm91cEludGVybmFsIHsKKyAgLy8gRXh0cmEgaW5mb3JtYXRpb24gdGhhdCBpcyBrZXB0IG9uIGRpc2suCisgIC8vCisgIC8vIFRoZSBleHRlbnNpb24gd2FzIG9yaWdpbmFsbHkgaW50cm9kdWNlZCBpbiBjbC8yNDg4MTM5NjYuIFdlIGFyZSBtaWdyYXRpbmcKKyAgLy8gYXdheSBmcm9tIHRoZSBleHRlbnNpb24uIEhvd2V2ZXIsIHdlIHN0aWxsIG5lZWQgdG8gcmVhZCBmcm9tIGZpZWxkcyBpbiB0aGUKKyAgLy8gZXh0ZW5zaW9uLiBSZXVzZSB0aGUgc2FtZSB0YWcgbnVtYmVyIGFzIHRoZSBleHRlbnNpb24gbnVtYmVyIHRvIHJlYWQgZnJvbQorICAvLyB0aGUgZXh0ZW5zaW9uLgorICBvcHRpb25hbCBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcgYm9va2tlZXBpbmcgPSAyNDg4MTM5NjY7CisKKyAgLy8gVW5pcXVlIG5hbWUgdG8gaWRlbnRpZnkgdGhlIGdyb3VwLiBJdCBzaG91bGQgYmUgdW5pcXVlIHBlciBvd25lciBwYWNrYWdlLgorICAvLyBJbiBHTVNDb3JlLCB1c2UgdGhlIG1vZHVsZSBuYW1lIGFzIHRoZSBwcmVmaXggb2YgdGhlIGdyb3VwIG5hbWUuCisgIC8vCisgIC8vIEV4OiBBIGdyb3VwIG5hbWUgaW4gbWRpc3luYyBtb2R1bGUgY291bGQgYmUgbmFtZWQ6IG1kaXN5bmMtcHJvZmlsZS1waG90b3MuCisgIC8vCisgIC8vIFRoaXMgc2hvdWxkbid0IGlkZWFsbHkgYmUgc29tZXRoaW5nIGxpa2UgImNvbmZpZyIsIGFuZAorICAvLyBpbnN0ZWFkIHNob3VsZCBiZXR0ZXIgZGVmaW5lIHRoZSBmZWF0dXJlIGl0IHdpbGwgYmUgdXNlZCBmb3IuCisgIC8vCisgIC8vIEV4OiAiaWNpbmctbGFuZ3VhZ2UtZGV0ZWN0aW9uLW1vZGVsIiwgInNtYXJ0LWFjdGlvbi1kZXRlY3Rpb24tbW9kZWwiCisgIG9wdGlvbmFsIHN0cmluZyBncm91cF9uYW1lID0gMTsKKworICAvLyBUaGUgbmFtZSBvZiB0aGUgcGFja2FnZSB0aGF0IG93bnMgdGhpcyBncm91cC4gSWYgdGhpcyBmaWVsZCBpcyBsZWZ0IGVtcHR5LAorICAvLyB0aGUgb3duZXIgaXMgYXNzdW1lZCB0byBiZSB0aGUgcGFja2FnZSBuYW1lIG9mIHRoZSBob3N0IGFwcC4KKyAgLy8KKyAgLy8gVGhlIGZpbGVzIHdpbGwgb25seSBiZSBkb3dubG9hZGVkIG9udG8gdGhlIGRldmljZSBpZiB0aGUgb3duZXIgcGFja2FnZSBpcworICAvLyBwcmVzZW50IG9uIHRoZSBkZXZpY2UuCisgIC8vCisgIC8vIEV4OiAiY29tLmdvb2dsZS5hbmRyb2lkLmdtcyIsICJjb20uZ29vZ2xlLmFuZHJvaWQuYXBwcy5idWdsZSIKKyAgb3B0aW9uYWwgc3RyaW5nIG93bmVyX3BhY2thZ2UgPSA2OworCisgIC8vIENsaWVudCBzZXQgdmVyc2lvbiBudW1iZXIgdXNlZCB0byBpZGVudGlmeSB0aGUgZmlsZSBncm91cC4KKyAgLy8KKyAgLy8gTm90ZSB0aGF0IHRoaXMgZG9lcyBub3QgdW5pcXVlbHkgaWRlbnRpZnkgdGhlIGNvbnRlbnRzIG9mIHRoZSBmaWxlIGdyb3VwLgorICAvLyBJdCBzaW1wbHkgcmVmbGVjdHMgYSBzbmFwc2hvdCBvZiBjbGllbnQgY29uZmlnIGNoYW5nZXMuCisgIC8vIEZvciBleGFtcGxlOiBzYXkgdGhlcmUncyBhIGZpbGUgZ3JvdXAgJ2xhbmd1YWdlLWRldGVjdG9yLW1vZGVsJyB0aGF0CisgIC8vIGRvd25sb2FkcyBhIGRpZmZlcmVudCBmaWxlIHBlciB1c2VyIGxvY2FsZS4KKyAgLy8gZGF0YV9maWxlX2dyb3VwIHsKKyAgLy8gICBmaWxlX2dyb3VwX25hbWUgPSAnbGFuZ3VhZ2UtZGV0ZWN0b3ItbW9kZWwnCisgIC8vICAgZmlsZV9ncm91cF92ZXJzaW9uX251bWJlciA9IDEKKyAgLy8gICBmaWxlIHsKKyAgLy8gICAgICB1cmwgPSAnZW4tbW9kZWwnCisgIC8vICAgfQorICAvLyB9CisgIC8vIGRhdGFfZmlsZV9ncm91cCB7CisgIC8vICAgZmlsZV9ncm91cF9uYW1lID0gJ2xhbmd1YWdlLWRldGVjdG9yLW1vZGVsJworICAvLyAgIGZpbGVfZ3JvdXBfdmVyc2lvbl9udW1iZXIgPSAxCisgIC8vICAgZmlsZSB7CisgIC8vICAgICAgdXJsID0gJ2VzLW1vZGVsJworICAvLyAgIH0KKyAgLy8gfQorICAvLyBOb3RlIHRoYXQgZXZlbiB0aG91Z2ggdGhlIGFjdHVhbCBjb250ZW50cyBvZiB0aGUgZmlsZSBncm91cCBhcmUgZGlmZmVyZW50CisgIC8vIGZvciBlYWNoIGxvY2FsZSwgdGhlIHZlcnNpb24gaXMgdGhlIHNhbWUgYmVjYXVzZSB0aGlzIGNvbmZpZyB3YXMgcHVzaGVkCisgIC8vIGF0IHRoZSBzYW1lIHNuYXBzaG90LgorICAvLworICAvLyBBdmFpbGFibGUgR01TIHYxOCsuCisgIG9wdGlvbmFsIGludDMyIGZpbGVfZ3JvdXBfdmVyc2lvbl9udW1iZXIgPSAxMDsKKworICAvLyBERVBSRUNBVEVECisgIC8vIE1ERCB0ZWFtIHJlY29tbWVuZHMgdG8gdXNlIGV4cGxpY2l0IHByb3BlcnRpZXMgaW5zdGVhZC4KKyAgb3B0aW9uYWwgZ29vZ2xlLnByb3RvYnVmLkFueSBjdXN0b21fcHJvcGVydHkgPSAyMCBbZGVwcmVjYXRlZCA9IHRydWVdOworCisgIC8vIEN1c3RvbSBtZXRhZGF0YSBhdHRhY2hlZCB0byB0aGUgZmlsZSBncm91cC4KKyAgLy8KKyAgLy8gVGhpcyBhbGxvd3MgY2xpZW50cyB0byBpbmNsdWRlIHNwZWNpZmljIG1ldGFkYXRhIGFib3V0IHRoZSBncm91cCBmb3IgdGhlaXIKKyAgLy8gb3duIHByb2Nlc3NpbmcgcHVycG9zZXMuIFRoZSBtZXRhZGF0YSB3aWxsIGJlIHN0b3JlZCB3aXRoIHRoZSBncm91cCBhbmQKKyAgLy8gYWNjZXNzaWJsZSB3aGVuIHRoZSBmaWxlIGdyb3VwIGlzIHJldHJpZXZlZC4KKyAgLy8KKyAgLy8gVGhpcyBwcm9wZXJ0eSBzaG91bGQgb25seSBiZSB1c2VkIGlmIGFic29sdXRlbHkgbmVjZXNzYXJ5LiBQbGVhc2UgY29uc3VsdAorICAvLyB3aXRoIDxpbnRlcm5hbD5AIGlmIHlvdSBoYXZlIHF1ZXN0aW9ucyBhYm91dCB0aGlzIHByb3BlcnR5IG9yIGEgcG90ZW50aWFsCisgIC8vIHVzZS1jYXNlLgorICBvcHRpb25hbCBnb29nbGUucHJvdG9idWYuQW55IGN1c3RvbV9tZXRhZGF0YSA9IDI3OworCisgIHJlc2VydmVkIDIxOworCisgIC8vIE1pcnJvcnMgbWRpLmRvd25sb2FkLkRhdGFGaWxlR3JvdXAuQWxsb3dlZFJlYWRlcnMKKyAgZW51bSBBbGxvd2VkUmVhZGVycyB7CisgICAgQUxMX0dPT0dMRV9BUFBTID0gMDsKKyAgICBPTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTID0gMTsKKyAgICBBTExfQVBQUyA9IDI7CisgIH0KKworICAvLyBEZWZpbmVzIHdobyBpcyBhbGxvd2VkIHRvIHJlYWQgdGhpcyBmaWxlIGdyb3VwLiBDdXJyZW50bHkgdGhlIG9wdGlvbnMgYXJlOgorICAvLworICAvLyBBTExfR09PR0xFX0FQUFM6IGFjY2Vzc2libGUgdG8gYWxsIEdvb2dsZSAxcCBBcHBzLgorICAvLyBPTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTOiBhY2Nlc3NpYmxlIHRvIG9ubHkgR01TIENvcmUuCisgIC8vCisgIC8vIElmIHRoaXMgZmllbGQgaXMgbm90IGV4cGxpY2l0bHkgc2V0IGl0IGRlZmF1bHRzIHRvICJBTExfR09PR0xFX0FQUFMiLgorICAvLworICAvLyBBdmFpbGFibGUgR01TIHYyMCsuCisgIG9wdGlvbmFsIEFsbG93ZWRSZWFkZXJzIGFsbG93ZWRfcmVhZGVyc19lbnVtID0gMTI7CisKKyAgLy8gTGVuZ3RoIG9mIHRpbWUgKGluIHNlY29uZHMpIGZvciB3aGljaCBhIGZpbGUgZ3JvdXAgdmVyc2lvbiB3aWxsIGxpdmUgYWZ0ZXIKKyAgLy8gc2luY2UgYSBuZXdlciB2ZXJzaW9uIGJlY2FtZSBmdWxseSBkb3dubG9hZGVkLiBDbGllbnRzIHNob3VsZCBzZXQgdGhpcyB0aW1lCisgIC8vIHRvIGJlIG1vcmUgdGhhbiB0aGUgdGltZSBpbiB3aGljaCB0aGV5IGNhbGwgTUREIHRvIHJlZnJlc2ggdGhlaXIgZGF0YS4KKyAgLy8gTk9URTogTUREIHdpbGwgZGVsZXRlIHRoZSBmaWxlIGdyb3VwIHZlcnNpb24gd2l0aGluIGEgZGF5IG9mIHRoaXMgdGltZS4KKyAgLy8gRXg6IDE3MjgwMCAgLy8gMiBEYXlzCisgIG9wdGlvbmFsIGludDY0IHN0YWxlX2xpZmV0aW1lX3NlY3MgPSAzOworCisgIC8vIFRoZSB0aW1lc3RhbXAgYXQgd2hpY2ggdGhpcyBmaWxlZ3JvdXAgc2hvdWxkIGJlIGRlbGV0ZWQsIGV2ZW4gaWYgaXQgaXMKKyAgLy8gc3RpbGwgYWN0aXZlLCBzcGVjaWZpZWQgaW4gc2Vjb25kcyBzaW5jZSBlcG9jaC4KKyAgLy8gTk9URTogTUREIHdpbGwgZGVsZXRlIHRoZSBmaWxlIGdyb3VwIHZlcnNpb24gd2l0aGluIGEgZGF5IG9mIHRoaXMgdGltZS4KKyAgb3B0aW9uYWwgaW50NjQgZXhwaXJhdGlvbl9kYXRlX3NlY3MgPSAxMTsKKworICAvLyBTcGVjaWZ5IHRoZSBjb25kaXRpb25zIHVuZGVyIHdoaWNoIHRoZSBmaWxlIGdyb3VwIHNob3VsZCBiZSBkb3dubG9hZGVkLgorICBvcHRpb25hbCBEb3dubG9hZENvbmRpdGlvbnMgZG93bmxvYWRfY29uZGl0aW9ucyA9IDEzOworCisgIC8vIFNldHRpbmcgdGhpcyBmbGFnIHRvIHRydWUgd2lsbCBtZWFuIHRoYXQgdGhlIGRvd25sb2FkZWQgZmlsZXMgd2lsbCBhcHBlYXIKKyAgLy8gdG8gYmUgaW4gYSBkaXJlY3RvcnkgYnkgdGhlbXNlbHZlcy4KKyAgLy8gVGhlIGZpbGUgbmFtZS9maWxlIHBhdGggb2YgdGhlIGV4cG9zZWQgZmlsZSB3aWxsIGJlIHRoZSBmaWxlbmFtZSBzZXQgaW4gdGhlCisgIC8vIGZpbGUucmVsYXRpdmVfZmlsZV9wYXRoIGZpZWxkLCBPUiBpZiB0aGF0IGZpZWxkIGlzIGVtcHR5LCB0aGUgZmlsZSBuYW1lCisgIC8vIGZyb20gdGhlIGZpbGUudXJsX3RvX2Rvd25sb2FkIGZpZWxkLiBUaGlzIGVuYWJsZXMgZG93bmxvYWRlZCBmaWxlcyB0byByZWZlcgorICAvLyB0byBlYWNoIG90aGVyIGJ5IG5hbWUuCisgIC8vIEl0J3MgaW52YWxpZCB0byBzZXQgdGhpcyBmbGFnIHRvIHRydWUgaWYgdHdvIGZpbGVzIGVuZCB1cCB3aXRoIHRoZSBzYW1lCisgIC8vIGZpbGUgcGF0aC4KKyAgLy8gVmFsaWQgb24gaU9TLCBjTURELCBhbmQgYU1ERC4KKyAgLy8KKyAgLy8gTk9URTogRm9yIGFNREQsIHRoaXMgZmVhdHVyZSBpcyBub3QgYXZhaWxhYmxlIGlmIEFuZHJvaWQgQmxvYiBTaGFyaW5nIGlzCisgIC8vIGVuYWJsZWQgb3IgaWYgdXNpbmcgYW4gQVBJIGxldmVsIGJlbG93IDIxIChMKS4gSWYgZWl0aGVyIGNhc2UgaXMgdHJ1ZSwgdGhpcworICAvLyBvcHRpb24gd2lsbCBiZSBpZ25vcmVkLgorICBvcHRpb25hbCBib29sIHByZXNlcnZlX2ZpbGVuYW1lc19hbmRfaXNvbGF0ZV9maWxlcyA9IDE0OworCisgIC8vIExpc3Qgb2YgZmlsZXMgaW4gdGhlIGdyb3VwLgorICByZXBlYXRlZCBEYXRhRmlsZSBmaWxlID0gMjsKKworICAvLyBUYWcgZm9yIHRoZSBuZXR3b3JrIHRyYWZmaWMgdG8gZG93bmxvYWQgdGhpcyBmaWxlIGdyb3VwLgorICAvLyBUYWcgc3BhY2UgaXMgZGV0ZXJtaW5lZCBieSB0aGUgaG9zdCBhcHAuCisgIC8vIEZvciBHbXNjb3JlLCB0aGUgdGFnIHNob3VsZCBjb21lIGZyb206CisgIC8vIDxpbnRlcm5hbD4KKyAgb3B0aW9uYWwgaW50MzIgdHJhZmZpY190YWcgPSAxNjsKKworICAvLyBFeHRyYSBIVFRQIGhlYWRlcnMgdG8gYXBwbHkgd2hlbiBkb3dubG9hZGluZyBhbGwgZmlsZXMgaW4gdGhlIGdyb3VwLgorICByZXBlYXRlZCBFeHRyYUh0dHBIZWFkZXIgZ3JvdXBfZXh0cmFfaHR0cF9oZWFkZXJzID0gMTc7CisKKyAgcmVzZXJ2ZWQgMTk7CisKKyAgLy8gVW5pcXVlIGlkZW50aWZpZXIgb2YgYSBEYXRhRmlsZUdyb3VwIGNvbmZpZyAoaS5lLiBhICJzbmFwc2hvdCIpIGNyZWF0ZWQKKyAgLy8gd2hlbiB1c2luZyBNREQgSW5ncmVzcyBBUEkuCisgIG9wdGlvbmFsIGludDY0IGJ1aWxkX2lkID0gMjM7CisKKyAgLy8gQSBmaW5nZXJwcmludCBhbGxvd2luZyBjbGllbnRzIHRvIGlkZW50aWZ5IGEgRGF0YUZpbGVHcm91cAorICAvLyBjb25maWcgYmFzZWQgb24gYSBnaXZlbiBzZXQgb2YgcHJvcGVydGllcyAoaS5lLiBhICJwYXJ0aXRpb24iIG9mCisgIC8vIGFueSBmaWxlIGdyb3VwIHByb3BlcnRpZXMpLiBUaGlzIGNhbiBiZSB1c2VkIGJ5IGNsaWVudHMgYXMgYW4gZXhhY3QgbWF0Y2gKKyAgLy8gZm9yIGEgY2xhc3Mgb2YgRGF0YUZpbGVHcm91cHMgZHVyaW5nIHRhcmdldGluZyBvciBhcyBhIGNvbXBhdGliaWxpdHkgY2hlY2suCisgIG9wdGlvbmFsIHN0cmluZyB2YXJpYW50X2lkID0gMjY7CisKKyAgLy8gVGhlIGxvY2FsZXMgY29tcGF0aWJsZSB3aXRoIHRoZSBmaWxlIGdyb3VwLiBUaGlzIGNhbiBiZSBkaWZmZXJlbnQgZnJvbSB0aGUKKyAgLy8gZGV2aWNlIGxvY2FsZS4KKyAgLy8KKyAgLy8gVmFsdWVzIGluIHRoaXMgbGlzdCBtYXkgYmUgZXhhY3QgbG9jYWxlcyAoZS5nLiAiZW4tVVMiKSBvciBsYW5ndWFnZS1vbmx5CisgIC8vICgiZW4tKiIpLgorICAvLyBFeGFtcGxlIDE6IGxvY2FsZSA9IFsiZW4tVVMiXTsgLy8gY29tcGF0aWJsZSB3aXRoICJlbi1VUyIgb25seQorICAvLyBFeGFtcGxlIDI6IGxvY2FsZSA9IFsiZW4tVVMiLCAiZW4tQ0EiXTsgLy8gY29tcGF0aWJsZSB3aXRoICJlbi1VUyIgb3IKKyAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICJlbi1DQSIKKyAgLy8gRXhhbXBsZSAzOiBsb2NhbGUgPSBbImVuLSoiXTsgLy8gY29tcGF0aWJsZSB3aXRoIGFsbCAiZW4iIGxvY2FsZXMKKyAgcmVwZWF0ZWQgc3RyaW5nIGxvY2FsZSA9IDI1OworCisgIHJlc2VydmVkIDI4OworCisgIHJlc2VydmVkIDQsIDUsIDcsIDgsIDksIDE1LCAxOCwgMjIsIDI0OworfQorCisvLyBNaXJyb3JzIG1kaS5kb3dubG9hZC5EYXRhRmlsZQorLy8KKy8vIEEgZGF0YSBmaWxlIHJlcHJlc2VudHMgYWxsIHRoZSBtZXRhZGF0YSB0byBkb3dubG9hZCB0aGUgZmlsZSBhbmQgdGhlbgorLy8gbWFuYWdlIGl0IG9uIHRoZSBkZXZpY2UuCisvLyBOZXh0IHRhZzogMjIKKy8vCisvLyBUaGlzIHNob3VsZCBub3QgY29udGFpbiBhbnkgZmllbGRzIHRoYXQgYXJlIG1hcmtlZCBpbnRlcm5hbCwgYXMgd2UgY29tcGFyZQorLy8gdGhlIHByb3RvcyBkaXJlY3RseSB0byBkZWNpZGUgaWYgaXQgaXMgYSBuZXcgdmVyc2lvbiBvZiB0aGUgZmlsZS4KKy8vIExJTlQuSWZDaGFuZ2UoZGF0YV9maWxlKQorbWVzc2FnZSBEYXRhRmlsZSB7CisgIC8vIEEgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGZpbGUgd2l0aGluIHRoZSBncm91cCwgdGhhdCBjYW4gYmUgdXNlZCB0bworICAvLyBnZXQgdGhpcyBmaWxlIGZyb20gdGhlIGdyb3VwLgorICAvLyBFeDogImxhbmd1YWdlLWRldGVjdGlvbi1tb2RlbCIKKyAgb3B0aW9uYWwgc3RyaW5nIGZpbGVfaWQgPSA3OworCisgIC8vIFVybCBmcm9tIHdoZXJlIHRoZSBmaWxlIGlzIHRvIGJlIGRvd25sb2FkZWQuCisgIC8vIEV4OiBodHRwczovL3d3dy5nc3RhdGljLmNvbS9ncm91cC1uYW1lL21vZGVsXzEyMzQuemlwCisgIG9wdGlvbmFsIHN0cmluZyB1cmxfdG9fZG93bmxvYWQgPSAyOworCisgIC8vIEV4YWN0IHNpemUgb2YgdGhlIGZpbGUuIFRoaXMgaXMgdXNlZCB0byBjaGVjayBpZiB0aGVyZSBpcyBzcGFjZSBhdmFpbGFibGUKKyAgLy8gZm9yIHRoZSBmaWxlIGJlZm9yZSBzY2hlZHVsaW5nIHRoZSBkb3dubG9hZC4KKyAgLy8gVGhlIGJ5dGVfc2l6ZSBpcyBvcHRpb25hbC4gSWYgbm90IHNldCwgTUREIHdpbGwgdHJ5IHdpdGggYmVzdCBlZmZvcnQgdG8gZ2V0CisgIC8vIHRoZSBmaWxlIHNpemUgdXNpbmcgdGhlIEhUVFAgSEVBRCByZXF1ZXN0LgorICBvcHRpb25hbCBpbnQzMiBieXRlX3NpemUgPSA0OworCisgIC8vIEVudW0gZm9yIGNoZWNrc3VtIHR5cGVzLgorICAvLyBOT1RFOiBkbyBub3QgYWRkIGFueSBuZXcgY2hlY2tzdW0gdHlwZSBoZXJlLCBvbGRlciBNREQgdmVyc2lvbnMgd291bGQgYnJlYWsKKyAgLy8gb3RoZXJ3aXNlLgorICBlbnVtIENoZWNrc3VtVHlwZSB7CisgICAgLy8gRGVmYXVsdCBjaGVja3N1bSBpcyBTSEExLgorICAgIERFRkFVTFQgPSAwOworCisgICAgLy8gTm8gY2hlY2tzdW0gaXMgcHJvdmlkZWQuCisgICAgTk9ORSA9IDE7CisKKyAgICByZXNlcnZlZCAyIC8qIFNIQTI1NiAqLzsKKyAgfQorCisgIG9wdGlvbmFsIENoZWNrc3VtVHlwZSBjaGVja3N1bV90eXBlID0gMTU7CisKKyAgLy8gU0hBMSBjaGVja3N1bSB0byB2ZXJpZnkgdGhlIGZpbGUgYmVmb3JlIGl0IGNhbiBiZSB1c2VkLiBUaGlzIGlzIGFsc28gdXNlZAorICAvLyB0byBkZS1kdXBsaWNhdGUgZmlsZXMgYmV0d2VlbiBkaWZmZXJlbnQgZ3JvdXBzLgorICAvLyBGb3IgbW9zdCBmaWxlcywgdGhpcyB3aWxsIGJlIHRoZSBjaGVja3N1bSBvZiB0aGUgZmlsZSBiZWluZyBkb3dubG9hZGVkLgorICAvLyBGb3IgZmlsZXMgd2l0aCBkb3dubG9hZF90cmFuc2Zvcm0sIHRoaXMgc2hvdWxkIGNvbnRhaW4gdGhlIHRyYW5zZm9ybSBvZgorICAvLyB0aGUgZmlsZSBhZnRlciB0aGUgdHJhbnNmb3JtcyBoYXZlIGJlZW4gYXBwbGllZC4KKyAgLy8gVGhlIGNoZWNrc3VtIGlzIG9wdGlvbmFsLiBJZiBub3Qgc2V0LCB0aGUgY2hlY2tzdW1fdHlwZSBtdXN0IGJlCisgIC8vIENoZWNrc3VtVHlwZS5OT05FLgorICBvcHRpb25hbCBzdHJpbmcgY2hlY2tzdW0gPSA1OworCisgIC8vIFRoZSBmb2xsb3dpbmcgYXJlIDxpbnRlcm5hbD4gdHJhbnNmb3JtcyB0byBhcHBseSB0byB0aGUgZG93bmxvYWRlZCBmaWxlcy4KKyAgLy8gVHJhbnNmb3JtcyBhcmUgYmktZGlyZWN0aW9uYWwgYW5kIGRlZmluZWQgaW4gdGVybXMgb2Ygd2hhdCB0aGV5IGRvIG9uCisgIC8vIHdyaXRlLiBTaW5jZSB0aGVzZSB0cmFuc2Zvcm1zIGFyZSBhcHBsaWVkIHdoaWxlIHJlYWRpbmcsIHRoZWlyCisgIC8vIGRpcmVjdGlvbmFsaXR5IGlzIHJldmVyc2VkLiBFZywgeW91J2xsIHNlZSAnY29tcHJlc3MnIHRvIGluZGljYXRlIHRoYXQgdGhlCisgIC8vIGZpbGUgc2hvdWxkIGJlIGRlY29tcHJlc3NlZC4KKworICAvLyBUaGVzZSB0cmFuc2Zvcm1zIGFyZSBhcHBsaWVkIG9uY2UgYnkgTUREIGFmdGVyIGRvd25sb2FkaW5nIHRoZSBmaWxlLgorICAvLyBDdXJyZW50bHkgb25seSBjb21wcmVzcyBpcyBhdmFpbGFibGUuCisgIC8vIFZhbGlkIG9uIEFuZHJvaWQuIGlPUyBzdXBwb3J0IGlzIHRyYWNrZWQgYnkgYi8xMTg4MjgwNDUuCisgIG9wdGlvbmFsIG1vYnN0b3JlLnByb3RvLlRyYW5zZm9ybXMgZG93bmxvYWRfdHJhbnNmb3JtcyA9IDExOworCisgIC8vIElmIERhdGFGaWxlIGhhcyBkb3dubG9hZF90cmFuc2Zvcm1zLCB0aGlzIGZpZWxkIG11c3QgYmUgcHJvdmlkZWQgd2l0aCB0aGUKKyAgLy8gU0hBMSBjaGVja3N1bSBvZiB0aGUgZmlsZSBiZWZvcmUgYW55IHRyYW5zZm9ybSBhcmUgYXBwbGllZC4gVGhlIG9yaWdpbmFsCisgIC8vIGNoZWNrc3VtIHdvdWxkIGFsc28gYmUgY2hlY2tlZCBhZnRlciB0aGUgZG93bmxvYWRfdHJhbnNmb3JtcyBhcmUgYXBwbGllZC4KKyAgb3B0aW9uYWwgc3RyaW5nIGRvd25sb2FkZWRfZmlsZV9jaGVja3N1bSA9IDE0OworCisgIC8vIEV4YWN0IHNpemUgb2YgdGhlIGRvd25sb2FkZWQgZmlsZS4gSWYgdGhlIERhdGFGaWxlIGhhcyBkb3dubG9hZCB0cmFuc2Zvcm1zCisgIC8vIGxpa2UgY29tcHJlc3MgYW5kIHppcCwgdGhlIGRvd25sb2FkZWQgZmlsZSBzaXplIHdvdWxkIGJlIGRpZmZlcmVudCB0aGFuCisgIC8vIHRoZSBmaW5hbCBmaWxlIHNpemUgb24gZGlzay4gQ2xpZW50IGNvdWxkIHVzZQorICAvLyB0aGlzIGZpZWxkIHRvIHRyYWNrIHRoZSBkb3dubG9hZGVkIGZpbGUgc2l6ZSBhbmQgY2FsY3VsYXRlIHRoZSBkb3dubG9hZAorICAvLyBwcm9ncmVzcyBwZXJjZW50YWdlLiBUaGlzIGZpZWxkIGlzIG5vdCB1c2VkIGJ5IE1ERCBjdXJyZW50bHkuCisgIG9wdGlvbmFsIGludDMyIGRvd25sb2FkZWRfZmlsZV9ieXRlX3NpemUgPSAxNjsKKworICAvLyBUaGVzZSB0cmFuc2Zvcm1zIGFyZSBldmFsdWF0ZWQgYnkgdGhlIGNhbGxlciBvbi10aGUtZmx5IHdoZW4gcmVhZGluZyB0aGUKKyAgLy8gZGF0YSB3aXRoIE1vYlN0b3JlLiBBbnkgdHJhbnNmb3JtcyBpbnN0YWxsZWQgaW4gdGhlIGNhbGxlcidzIE1vYlN0b3JlCisgIC8vIGluc3RhbmNlIGlzIGF2YWlsYWJsZS4KKyAgLy8gVmFsaWQgb24gQW5kcm9pZC4gaU9TIHN1cHBvcnQgaXMgdHJhY2tlZCBieSBiLzExODc1OTI1NC4KKyAgb3B0aW9uYWwgbW9ic3RvcmUucHJvdG8uVHJhbnNmb3JtcyByZWFkX3RyYW5zZm9ybXMgPSAxMjsKKworICAvLyBMaXN0IG9mIGRlbHRhIGZpbGVzIHRoYXQgY2FuIGJlIGVuY29kZWQgYW5kIGRlY29kZWQgd2l0aCBiYXNlIGZpbGVzLgorICAvLyBJZiB0aGUgZGV2aWNlIGhhcyBhbnkgYmFzZSBmaWxlLCB0aGUgZGVsdGEgZmlsZSB3aGljaCBpcyBtdWNoCisgIC8vIHNtYWxsZXIgd2lsbCBiZSBkb3dubG9hZGVkIGluc3RlYWQgb2YgdGhlIGZ1bGwgZmlsZS4KKyAgLy8gRm9yIG1vc3QgY2xpZW50cywgb25seSBvbmUgZGVsdGEgZmlsZSBzaG91bGQgYmUgZW5vdWdoLiBJZiBzcGVjaWZ5aW5nCisgIC8vIG11bHRpcGxlIGRlbHRhIGZpbGVzLCB0aGV5IHNob3VsZCBiZSBpbiBhIHNlcXVlbmNlIGZyb20gdGhlIG1vc3QgcmVjZW50CisgIC8vIGJhc2UgZmlsZSB0byB0aGUgb2xkZXN0LgorICAvLyBUaGlzIGlzIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRlZCBvbiBBbmRyb2lkLgorICByZXBlYXRlZCBEZWx0YUZpbGUgZGVsdGFfZmlsZSA9IDEzOworCisgIGVudW0gQW5kcm9pZFNoYXJpbmdUeXBlIHsKKyAgICAvLyBUaGUgZGF0YUZpbGUgaXNuJ3QgYXZhaWxhYmxlIGZvciBzaGFyaW5nLgorICAgIFVOU1VQUE9SVEVEID0gMDsKKworICAgIC8vIElmIHNoYXJpbmcgd2l0aCB0aGUgQW5kcm9pZCBCbG9iIFNoYXJpbmcgU2VydmljZSBpc24ndCBhdmFpbGFibGUsIGZhbGwKKyAgICAvLyBiYWNrIHRvIG5vcm1hbCBiZWhhdmlvciwgaS5lLiBkb3dubG9hZCBsb2NhbGx5LgorICAgIEFORFJPSURfQkxPQl9XSEVOX0FWQUlMQUJMRSA9IDE7CisgIH0KKworICAvLyBEZWZpbmVzIHdoZXRoZXIgdGhlIGZpbGUgc2hvdWxkIGJlIHNoYXJlZCBhbmQgaG93LgorICAvLyBOT1RFOiBjdXJyZW50bHkgdGhpcyBmaWVsZCBpcyBvbmx5IHVzZWQgYnkgYU1ERCBhbmQgaGFzIG5vIGVmZmVjdCBvbiBpTURELgorICBvcHRpb25hbCBBbmRyb2lkU2hhcmluZ1R5cGUgYW5kcm9pZF9zaGFyaW5nX3R5cGUgPSAxNzsKKworICAvLyBFbnVtIGZvciBhbmRyb2lkIHNoYXJpbmcgY2hlY2tzdW0gdHlwZXMuCisgIGVudW0gQW5kcm9pZFNoYXJpbmdDaGVja3N1bVR5cGUgeworICAgIE5PVF9TRVQgPSAwOworCisgICAgLy8gSWYgdGhlIGZpbGUgZ3JvdXAgc2hvdWxkIGJlIHNoYXJlZCB0aHJvdWdoIHRoZSBBbmRyb2lkIEJsb2IgU2hhcmluZworICAgIC8vIFNlcnZpY2UsIHRoZSBjaGVja3N1bSB0eXBlIG11c3QgYmUgc2V0IHRvIFNIQTI1Ni4KKyAgICBTSEEyXzI1NiA9IDE7CisgIH0KKworICBvcHRpb25hbCBBbmRyb2lkU2hhcmluZ0NoZWNrc3VtVHlwZSBhbmRyb2lkX3NoYXJpbmdfY2hlY2tzdW1fdHlwZSA9IDE4OworCisgIC8vIENoZWNrc3VtIHVzZWQgdG8gYWNjZXNzIGZpbGVzIHRocm91Z2ggdGhlIEFuZHJvaWQgQmxvYiBTaGFyaW5nIFNlcnZpY2UuCisgIG9wdGlvbmFsIHN0cmluZyBhbmRyb2lkX3NoYXJpbmdfY2hlY2tzdW0gPSAxOTsKKworICAvLyBSZWxhdGl2ZSBmaWxlIHBhdGggYW5kIGZpbGUgbmFtZSB0byBiZSBwcmVzZXJ2ZWQgd2l0aGluIHRoZSBwYXJlbnQKKyAgLy8gZGlyZWN0b3J5IHdoZW4gY3JlYXRpbmcgc3ltbGlua3MgZm9yIHRoZSBmaWxlIGdyb3VwcyB0aGF0IGhhdmUKKyAgLy8gcHJlc2VydmVfZmlsZW5hbWVzX2FuZF9pc29sYXRlX2ZpbGVzIHNldCB0byB0cnVlLgorICAvLyBUaGlzIGZpbGVuYW1lIHNob3VsZCBOT1Qgc3RhcnQgb3IgZW5kIHdpdGggYSAnLycsIGFuZCBpdCBjYW4gbm90IGNvbnRhaW4KKyAgLy8gdGhlIHN1YnN0cmluZyAnLi4nLgorICAvLyBXb3JraW5nIGV4YW1wbGU6ICJzdWJEaXIvRmlsZU5hbWUudHh0Ii4KKyAgb3B0aW9uYWwgc3RyaW5nIHJlbGF0aXZlX2ZpbGVfcGF0aCA9IDIwOworCisgIC8vIEN1c3RvbSBtZXRhZGF0YSBhdHRhY2hlZCB0byB0aGUgZmlsZS4KKyAgLy8KKyAgLy8gVGhpcyBhbGxvd3MgY2xpZW50cyB0byBpbmNsdWRlIHNwZWNpZmljIG1ldGFkYXRhIGFib3V0IHRoZSBmaWxlIGZvciB0aGVpcgorICAvLyBvd24gcHJvY2Vzc2luZyBwdXJwb3Nlcy4gVGhlIG1ldGFkYXRhIHdpbGwgYmUgc3RvcmVkIHdpdGggdGhlIGZpbGUgYW5kCisgIC8vIGFjY2Vzc2libGUgd2hlbiB0aGUgZmlsZSdzIGZpbGUgZ3JvdXAgaXMgcmV0cmlldmVkLgorICAvLworICAvLyBUaGlzIHByb3BlcnR5IHNob3VsZCBvbmx5IGJlIHVzZWQgaWYgYWJzb2x1dGVseSBuZWNlc3NhcnkuIFBsZWFzZSBjb25zdWx0CisgIC8vIHdpdGggPGludGVybmFsPkAgaWYgeW91IGhhdmUgcXVlc3Rpb25zIGFib3V0IHRoaXMgcHJvcGVydHkgb3IgYSBwb3RlbnRpYWwKKyAgLy8gdXNlLWNhc2UuCisgIG9wdGlvbmFsIGdvb2dsZS5wcm90b2J1Zi5BbnkgY3VzdG9tX21ldGFkYXRhID0gMjE7CisKKyAgcmVzZXJ2ZWQgMSwgMywgNiwgOCwgOTsKK30KKy8vIExJTlQuVGhlbkNoYW5nZSgKKy8vICAgICA8aW50ZXJuYWw+LAorLy8gICAgIDxpbnRlcm5hbD4pCisKKy8vIE1pcnJvcnMgbWRpLmRvd25sb2FkLkRlbHRhRmlsZQorLy8KKy8vIEEgZGVsdGEgZmlsZSByZXByZXNlbnRzIGFsbCB0aGUgbWV0YWRhdGEgdG8gZG93bmxvYWQgZm9yIGEgZGlmZiBmaWxlIGVuY29kZWQKKy8vIGJhc2VkIG9uIGEgYmFzZSBmaWxlCisvLyBMSU5ULklmQ2hhbmdlKGRlbHRhX2ZpbGUpCittZXNzYWdlIERlbHRhRmlsZSB7CisgIC8vIFRoZXNlIGZpZWxkcyBhbGwgbWlycm9yIHRoZSBzaW1pbGFybHktbmFtZWQgZmllbGRzIGluIERhdGFGaWxlLgorICBvcHRpb25hbCBzdHJpbmcgdXJsX3RvX2Rvd25sb2FkID0gMTsKKyAgb3B0aW9uYWwgaW50MzIgYnl0ZV9zaXplID0gMjsKKyAgb3B0aW9uYWwgc3RyaW5nIGNoZWNrc3VtID0gMzsKKworICAvLyBFbnVtIG9mIGFsbCBkaWZmIGRlY29kZXJzIHN1cHBvcnRlZAorICBlbnVtIERpZmZEZWNvZGVyIHsKKyAgICAvLyBEZWZhdWx0IHRvIGhhdmUgbm8gZGlmZiBkZWNvZGVyIHNwZWNpZmllZCwgd2lsbCB0aHJvd24gdW5zdXBwb3J0ZWQKKyAgICAvLyBleGNlcHRpb24KKyAgICBVTlNQRUNJRklFRCA9IDA7CisKKyAgICAvLyBWY0RJRkYgZGVjb2RlcgorICAgIC8vIEdlbmVyaWMgRGlmZmVyZW5jaW5nIGFuZCBDb21wcmVzc2lvbiBEYXRhIEZvcm1hdAorICAgIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uLCBwbGVhc2UgcmVmZXIgdG8gcmZjMzI4NAorICAgIC8vIFRoZSBWY0RpZmYgZGVjb2RlciBmb3IgR01TIHNlcnZpY2U6CisgICAgLy8gPGludGVybmFsPgorICAgIFZDX0RJRkYgPSAxOworICB9CisgIC8vIFRoZSBkaWZmIGRlY29kZXIgdXNlZCB0byBnZW5lcmF0ZSBmdWxsIGZpbGUgd2l0aCBkZWx0YSBhbmQgYmFzZSBmaWxlLgorICAvLyBGb3IgTUREIGFzIGEgR01TIHNlcnZpY2UsIGEgVmNEaWZmIGRlY29kZXIgd2lsbCBiZSByZWdpc3RlcmVkIGFuZCBpbmplY3RlZAorICAvLyBpbiBieSBkZWZhdWx0LiBVc2luZyBNREQgYXMgYSBsaWJyYXJ5LCBjbGllbnRzIG5lZWQgdG8gcmVnaXN0ZXIgYW5kIGluamVjdAorICAvLyBpbiBhIFZjRGlmZiBkZWNvZGVyLCBvdGhlcndpc2UsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KKyAgb3B0aW9uYWwgRGlmZkRlY29kZXIgZGlmZl9kZWNvZGVyID0gNTsKKworICAvLyBUaGUgYmFzZSBmaWxlIHJlcHJlc2VudHMgdG8gYSBmdWxsIGZpbGUgb24gZGV2aWNlLiBJdCBzaG91bGQgY29udGFpbiB0aGUKKyAgLy8gYmFyZSBtaW5pbXVtIGZpZWxkcyBvZiBhIERhdGFGaWxlIHRvIGlkZW50aWZ5IGEgRGF0YUZpbGUgb24gZGV2aWNlLgorICBvcHRpb25hbCBCYXNlRmlsZSBiYXNlX2ZpbGUgPSA2OworCisgIHJlc2VydmVkIDQ7Cit9CisvLyBMSU5ULlRoZW5DaGFuZ2UoCisvLyAgICAgPGludGVybmFsPiwKKy8vICAgICA8aW50ZXJuYWw+KQorCisvLyBNaXJyb3JzIG1kaS5kb3dubG9hZC5CYXNlRmlsZQorbWVzc2FnZSBCYXNlRmlsZSB7CisgIC8vIFNIQTEgY2hlY2tzdW0gb2YgdGhlIGJhc2UgZmlsZSB0byBpZGVudGlmeSBhIGZpbGUgb24gZGV2aWNlLiBJdCBzaG91bGQKKyAgLy8gbWF0Y2ggdGhlIGNoZWNrc3VtIGZpZWxkIG9mIHRoZSBiYXNlIGZpbGUgdXNlZCB0byBnZW5lcmF0ZSB0aGUgZGVsdGEgZmlsZS4KKyAgb3B0aW9uYWwgc3RyaW5nIGNoZWNrc3VtID0gMTsKK30KKworLy8gTWlycm9ycyBtZGkuZG93bmxvYWQuRG93bmxvYWRDb25kaXRpb25zCisvLworLy8gTmV4dCBpZDogNQorbWVzc2FnZSBEb3dubG9hZENvbmRpdGlvbnMgeworICAvLyBUT0RPKGIvMTQzNTQ4NzUzKTogVGhlIGZpcnN0IHZhbHVlIGluIGFuIGVudW0gbXVzdCBoYXZlIGEgc3BlY2lmaWMgcHJlZml4LgorICBlbnVtIERldmljZVN0b3JhZ2VQb2xpY3kgeworICAgIC8vIE1ERCB3aWxsIGJsb2NrIGRvd25sb2FkIG9mIGZpbGVzIGluIGFuZHJvaWQgbG93IHN0b3JhZ2UuIEN1cnJlbnRseSBNREQKKyAgICAvLyBkb2Vzbid0IGRlbGV0ZSB0aGUgZmlsZXMgaW4gY2FzZSB0aGUgZGV2aWNlIHJlYWNoZXMgbG93IHN0b3JhZ2UKKyAgICAvLyBhZnRlciB0aGUgZmlsZSBoYXMgYmVlbiBkb3dubG9hZGVkLgorICAgIEJMT0NLX0RPV05MT0FEX0lOX0xPV19TVE9SQUdFID0gMDsKKworICAgIC8vIEJsb2NrIGRvd25sb2FkIG9mIGZpbGVzIG9ubHkgdW5kZXIgYSBsb3dlciB0aHJlc2hvbGQgZGVmaW5lZCBoZXJlCisgICAgLy8gPGludGVybmFsPgorICAgIEJMT0NLX0RPV05MT0FEX0xPV0VSX1RIUkVTSE9MRCA9IDE7CisKKyAgICAvLyBTZXQgdGhlIHN0b3JhZ2UgdGhyZXNob2xkIHRvIGFuIGV4dHJlbWVseSBsb3cgdmFsdWUgd2hlbiBkb3dubG9hZGluZy4KKyAgICAvLyBJTVBPUlRBTlQ6IGlmIHRoZSBkb3dubG9hZCBtYWtlIHRoZSBkZXZpY2UgcnVucyBvdXQgb2YgZGlzaywgdGhpcyBjb3VsZAorICAgIC8vIHJlbmRlciB0aGUgZGV2aWNlIHVudXNhYmxlLgorICAgIC8vIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBmb3IgY3JpdGljYWwgdXNlIGNhc2VzIHN1Y2ggYXMgcHJpdmFjeQorICAgIC8vIHZpb2xhdGlvbnMuIEVtZXJnZW5jeSBmaXggc2hvdWxkIG5vdCBiZWxvbmcgdG8gdGhpcyBjYXRlZ29yeS4gUGxlYXNlCisgICAgLy8gdGFsa3MgdG8gPGludGVybmFsPkAgd2hlbiB5b3Ugd2FudCB0byB1c2UgdGhpcyBvcHRpb24uCisgICAgRVhUUkVNRUxZX0xPV19USFJFU0hPTEQgPSAyOworICB9CisKKyAgLy8gU3BlY2lmeSB0aGUgZGV2aWNlIHN0b3JhZ2UgdW5kZXIgd2hpY2ggdGhlIGZpbGVzIHNob3VsZCBiZSBkb3dubG9hZGVkLgorICAvLyBCeSBkZWZhdWx0LCB0aGUgZmlsZXMgd2lsbCBvbmx5IGJlIGRvd25sb2FkZWQgaWYgdGhlIGRldmljZSBpcyBub3QgaW4KKyAgLy8gbG93IHN0b3JhZ2UuCisgIG9wdGlvbmFsIERldmljZVN0b3JhZ2VQb2xpY3kgZGV2aWNlX3N0b3JhZ2VfcG9saWN5ID0gMTsKKworICAvLyBUT0RPKGIvMTQzNTQ4NzUzKTogVGhlIGZpcnN0IHZhbHVlIGluIGFuIGVudW0gbXVzdCBoYXZlIGEgc3BlY2lmaWMgcHJlZml4LgorICBlbnVtIERldmljZU5ldHdvcmtQb2xpY3kgeworICAgIC8vIE9ubHkgZG93bmxvYWQgZmlsZXMgb24gd2lmaS4KKyAgICBET1dOTE9BRF9PTkxZX09OX1dJRkkgPSAwOworCisgICAgLy8gQWxsb3cgZG93bmxvYWQgb24gYW55IG5ldHdvcmsgaW5jbHVkaW5nIHdpZmkgYW5kIGNlbGx1bGFyLgorICAgIERPV05MT0FEX09OX0FOWV9ORVRXT1JLID0gMTsKKworICAgIC8vIEFsbG93IGRvd25sb2FkaW5nIG9ubHkgb24gd2lmaSBmaXJzdCwgdGhlbiBhZnRlciBhIGNvbmZpZ3VyYWJsZSB0aW1lCisgICAgLy8gcGVyaW9kIHNldCBpbiB0aGUgZmllbGQgZG93bmxvYWRfZmlyc3Rfb25fd2lmaV9wZXJpb2Rfc2VjcyBiZWxvdywKKyAgICAvLyBhbGxvdyBkb3dubG9hZGluZyBvbiBhbnkgbmV0d29yayBpbmNsdWRpbmcgd2lmaSBhbmQgY2VsbHVsYXIuCisgICAgRE9XTkxPQURfRklSU1RfT05fV0lGSV9USEVOX09OX0FOWV9ORVRXT1JLID0gMjsKKyAgfQorCisgIC8vIFNwZWNpZnkgdGhlIGRldmljZSBuZXR3b3JrIHVuZGVyIHdoaWNoIHRoZSBmaWxlcyBzaG91bGQgYmUgZG93bmxvYWRlZC4KKyAgLy8gQnkgZGVmYXVsdCwgdGhlIGZpbGVzIHdpbGwgb25seSBiZSBkb3dubG9hZGVkIG9uIHdpZmkuCisgIC8vCisgIC8vIElmIHlvdXIgZmVhdHVyZSB0YXJnZXRzIGJlbG93IHYyMCBhbmQgd2FudCB0byBkb3dubG9hZCBvbiBjZWxsdWxhciBpbgorICAvLyB0aGVzZSB2ZXJzaW9ucyBvZiBnbXMsIGFsc28gc2V0IGFsbG93X2Rvd2xvYWRfd2l0aG91dF93aWZpID0gdHJ1ZTsKKyAgb3B0aW9uYWwgRGV2aWNlTmV0d29ya1BvbGljeSBkZXZpY2VfbmV0d29ya19wb2xpY3kgPSAyOworCisgIC8vIFRoaXMgZmllbGQgd2lsbCBvbmx5IGJlIHVzZWQgd2hlbiB0aGUKKyAgLy8gRGV2aWNlTmV0d29ya1BvbGljeSA9IERPV05MT0FEX0ZJUlNUX09OX1dJRklfVEhFTl9PTl9BTllfTkVUV09SSworICAvLyBNREQgd2lsbCBkb3dubG9hZCB0aGUgZmlsZSBvbmx5IG9uIHdpZmkgZm9yIHRoaXMgcGVyaW9kIG9mIHRpbWUuIElmIHRoZQorICAvLyBkb3dubG9hZCB3YXMgbm90IGZpbmlzaGVkLCBNREQgd2lsbCBkb3dubG9hZCBvbiBhbnkgbmV0d29yayBpbmNsdWRpbmcKKyAgLy8gd2lmaSBhbmQgY2VsbHVsYXIuCisgIC8vIEV4OiA2MDQ4MDAgIC8vIDcgRGF5cworICBvcHRpb25hbCBpbnQ2NCBkb3dubG9hZF9maXJzdF9vbl93aWZpX3BlcmlvZF9zZWNzID0gNDsKKworICAvLyBUT0RPKGIvMTQzNTQ4NzUzKTogVGhlIGZpcnN0IHZhbHVlIGluIGFuIGVudW0gbXVzdCBoYXZlIGEgc3BlY2lmaWMgcHJlZml4LgorICBlbnVtIEFjdGl2YXRpbmdDb25kaXRpb24geworICAgIC8vIFRoZSBkb3dubG9hZCBpcyBhY3RpdmF0ZWQgYXMgc29vbiB0aGUgc2VydmVyIHNpZGUgY29uZmlnIGlzIHJlY2VpdmVkIGFuZAorICAgIC8vIHRoZSBzZXJ2ZXIgY29uZmlndXJlZCBkb3dubG9hZCBjb25kaXRpb25zIGFyZSBzYXRpc2ZpZWQuCisgICAgQUxXQVlTX0FDVElWQVRFRCA9IDA7CisKKyAgICAvLyBUaGUgZG93bmxvYWQgaXMgYWN0aXZhdGVkIHdoZW4gYm90aCBzZXJ2ZXIgc2lkZSBhY3RpdmF0aW9uIGNvbmRpdGlvbnMKKyAgICAvLyBhcmUgc2F0aXNmaWVkIGFuZCB0aGUgY2xpZW50IGhhcyBhY3RpdmF0ZWQgdGhlIGRvd25sb2FkIG9uIGRldmljZS4KKyAgICAvLworICAgIC8vIENsaWVudHMgY2FuIGFjdGl2YXRlIHRoaXMgZ3JvdXAgdXNpbmcgdGhlIGFjdGl2YXRlRmlsZUdyb3VwIEFQSS4KKyAgICAvLyA8aW50ZXJuYWw+CisgICAgREVWSUNFX0FDVElWQVRFRCA9IDE7CisgIH0KKworICAvLyBTcGVjaWZ5IGhvdyB0aGUgZG93bmxvYWQgaXMgYWN0aXZhdGVkLiBCeSBkZWZhdWx0LCB0aGUgZG93bmxvYWQgaXMKKyAgLy8gYWN0aXZhdGVkIGFzIHNvb24gYXMgc2VydmVyIGNvbmZpZ3VyZWQgYWN0aXZhdGluZyBjb25kaXRpb25zIGFyZSBzYXRpc2ZpZWQuCisgIG9wdGlvbmFsIEFjdGl2YXRpbmdDb25kaXRpb24gYWN0aXZhdGluZ19jb25kaXRpb24gPSAzOworfQorCisvLyBUaGlzIHByb3RvIGNvbnRhaW5zIGV4dHJhIGluZm9ybWF0aW9uIGFib3V0IGEgZmlsZSBncm91cCBmb3IgYm9va2tlZXBpbmcuCisvLyBOZXh0IHRhZzogNgorbWVzc2FnZSBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcgeworICAvLyBUaGUgZXBvY2ggdGltZSAoc2Vjb25kcyBzaW5jZSAxLzEvMTk3MCkgYXQgd2hpY2ggdGhpcyBzdGFsZSBmaWxlIGdyb3VwIHdpbGwKKyAgLy8gYmUgZGVsZXRlZC4KKyAgb3B0aW9uYWwgaW50NjQgc3RhbGVfZXhwaXJhdGlvbl9kYXRlID0gMTsKKworICAvLyBUaGUgdGltZXN0YW1wIChlcG9jaCB0aW1lLCBtaWxsaXNlY29uZHMgc2luY2UgMS8xLzE5NzApIHRoYXQgdGhlIGZpbGUgZ3JvdXAKKyAgLy8gd2FzIGZpcnN0IHJlY2VpdmVkLgorICAvLworICAvLyBJZiB0aGlzIGlzIGFuIHVwZGF0ZSBvbiBhbiBleGlzdGluZyBncm91cCwgdGhlbiB0aGUgdGltZXN0YW1wIGZyb20gdGhlIG9sZAorICAvLyBncm91cCBpcyB1c2VkIGlmIG5vIGZpbGVzIHdlcmUgdXBkYXRlZC4KKyAgb3B0aW9uYWwgaW50NjQgZ3JvdXBfbmV3X2ZpbGVzX3JlY2VpdmVkX3RpbWVzdGFtcCA9IDI7CisKKyAgLy8gVGhlIHRpbWVzdGFtcCAoZXBvY2ggdGltZSwgbWlsbGlzZWNvbmRzIHNpbmNlIDEvMS8xOTcwKSBhdCB3aGljaCB0aGUgZ3JvdXAKKyAgLy8gd2FzIGZpcnN0IG1hcmtlZCBhcyBkb3dubG9hZGVkLgorICBvcHRpb25hbCBpbnQ2NCBncm91cF9kb3dubG9hZGVkX3RpbWVzdGFtcF9pbl9taWxsaXMgPSAzOworCisgIC8vIFRoZSB0aW1lc3RhbXAgKGVwb2NoIHRpbWUsIG1pbGxpc2Vjb25kcyBzaW5jZSAxLzEvMTk3MCkgdGhhdCBNREQgc3RhcnRzCisgIC8vIGRvd25sb2FkaW5nIHRoZSBmaWxlIGdyb3VwIGZvciB0aGUgZmlyc3QgdGltZS4KKyAgb3B0aW9uYWwgaW50NjQgZ3JvdXBfZG93bmxvYWRfc3RhcnRlZF90aW1lc3RhbXBfaW5fbWlsbGlzID0gNDsKKworICAvLyBUaGUgdG90YWwgY291bnQgb2YgZG93bmxvYWQgcGVyaW9kaWMgdGFza3MgbmVlZGVkIHRvIGZ1bGx5IGRvd25sb2FkIHRoZQorICAvLyBmaWxlIGdyb3VwLgorICBvcHRpb25hbCBpbnQzMiBkb3dubG9hZF9zdGFydGVkX2NvdW50ID0gNTsKK30KKworLy8gS2V5IHVzZWQgYnkgbWRkIHRvIHVuaXF1ZWx5IGlkZW50aWZ5IGEgY2xpZW50IGdyb3VwLgorbWVzc2FnZSBHcm91cEtleSB7CisgIC8vIFRoZSBuYW1lIG9mIHRoZSBncm91cC4KKyAgb3B0aW9uYWwgc3RyaW5nIGdyb3VwX25hbWUgPSAxOworCisgIC8vIFRoZSBwYWNrYWdlIG5hbWUgb2YgdGhlIGdyb3VwIG93bmVyLiBBIG51bGwgdmFsdWUgb3IgZW1wdHkgdmFsdWUgbWVhbnMKKyAgLy8gdGhhdCB0aGUgZ3JvdXAgaXMgbm90IGFzc29jaWF0ZWQgd2l0aCBhbnkgcGFja2FnZS4KKyAgb3B0aW9uYWwgc3RyaW5nIG93bmVyX3BhY2thZ2UgPSAyOworCisgIC8vIFRoZSBhY2NvdW50IGFzc29jaWF0ZWQgdG8gdGhlIGZpbGUgZ3JvdXAuCisgIG9wdGlvbmFsIHN0cmluZyBhY2NvdW50ID0gNTsKKworICAvLyBXaGV0aGVyIG9yIG5vdCBhbGwgZmlsZXMgaW4gYSBmaWxlR3JvdXAgaGF2ZSBiZWVuIGRvd25sb2FkZWQuCisgIG9wdGlvbmFsIGJvb2wgZG93bmxvYWRlZCA9IDQ7CisKKyAgLy8gVGhlIHZhcmlhbnQgaWQgb2YgdGhlIGdyb3VwLiBBIG51bGwgb3IgZW1wdHkgdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIGdyb3VwCisgIC8vIGRvZXMgbm90IGhhdmUgYW4gYXNzb2NpYXRlZCB2YXJpYW50LgorICBvcHRpb25hbCBzdHJpbmcgdmFyaWFudF9pZCA9IDY7CisKKyAgcmVzZXJ2ZWQgMzsKK30KKworLy8gR3JvdXAgS2V5IHByb3BlcnRpZXMgdGhhdCBhcHBseSB0byBhbGwgZ3JvdXBzIHdpdGggdGhhdCBrZXkuCittZXNzYWdlIEdyb3VwS2V5UHJvcGVydGllcyB7CisgIC8vIFdoZXRoZXIgdGhpcyBncm91cCBrZXkgaGFzIGJlZW4gYWN0aXZhdGVkIG9uIHRoZSBkZXZpY2UuCisgIG9wdGlvbmFsIGJvb2wgYWN0aXZhdGVkX29uX2RldmljZSA9IDE7Cit9CisKKy8vIFNoYXJlZEZpbGUgaXMgYSBpbnRlcm5hbCBkYXRhIHN0cnVjdHVyZSBvZiB0aGUgU2hhcmVkRmlsZU1hbmFnZXIuCittZXNzYWdlIFNoYXJlZEZpbGUgeworICBvcHRpb25hbCBzdHJpbmcgZmlsZV9uYW1lID0gNDsKKyAgb3B0aW9uYWwgRmlsZVN0YXR1cyBmaWxlX3N0YXR1cyA9IDU7CisKKyAgLy8gVGhpcyBmaWVsZCB3aWxsIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIGEgZmlsZSBjYW4gYmUgcmV0cmlldmVkIGZyb20gdGhlCisgIC8vIEFuZHJvaWQgQmxvYiBTaGFyaW5nIFNlcnZpY2UuCisgIG9wdGlvbmFsIGJvb2wgYW5kcm9pZF9zaGFyZWQgPSA4OworCisgIC8vIFRoZSBtYXhpbXVtIGV4cGlyYXRpb24gZGF0ZSBmb3VuZCBmb3IgYSBkb3dubG9hZGVkIGRhdGEgZmlsZS4gSWYKKyAgLy8ge0Bjb2RlIGFuZHJvaWRfc2hhcmVkfSBpcyBzZXQgdG8gdHJ1ZSwgdGhpcyBmaWVsZCBzdG9yZXMgdGhlIGN1cnJlbnQgbGVhc2UKKyAgLy8gZXhwaXJhdGlvbiBkYXRlLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyAwLgorICAvLyBTZWUgPGludGVybmFsPiBmb3IgbW9yZSBkZXRhaWxzLgorICBvcHRpb25hbCBpbnQ2NCBtYXhfZXhwaXJhdGlvbl9kYXRlX3NlY3MgPSA5OworCisgIC8vIENoZWNrc3VtIHVzZWQgdG8gYWNjZXNzIGZpbGVzIHRocm91Z2ggdGhlIEFuZHJvaWQgQmxvYiBTaGFyaW5nIFNlcnZpY2UuCisgIG9wdGlvbmFsIHN0cmluZyBhbmRyb2lkX3NoYXJpbmdfY2hlY2tzdW0gPSAxMDsKKworICAvLyBJZiB0aGUgZmlsZSBpcyBkb3dubG9hZGVkIHN1Y2Nlc3NmdWxseSBidXQgZmFpbHMgY2hlY2tzdW0gbWF0Y2hpbmcsIHdlIHdpbGwKKyAgLy8gYXR0ZW1wdCB0byBkZWxldGUgdGhlIGZpbGUgc28gaXQgY2FuIGJlIHJlZG93bmxvYWRlZCBmcm9tIHNjcmF0Y2guIFRvCisgIC8vIHByZXZlbnQgdW5uZWNlc3NhcnkgbmV0d29yayBiYW5kd2lkdGgsIHdlIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiB0aGVzZQorICAvLyBhdHRlbXB0cyBpbiB0aGlzIGZpZWxkIGFuZCBzdG9wIGFmdGVyIGEgY2VydGFpbiBudW1iZXIuIChjb25maWd1cmFibGUgYnkgYQorICAvLyBkb3dubG9hZCBmbGFnKS4KKyAgb3B0aW9uYWwgaW50MzIgY2hlY2tzdW1fbWlzbWF0Y2hfcmV0cnlfZG93bmxvYWRfY291bnQgPSAxMTsKKworICByZXNlcnZlZCAxLCAyLCAzLCA2LCA3OworfQorCisvLyBNZXRhZGF0YSB1c2VkIGJ5CisvLyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1kaS5kb3dubG9hZC5Nb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyCittZXNzYWdlIE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXJNZXRhZGF0YSB7CisgIG9wdGlvbmFsIGJvb2wgbWRkX21pZ3JhdGVkX3RvX29mZnJvYWQgPSAxOworICBvcHRpb25hbCBpbnQzMiByZXNldF90cmlnZ2VyID0gMjsKK30KKworLy8gTWV0YWRhdGEgdXNlZCBieQorLy8gY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tZGkuZG93bmxvYWQuU2hhcmVkRmlsZU1hbmFnZXIKK21lc3NhZ2UgU2hhcmVkRmlsZU1hbmFnZXJNZXRhZGF0YSB7CisgIG9wdGlvbmFsIGJvb2wgbWlncmF0ZWRfdG9fbmV3X2ZpbGVfa2V5ID0gMTsKKyAgb3B0aW9uYWwgaW50NjQgbmV4dF9maWxlX25hbWUgPSAyOworfQorCisvLyBDb2xsZWN0cyBhbGwgZGF0YSB1c2VkIGJ5CisvLyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1kaS5kb3dubG9hZC5pbnRlcm5hbC5NaWdyYXRpb25zCittZXNzYWdlIE1pZ3JhdGlvbnNTdG9yZSB7CisgIGVudW0gRmlsZUtleVZlcnNpb24geworICAgIE5FV19GSUxFX0tFWSA9IDA7CisgICAgQUREX0RPV05MT0FEX1RSQU5TRk9STSA9IDE7CisgICAgVVNFX0NIRUNLU1VNX09OTFkgPSAyOworICB9CisgIG9wdGlvbmFsIGJvb2wgaXNfbWlncmF0ZWRfdG9fbmV3X2ZpbGVfa2V5ID0gMTsKKyAgb3B0aW9uYWwgRmlsZUtleVZlcnNpb24gY3VycmVudF92ZXJzaW9uID0gMjsKK30KKworLy8gQ29sbGVjdHMgYWxsIGRhdGEgdXNlZCBieQorLy8gY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tZGkuZG93bmxvYWQuaW50ZXJuYWwuRmlsZUdyb3Vwc01ldGFkYXRhCittZXNzYWdlIEZpbGVHcm91cHNNZXRhZGF0YVN0b3JlIHsKKyAgLy8gS2V5IG11c3QgYmUgYSBzZXJpYWxpemVkIEdyb3VwS2V5LgorICBtYXA8c3RyaW5nLCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRhdGFfZmlsZV9ncm91cHMgPSAxOworICAvLyBLZXkgbXVzdCBiZSBhIHNlcmlhbGl6ZWQgR3JvdXBLZXkuCisgIG1hcDxzdHJpbmcsIEdyb3VwS2V5UHJvcGVydGllcz4gZ3JvdXBfa2V5X3Byb3BlcnRpZXMgPSAyOworICByZXBlYXRlZCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgc3RhbGVfZ3JvdXBzID0gMzsKK30KKworLy8gQ29sbGVjdHMgYWxsIGRhdGEgdXNlZCBieQorLy8gY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tZGkuZG93bmxvYWQuaW50ZXJuYWwuU2hhcmVkRmlsZXNNZXRhZGF0YQorbWVzc2FnZSBTaGFyZWRGaWxlc01ldGFkYXRhU3RvcmUgeworICAvLyBUaGUga2V5IG11c3QgYmUgYSBzZXJpYWxpemVkIE5ld0ZpbGVLZXkuCisgIG1hcDxzdHJpbmcsIFNoYXJlZEZpbGU+IHNoYXJlZF9maWxlcyA9IDE7Cit9CisKK2VudW0gRmlsZVN0YXR1cyB7CisgIC8vIFRoZSBmaWxlIGhhcyBuZXZlciBiZWVuIHNlZW4gYmVmb3JlLgorICBOT05FID0gMDsKKyAgLy8gVGhlIGZpbGUgaGFzIGJlZW4gc3Vic2NyaWJlZCB0bywgYnV0IGRvd25sb2FkIGhhcyBub3QgYmVlbiBhdHRlbXB0ZWQuCisgIFNVQlNDUklCRUQgPSAxOworICAvLyBUaGUgZmlsZSBkb3dubG9hZCBpcyBjdXJyZW50bHkgaW4gcHJvZ3Jlc3MuCisgIERPV05MT0FEX0lOX1BST0dSRVNTID0gMjsKKyAgLy8gRG93bmxvYWRpbmcgdGhlIGZpbGUgZmFpbGVkLgorICBET1dOTE9BRF9GQUlMRUQgPSAzOworICAvLyBUaGUgZmlsZSB3YXMgZG93bmxvYWRlZCBjb21wbGV0ZWx5LCBhbmQgaXMgYXZhaWxhYmxlIGZvciB1c2UuCisgIERPV05MT0FEX0NPTVBMRVRFID0gNDsKKyAgLy8gVGhlIGZpbGUgd2FzIGNvcnJ1cHRlZCBvciBsb3N0IGFmdGVyIGJlaW5nIHN1Y2Nlc3NmdWxseSBkb3dubG9hZGVkLgorICBDT1JSVVBURUQgPSA2OworICAvLyBTdGF0dXMgcmV0dXJuZWQgd2hlbiB0aGVpciBpcyBhbiBlcnJvciB3aGlsZSBnZXR0aW5nIHRoZSBmaWxlIHN0YXR1cy4KKyAgLy8gVGhpcyBpcyBuZXZlciBzYXZlZCBvbiBkaXNrLgorICBJTlRFUk5BTF9FUlJPUiA9IDU7Cit9CisKKy8vIEtleSB1c2VkIGJ5IHRoZSBTaGFyZWRGaWxlTWFuYWdlciB0byBpZGVudGlmeSBhIHNoYXJlZCBmaWxlLgorbWVzc2FnZSBOZXdGaWxlS2V5IHsKKyAgLy8gVGhlc2UgZmllbGRzIGFsbCBtaXJyb3IgdGhlIHNpbWlsYXJseS1uYW1lZCBmaWVsZHMgaW4gRGF0YUZpbGUuCisgIG9wdGlvbmFsIHN0cmluZyB1cmxfdG9fZG93bmxvYWQgPSAxIFtkZXByZWNhdGVkID0gdHJ1ZV07CisgIG9wdGlvbmFsIGludDMyIGJ5dGVfc2l6ZSA9IDIgW2RlcHJlY2F0ZWQgPSB0cnVlXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGNoZWNrc3VtID0gMzsKKyAgb3B0aW9uYWwgRGF0YUZpbGVHcm91cEludGVybmFsLkFsbG93ZWRSZWFkZXJzIGFsbG93ZWRfcmVhZGVycyA9IDQ7CisgIG9wdGlvbmFsIG1vYnN0b3JlLnByb3RvLlRyYW5zZm9ybXMgZG93bmxvYWRfdHJhbnNmb3JtcyA9IDUKKyAgICAgIFtkZXByZWNhdGVkID0gdHJ1ZV07Cit9CisKKy8vIFRoaXMgcHJvdG8gaXMgdXNlZCB0byBzdG9yZSBzdGF0ZSBmb3IgbG9nZ2luZy4gU2VlIGRldGFpbHMgYXQKKy8vIDxpbnRlcm5hbD4KK21lc3NhZ2UgTG9nZ2luZ1N0YXRlIHsKKyAgLy8gVGhlIGxhc3QgdGltZSBtYWludGVuYW5jZSB3YXMgcnVuLiBUaGlzIHNob3VsZCBiZSB1cGRhdGVkIGV2ZXJ5IHRpbWUKKyAgLy8gbWFpbnRlbmFuY2UgaXMgcnVuLgorICAvLyBOb3RlOiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvbmx5IHVzZXMgdGhpcyB0byBkZXRlcm1pbmUgdGhlIGRhdGUgb2YKKyAgLy8gdGhlIGxhc3QgbG9nIGV2ZW50LCBidXQgaW4gdGhlIGZ1dHVyZSB3ZSBtYXkgd2FudCBtb3JlIGdyYW51bGFyCisgIC8vIG1lYXN1cmVtZW50cyBmb3IgdGhpcywgc28gd2Ugc3RvcmUgdGhlIHRpbWVzdGFtcCBhcy1pcy4KKyAgb3B0aW9uYWwgZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBsYXN0X21haW50ZW5hbmNlX3J1bl90aW1lc3RhbXAgPSAxOworCisgIC8vIEZpbGUgZ3JvdXAgc3BlY2lmaWMgbG9nZ2luZyBzdGF0ZSBrZXllZCBieSBHcm91cEtleSwgYnVpbGQgaWQgYW5kIHZlcnNpb24KKyAgLy8gbnVtYmVyLgorICByZXBlYXRlZCBGaWxlR3JvdXBMb2dnaW5nU3RhdGUgZmlsZV9ncm91cF9sb2dnaW5nX3N0YXRlID0gMjsKKworICAvLyBTZXQgdG8gdHJ1ZSBvbmNlIHRoZSBzaGFyZWQgcHJlZmVyZW5jZXMgbWlncmF0aW9uIGlzIGNvbXBsZXRlLgorICAvLyBOb3RlOiB0aGlzIGZpZWxkIGlzbid0IHN0cmljdGx5IG5lY2Vzc2FyeSBhdCB0aGUgbW9tZW50IC0gd2UgY291bGQganVzdAorICAvLyBjaGVjayB0aGF0IHRoZSBmaWxlX2dyb3VwX2xvZ2dpbmdfc3RhdGUgaXMgZW1wdHkgc2luY2Ugbm8gb25lIHNob3VsZCB3cml0ZQorICAvLyB0byB0aGUgbmV0d29yayB1c2FnZSBtb25pdG9yIHNoYXJlZCBwcmVmcyBzaW5jZSB0aGUgbWlncmF0aW9uIHdpbGwgYmUKKyAgLy8gaW5zdGFsbGVkIGF0IHRoZSBzYW1lIGNsIHdoZXJlIHRoZSBjb2RlIGlzIHJlbW92ZWQuIEhvd2V2ZXIsIGlmIHdlIHdlcmUgdG8KKyAgLy8gYWRkIG1vcmUgZmllbGRzIHRvIEZpbGVHcm91cExvZ2dpbmdTdGF0ZSwgaXQgd291bGQgYmUgbGVzcyBzdHJhaWdodGZvcndhcmQKKyAgLy8gdG8gY2hlY2sgZm9yIG1pZ3JhdGlvbiBzdGF0ZSAtIHNvIGhhdmluZyB0aGlzIGJvb2xlYW4gbWFrZXMgaXQgYSBiaXQgc2FmZXIuCisgIG9wdGlvbmFsIGJvb2wgc2hhcmVkX3ByZWZlcmVuY2VzX25ldHdvcmtfdXNhZ2VfbW9uaXRvcl9taWdyYXRpb25fY29tcGxldGUgPSAzOworCisgIC8vIEluZm8gdG8gZW5hYmxlIHN0YWJsZSBzYW1wbGluZy4gU2VlIDxpbnRlcm5hbD4gZm9yIG1vcmUKKyAgLy8gaW5mby4gVGhpcyBmaWVsZCB3aWxsIGJlIHNldCBieSBhIG1pZ3JhdGlvbiBvbiBmaXJzdCBhY2Nlc3MuCisgIG9wdGlvbmFsIFNhbXBsaW5nSW5mbyBzYW1wbGluZ19pbmZvID0gNDsKK30KKworLy8gVGhpcyBwcm90byBpcyB1c2VkIHRvIHN0b3JlIHN0YXRlIGZvciBsb2dnaW5nIHRoYXQgaXMgc3BlY2lmaWMgdG8gYSBGaWxlCisvLyBHcm91cC4gVGhpcyBpbmNsdWRlcyBuZXR3b3JrIHVzYWdlIGxvZ2dpbmcgYW5kIG1heWJlIGRvd25sb2FkIHRpZXJzIChmb3IKKy8vIDxpbnRlcm5hbD4pLgorbWVzc2FnZSBGaWxlR3JvdXBMb2dnaW5nU3RhdGUgeworICBvcHRpb25hbCBHcm91cEtleSBncm91cF9rZXkgPSAxOworICBvcHRpb25hbCBpbnQ2NCBidWlsZF9pZCA9IDI7CisgIG9wdGlvbmFsIGludDMyIGZpbGVfZ3JvdXBfdmVyc2lvbl9udW1iZXIgPSAzOworICBvcHRpb25hbCBpbnQ2NCBjZWxsdWxhcl91c2FnZSA9IDQ7CisgIG9wdGlvbmFsIGludDY0IHdpZmlfdXNhZ2UgPSA1OworfQorCisvLyBOZXh0IGlkOiAzCittZXNzYWdlIFNhbXBsaW5nSW5mbyB7CisgIC8vIFJhbmRvbSBudW1iZXIgZ2VuZXJhdGVkIGFuZCBwZXJzaXN0ZWQgb24gZGV2aWNlLiBUaGlzIG51bWJlciBzaG91bGQgbm90CisgIC8vIGNoYW5nZSAodW5sZXNzIGRldmljZSBzdG9yYWdlL21kZCBpcyBjbGVhcmVkKS4gSXQgaXMgdXNlZCBhcyBhIHN0YWJsZQorICAvLyBpZGVudGlmaWVyIHRvIGRldGVybWluZSB3aGV0aGVyIE1ERCBzaG91bGQgbG9nIGV2ZW50cy4KKyAgb3B0aW9uYWwgaW50NjQgc3RhYmxlX2xvZ19zYW1wbGluZ19zYWx0ID0gMTsKKworICAvLyBXaGVuIHRoZSBzdGFibGVfbG9nX3NhbXBsaW5nX3NhbHQgd2FzIGZpcnN0IHNldC4gVGhpcyB3aWxsIGJlIHVzZWQgZHVyaW5nCisgIC8vIHJvbGwgb3V0IHRvIGRldGVybWluZSB3aGljaCBkZXZpY2VzIGhhdmUgZW5hYmxlZCBzdGFibGUgc2FtcGxpbmcgZm9yIGEKKyAgLy8gc3VmZmljaWVudCB0aW1lIHBlcmlvZC4KKyAgb3B0aW9uYWwgZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBsb2dfc2FtcGxpbmdfc2FsdF9zZXRfdGltZXN0YW1wID0gMjsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9BbmRyb2lkU2hhcmluZ1V0aWwuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9BbmRyb2lkU2hhcmluZ1V0aWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NmVkN2RjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL0FuZHJvaWRTaGFyaW5nVXRpbC5qYXZhCkBAIC0wLDAgKzEsMjMxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudGV4dC5UZXh0VXRpbHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkxpbWl0RXhjZWVkZWRFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uTWFsZm9ybWVkVXJpRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLlJlYWRTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLldyaXRlU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5CeXRlU3RyZWFtczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKKworLyoqIFV0aWxzIGZvciBBbmRyb2lkIGZpbGUgc2hhcmluZy4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBBbmRyb2lkU2hhcmluZ1V0aWwgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiQW5kcm9pZFNoYXJpbmdVdGlsIjsKKworICAvKioKKyAgICogRXhjZXB0aW9uIHRocm93biBpZiBhbiBlcm9yIG9jY3VycyB3aGlsZSB0cnlpbmcgdG8gc2hhcmUgYSBmaWxlIHdpdGggdGhlIEFuZHJvaWQgQmxvYiBTaGFyaW5nCisgICAqIFNlcnZpY2UuCisgICAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEFuZHJvaWRTaGFyaW5nRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKyAgICAvLyBUaGUgZXJyb3IgY29kZSB0byBiZSBsb2dnZWQuCisgICAgcHJpdmF0ZSBmaW5hbCBpbnQgZXJyb3JDb2RlOworCisgICAgcHVibGljIEFuZHJvaWRTaGFyaW5nRXhjZXB0aW9uKGludCBlcnJvckNvZGUsIFN0cmluZyBtZXNzYWdlKSB7CisgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICAgIHRoaXMuZXJyb3JDb2RlID0gZXJyb3JDb2RlOworICAgIH0KKworICAgIHB1YmxpYyBpbnQgZ2V0RXJyb3JDb2RlKCkgeworICAgICAgcmV0dXJuIGVycm9yQ29kZTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIEFuZHJvaWRTaGFyaW5nVXRpbCgpIHt9CisKKyAgLyoqIFJldHVybnMgdHJ1ZSBpZiBhIGJsb2Igd2l0aCBjaGVja3N1bSB7QGNvZGUgY2hlY2tzdW19IGFscmVhZHkgZXhpc3RzIGluIHRoZSBzaGFyZWQgc3RvcmFnZS4gKi8KKyAgcHVibGljIHN0YXRpYyBib29sZWFuIGJsb2JFeGlzdHMoCisgICAgICBDb250ZXh0IGNvbnRleHQsCisgICAgICBTdHJpbmcgY2hlY2tzdW0sCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwLAorICAgICAgRGF0YUZpbGUgZGF0YUZpbGUsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlKQorICAgICAgdGhyb3dzIEFuZHJvaWRTaGFyaW5nRXhjZXB0aW9uIHsKKyAgICBpbnQgZXJyb3JDb2RlID0gLTE7CisgICAgYm9vbGVhbiBleGlzdHMgPSBmYWxzZTsKKyAgICBTdHJpbmcgbWVzc2FnZSA9ICIiOworICAgIHRyeSB7CisgICAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBjaGVja3N1bSk7CisgICAgICBleGlzdHMgPSBmaWxlU3RvcmFnZS5leGlzdHMoYmxvYlVyaSk7CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbiBlKSB7CisgICAgICBTdHJpbmcgbXNnID0gVGV4dFV0aWxzLmlzRW1wdHkoZS5nZXRNZXNzYWdlKCkpID8gIiIgOiBlLmdldE1lc3NhZ2UoKTsKKyAgICAgIExvZ1V0aWwudigKKyAgICAgICAgICAiJXM6IEZhaWxlZCB0byBzaGFyZSBmb3IgZmlsZSAlcywgZmlsZSBncm91cCAlcy4iCisgICAgICAgICAgICAgICsgIiBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uIHdhcyB0aHJvd24gd2l0aCBtZXNzYWdlIFwiJXNcIiIsCisgICAgICAgICAgVEFHLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpLCBtc2cpOworICAgICAgZXJyb3JDb2RlID0gMDsKKyAgICAgIG1lc3NhZ2UgPSAiVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbiB3YXMgdGhyb3duOiAiICsgbXNnOworICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVyaUV4Y2VwdGlvbiBlKSB7CisgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgIiVzOiBNYWxmb3JtZWQgbGVhc2UgdXJpIGZpbGUgJXMsIGZpbGUgZ3JvdXAgJXMiLAorICAgICAgICAgIFRBRywgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICBlcnJvckNvZGUgPSAwOworICAgICAgbWVzc2FnZSA9CisgICAgICAgICAgU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAgICAgIk1hbGZvcm1lZCBibG9iIFVyaSBmb3IgZmlsZSAlcywgZ3JvdXAgJXMiLAorICAgICAgICAgICAgICBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgIiVzOiBGYWlsZWQgdG8gY2hlY2sgZXhpc3RlbmNlIGluIHRoZSBzaGFyZWQgc3RvcmFnZSBmb3IgZmlsZSAlcywgZmlsZSBncm91cCIgKyAiICVzIiwKKyAgICAgICAgICBUQUcsIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgZXJyb3JDb2RlID0gMDsKKyAgICAgIG1lc3NhZ2UgPQorICAgICAgICAgIFN0cmluZy5mb3JtYXQoCisgICAgICAgICAgICAgICJFcnJvciB3aGlsZSBjaGVja2luZyBpZiBmaWxlICVzLCBncm91cCAlcywgZXhpc3RzIGluIHRoZSBzaGFyZWQgYmxvYiBzdG9yYWdlLiIsCisgICAgICAgICAgICAgIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgIH0KKyAgICBpZiAoZXJyb3JDb2RlICE9IC0xKSB7CisgICAgICB0aHJvdyBuZXcgQW5kcm9pZFNoYXJpbmdFeGNlcHRpb24oZXJyb3JDb2RlLCBtZXNzYWdlKTsKKyAgICB9CisgICAgcmV0dXJuIGV4aXN0czsKKyAgfQorCisgIC8qKgorICAgKiBDb3BpZXMgdGhlIGxvY2FsIHtAY29kZSBkb3dubG9hZEZpbGVPbkRldmljZVVyaX0gdG8gdGhlIGJsb2Igc3RvcmFnZS4KKyAgICoKKyAgICogQHBhcmFtIGFmdGVyRG93bmxvYWQgd2hldGhlciB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBiZWZvcmUgb3IgYWZ0ZXIgdGhlIHtAY29kZSBkYXRhRmlsZX0ncworICAgKiAgICAgZG93bmxvYWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgY29weUZpbGVUb0Jsb2JTdG9yZSgKKyAgICAgIENvbnRleHQgY29udGV4dCwKKyAgICAgIFN0cmluZyBjaGVja3N1bSwKKyAgICAgIFVyaSBkb3dubG9hZEZpbGVPbkRldmljZVVyaSwKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAsCisgICAgICBEYXRhRmlsZSBkYXRhRmlsZSwKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsCisgICAgICBib29sZWFuIGFmdGVyRG93bmxvYWQpCisgICAgICB0aHJvd3MgQW5kcm9pZFNoYXJpbmdFeGNlcHRpb24geworICAgIGludCBlcnJvckNvZGUgPSAtMTsKKyAgICBTdHJpbmcgbWVzc2FnZSA9ICIiOworICAgIHRyeSB7CisgICAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBjaGVja3N1bSk7CisgICAgICB0cnkgKElucHV0U3RyZWFtIGluID0gZmlsZVN0b3JhZ2Uub3Blbihkb3dubG9hZEZpbGVPbkRldmljZVVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSk7CisgICAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IGZpbGVTdG9yYWdlLm9wZW4oYmxvYlVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICAgIEJ5dGVTdHJlYW1zLmNvcHkoaW4sIG91dCk7CisgICAgICB9CisgICAgfSBjYXRjaCAoVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbiBlKSB7CisgICAgICBTdHJpbmcgbXNnID0gVGV4dFV0aWxzLmlzRW1wdHkoZS5nZXRNZXNzYWdlKCkpID8gIiIgOiBlLmdldE1lc3NhZ2UoKTsKKyAgICAgIExvZ1V0aWwudigKKyAgICAgICAgICAiJXM6IEZhaWxlZCB0byBzaGFyZSBhZnRlciBkb3dubG9hZCBmb3IgZmlsZSAlcywgZmlsZSBncm91cCAlcy4iCisgICAgICAgICAgICAgICsgIiBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uIHdhcyB0aHJvd24gd2l0aCBtZXNzYWdlIFwiJXNcIiIsCisgICAgICAgICAgVEFHLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpLCBtc2cpOworICAgICAgZXJyb3JDb2RlID0gMDsKKyAgICAgIG1lc3NhZ2UgPSAiVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbiB3YXMgdGhyb3duOiAiICsgbXNnOworICAgIH0gY2F0Y2ggKExpbWl0RXhjZWVkZWRFeGNlcHRpb24gZSkgeworICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICIlczogRmFpbGVkIHRvIHNoYXJlIGFmdGVyIGRvd25sb2FkIGZvciBmaWxlICVzLCBmaWxlIGdyb3VwICVzIGR1ZSB0byIKKyAgICAgICAgICAgICAgKyAiIExpbWl0RXhjZWVkZWRFeGNlcHRpb24iLAorICAgICAgICAgIFRBRywgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICBlcnJvckNvZGUgPSAwOworICAgICAgbWVzc2FnZSA9CisgICAgICAgICAgU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAgICAgIlN5c3RlbSBsaW1pdCBleGNlZWRlZCBmb3IgZmlsZSAlcywgZ3JvdXAgJXMiLAorICAgICAgICAgICAgICBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICB9IGNhdGNoIChNYWxmb3JtZWRVcmlFeGNlcHRpb24gZSkgeworICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICIlczogTWFsZm9ybWVkIGxlYXNlIHVyaSBmaWxlICVzLCBmaWxlIGdyb3VwICVzIiwKKyAgICAgICAgICBUQUcsIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgZXJyb3JDb2RlID0gMDsKKyAgICAgIG1lc3NhZ2UgPQorICAgICAgICAgIFN0cmluZy5mb3JtYXQoCisgICAgICAgICAgICAgICJNYWxmb3JtZWQgYmxvYiBVcmkgZm9yIGZpbGUgJXMsIGdyb3VwICVzIiwKKyAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgTG9nVXRpbC5lKAorICAgICAgICAgICIlczogRmFpbGVkIHRvIGNvcHkgdG8gdGhlIGJsb2JzdG9yZSBhZnRlciBkb3dubG9hZCBmb3IgZmlsZSAlcywgZmlsZSBncm91cCIgKyAiICVzIiwKKyAgICAgICAgICBUQUcsIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgZXJyb3JDb2RlID0gYWZ0ZXJEb3dubG9hZCA/IDAgOiAwOworICAgICAgbWVzc2FnZSA9CisgICAgICAgICAgU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAgICAgIkVycm9yIHdoaWxlIGNvcHlpbmcgZmlsZSAlcywgZ3JvdXAgJXMsIHRvIHRoZSBzaGFyZWQgYmxvYiBzdG9yYWdlIiwKKyAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgfQorICAgIGlmIChlcnJvckNvZGUgIT0gLTEpIHsKKyAgICAgIHRocm93IG5ldyBBbmRyb2lkU2hhcmluZ0V4Y2VwdGlvbihlcnJvckNvZGUsIG1lc3NhZ2UpOworICAgIH0KKyAgfQorCisgIC8qKiBBY3F1aXJlcyB0aGUgbGVhc2Ugb24gdGhlIHNoYXJlZCB7QGNvZGUgZGF0YUZpbGV9LiAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgYWNxdWlyZUxlYXNlKAorICAgICAgQ29udGV4dCBjb250ZXh0LAorICAgICAgU3RyaW5nIGNoZWNrc3VtLAorICAgICAgbG9uZyBleHBpcnlEYXRlLAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCwKKyAgICAgIERhdGFGaWxlIGRhdGFGaWxlLAorICAgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZSkKKyAgICAgIHRocm93cyBBbmRyb2lkU2hhcmluZ0V4Y2VwdGlvbiB7CisgICAgaW50IGVycm9yQ29kZSA9IC0xOworICAgIFN0cmluZyBtZXNzYWdlID0gIiI7CisgICAgdHJ5IHsKKyAgICAgIFVyaSBsZWFzZVVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlN0b3JlTGVhc2VVcmkoY29udGV4dCwgY2hlY2tzdW0sIGV4cGlyeURhdGUpOworICAgICAgLy8gQWNxdWlyZXMvdXBkYXRlcyB0aGUgbGVhc2UgdG8gdGhlIGJsb2IuCisgICAgICAvLyBUT0RPKGIvMTQ5MjYwNDk2KTogY2F0Y2ggTGltaXRFeGNlZWRlZEV4Y2VwdGlvbiwgdGhyb3duIHdoZW4gYSBsZWFzZSBjb3VsZCBub3QgYmUgYWNxdWlyZWQsCisgICAgICAvLyBzdWNoIGFzIHdoZW4gdGhlIGNhbGxlciBpcyB0cnlpbmcgdG8gYWNxdWlyZSBsZWFzZXMgb24gdG9vIG11Y2ggZGF0YS4KKyAgICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IGZpbGVTdG9yYWdlLm9wZW4obGVhc2VVcmksIFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkge30KKworICAgIH0gY2F0Y2ggKFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24gZSkgeworICAgICAgU3RyaW5nIG1zZyA9IFRleHRVdGlscy5pc0VtcHR5KGUuZ2V0TWVzc2FnZSgpKSA/ICIiIDogZS5nZXRNZXNzYWdlKCk7CisgICAgICBMb2dVdGlsLnYoCisgICAgICAgICAgIiVzOiBGYWlsZWQgdG8gc2hhcmUgZmlsZSAlcywgZmlsZSBncm91cCAlcy4iCisgICAgICAgICAgICAgICsgIiBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uIHdhcyB0aHJvd24gd2l0aCBtZXNzYWdlIFwiJXNcIiIsCisgICAgICAgICAgVEFHLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpLCBtc2cpOworICAgICAgZXJyb3JDb2RlID0gMDsKKyAgICAgIG1lc3NhZ2UgPSAiVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbiB3YXMgdGhyb3duOiAiICsgbXNnOworICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVyaUV4Y2VwdGlvbiBlKSB7CisgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgIiVzOiBNYWxmb3JtZWQgbGVhc2UgdXJpIGZpbGUgJXMsIGZpbGUgZ3JvdXAgJXMiLAorICAgICAgICAgIFRBRywgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICBlcnJvckNvZGUgPSAwOworICAgICAgbWVzc2FnZSA9CisgICAgICAgICAgU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAgICAgIk1hbGZvcm1lZCBsZWFzZSBVcmkgZm9yIGZpbGUgJXMsIGdyb3VwICVzIiwKKyAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgfSBjYXRjaCAoTGltaXRFeGNlZWRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgIiVzOiBGYWlsZWQgdG8gc2hhcmUgYWZ0ZXIgZG93bmxvYWQgZm9yIGZpbGUgJXMsIGZpbGUgZ3JvdXAgJXMgZHVlIHRvIgorICAgICAgICAgICAgICArICIgTGltaXRFeGNlZWRlZEV4Y2VwdGlvbiIsCisgICAgICAgICAgVEFHLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgIGVycm9yQ29kZSA9IDA7CisgICAgICBtZXNzYWdlID0KKyAgICAgICAgICBTdHJpbmcuZm9ybWF0KAorICAgICAgICAgICAgICAiU3lzdGVtIGxpbWl0IGV4Y2VlZGVkIGZvciBmaWxlICVzLCBncm91cCAlcyIsCisgICAgICAgICAgICAgIGRhdGFGaWxlLmdldEZpbGVJZCgpLCBmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAiJXM6IEZhaWxlZCB0byBhY3F1aXJlIGxlYXNlIGZvciBmaWxlICVzLCBmaWxlIGdyb3VwIiArICIgJXMiLAorICAgICAgICAgIFRBRywgZGF0YUZpbGUuZ2V0RmlsZUlkKCksIGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICBlcnJvckNvZGUgPSAwOworICAgICAgbWVzc2FnZSA9CisgICAgICAgICAgU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAgICAgIkVycm9yIHdoaWxlIGFjcXVpcmluZyBsZWFzZSBmb3IgZmlsZSAlcywgZ3JvdXAgJXMiLAorICAgICAgICAgICAgICBkYXRhRmlsZS5nZXRGaWxlSWQoKSwgZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICB9CisgICAgaWYgKGVycm9yQ29kZSAhPSAtMSkgeworICAgICAgdGhyb3cgbmV3IEFuZHJvaWRTaGFyaW5nRXhjZXB0aW9uKGVycm9yQ29kZSwgbWVzc2FnZSk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGU1ZTg0NAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9CVUlMRApAQCAtMCwwICsxLDE1OSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWyIvLzpfX3N1YnBhY2thZ2VzX18iXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkVpdGhlciIsCisgICAgc3JjcyA9IFsiRWl0aGVyLmphdmEiXSwKKyAgICBkZXBzID0gWyJAb3JnX2NoZWNrZXJmcmFtZXdvcmtfcXVhbCJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJTaGFyZWRQcmVmZXJlbmNlc1V0aWwiLAorICAgIHNyY3MgPSBbIlNoYXJlZFByZWZlcmVuY2VzVXRpbC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2Vycm9ycHJvbmVfZXJyb3JfcHJvbmVfYW5ub3RhdGlvbnMiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzpwcm90b2J1Zl9saXRlIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJBbmRyb2lkU2hhcmluZ1V0aWwiLAorICAgIHNyY3MgPSBbIkFuZHJvaWRTaGFyaW5nVXRpbC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpEaXJlY3RvcnlVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnN0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkZpbGVHcm91cFV0aWwiLAorICAgIHNyY3MgPSBbIkZpbGVHcm91cFV0aWwuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6RGlyZWN0b3J5VXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6VGltZVNvdXJjZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnJlY3Vyc2l2ZV9kZWxldGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOk1kZENvbnN0YW50cyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9jb2RlX2ZpbmRidWdzX2pzcjMwNSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiRmlsZUdyb3Vwc01ldGFkYXRhVXRpbCIsCisgICAgc3JjcyA9IFsiRmlsZUdyb3Vwc01ldGFkYXRhVXRpbC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ1V0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpQcm90b0xpdGVVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOlNoYXJlZFByZWZlcmVuY2VzVXRpbCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAY29tX2dvb2dsZV9wcm90b2J1Zi8vOnByb3RvYnVmX2xpdGUiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkZ1dHVyZXNVdGlsIiwKKyAgICBzcmNzID0gWyJGdXR1cmVzVXRpbC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9hbm5vdGF0aW9uczpTZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJEaXJlY3RvcnlVdGlsIiwKKyAgICBzcmNzID0gWyJEaXJlY3RvcnlVdGlsLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOlNpbGVudEZlZWRiYWNrIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFuZHJvaWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YmxvYl91cmkiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIlByb3RvTGl0ZVV0aWwiLAorICAgIHNyY3MgPSBbIlByb3RvTGl0ZVV0aWwuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICJAYW5kcm9pZHhfYW5ub3RhdGlvbl9hbm5vdGF0aW9uIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86cHJvdG9idWZfbGl0ZSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiUHJvdG9Db252ZXJzaW9uVXRpbCIsCisgICAgc3JjcyA9IFsiUHJvdG9Db252ZXJzaW9uVXRpbC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86cHJvdG9idWZfbGl0ZSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwiLAorICAgIHNyY3MgPSBbIlNoYXJlZEZpbGVzTWV0YWRhdGFVdGlsLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOlNpbGVudEZlZWRiYWNrIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpNZGRDb25zdGFudHMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOk1pZ3JhdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpTaGFyZWRQcmVmZXJlbmNlc1V0aWwiLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86cHJvdG9idWZfbGl0ZSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiU3ltbGlua1V0aWwiLAorICAgIHNyY3MgPSBbIlN5bWxpbmtVdGlsLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczphbmRyb2lkX2FkYXB0ZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk1kZExpdGVDb252ZXJzaW9uVXRpbCIsCisgICAgc3JjcyA9IFsiTWRkTGl0ZUNvbnZlcnNpb25VdGlsLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOnNpbmdsZV9maWxlX2ludGVyZmFjZXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGU6RG93bmxvYWRMaXN0ZW5lciIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9EaXJlY3RvcnlVdGlsLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRGlyZWN0b3J5VXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyMmI0MjEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRGlyZWN0b3J5VXRpbC5qYXZhCkBAIC0wLDAgKzEsMjAzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWR4LmFubm90YXRpb24uVmlzaWJsZUZvclRlc3Rpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuU2lsZW50RmVlZGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5BbmRyb2lkVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuQmxvYlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlByZWNvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwSW50ZXJuYWwuQWxsb3dlZFJlYWRlcnM7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworCisvKiogVXRpbHMgdG8gaGVscCB3aXRoIGRpcmVjdG9yeSBtYW5pcHVsYXRpb24uICovCitwdWJsaWMgY2xhc3MgRGlyZWN0b3J5VXRpbCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJEaXJlY3RvcnlVdGlsIjsKKyAgLy8gQ29ycmVzcG9uZCB0byBNb2JTdG9yZSBVcmkgY29tcG9uZW50cy4KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUREX1NUT1JBR0VfTU9EVUxFID0gImRhdGFkb3dubG9hZCI7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1ERF9NQU5JRkVTVF9NT0RVTEUgPSAiZGF0YWRvd25sb2FkbWFuaWZlc3QiOworICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfU1RPUkFHRV9BTExfR09PR0xFX0FQUFMgPSAicHVibGljIjsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUREX1NUT1JBR0VfT05MWV9HT09HTEVfUExBWV9TRVJWSUNFUyA9ICJwcml2YXRlIjsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUREX1NUT1JBR0VfU1lNTElOS1MgPSAibGlua3MiOworICBAVmlzaWJsZUZvclRlc3Rpbmcgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfU1RPUkFHRV9BTExfQVBQUyA9ICJwdWJsaWNfM3AiOworCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSB0b3AtbGV2ZWwgZGlyZWN0b3J5IHVyaSBmb3IgYWxsIE1ERCBkb3dubG9hZHMuIEluZGl2aWR1YWwgZmlsZXMgc2hvdWxkIG5vdCBiZQorICAgKiBwbGFjZWQgaGVyZTsgaW5zdGVhZCwgdXNlIHtAbGluayAjZ2V0RG93bmxvYWREaXJlY3RvcnkoQ29udGV4dCwgQWxsb3dlZFJlYWRlcnMpfS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgVXJpIGdldEJhc2VEb3dubG9hZERpcmVjdG9yeShDb250ZXh0IGNvbnRleHQsIE9wdGlvbmFsPFN0cmluZz4gaW5zdGFuY2VJZCkgeworICAgIEFuZHJvaWRVcmkuQnVpbGRlciBidWlsZGVyID0KKyAgICAgICAgQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpCisgICAgICAgICAgICAuc2V0TW9kdWxlKAorICAgICAgICAgICAgICAgIGluc3RhbmNlSWQgIT0gbnVsbCAmJiBpbnN0YW5jZUlkLmlzUHJlc2VudCgpCisgICAgICAgICAgICAgICAgICAgID8gaW5zdGFuY2VJZC5nZXQoKQorICAgICAgICAgICAgICAgICAgICA6IE1ERF9TVE9SQUdFX01PRFVMRSk7CisKKyAgICBpZiAoaW5zdGFuY2VJZCAhPSBudWxsICYmIGluc3RhbmNlSWQuaXNQcmVzZW50KCkpIHsKKyAgICAgIGJ1aWxkZXIuc2V0UmVsYXRpdmVQYXRoKE1ERF9TVE9SQUdFX01PRFVMRSk7CisgICAgfQorCisgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSBiYXNlIGRpcmVjdG9yeSB3aGVyZSBNREQgc3RvcmVzIG1hbmlmZXN0IGZpbGVzLiBJZiBpbnN0YW5jZUlkIGlzIGFic2VudCwgYSBzaGFyZWQKKyAgICogZGlyZWN0b3J5IGlzIHJldHVybmVkOyBvdGhlcndpc2UsIGEgc3RhbmRhbG9uZSBkaXJlY3Rvcnkgd2l0aCBpbnN0YW5jZUlkIGFzIGl0cyByZWxhdGl2ZSBwYXRoCisgICAqIGlzIHJldHVybmVkLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBVcmkgZ2V0TWFuaWZlc3REaXJlY3RvcnkoQ29udGV4dCBjb250ZXh0LCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQpIHsKKyAgICBQcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChpbnN0YW5jZUlkKTsKKworICAgIHJldHVybiBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkKKyAgICAgICAgLnNldE1vZHVsZShNRERfTUFOSUZFU1RfTU9EVUxFKQorICAgICAgICAuc2V0UmVsYXRpdmVQYXRoKGluc3RhbmNlSWQub3IoTUREX1NUT1JBR0VfTU9EVUxFKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgIH0KKworICAvKiogUmV0dXJucyB0aGUgZGlyZWN0b3J5IHVyaSBmb3IgbWRkIGRvd25sb2FkIGJhc2VkIG9uIHRoZSBhbGxvd2VkIHJlYWRlcnMuICovCisgIHB1YmxpYyBzdGF0aWMgVXJpIGdldERvd25sb2FkRGlyZWN0b3J5KAorICAgICAgQ29udGV4dCBjb250ZXh0LCBBbGxvd2VkUmVhZGVycyBhbGxvd2VkUmVhZGVycywgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkKSB7CisgICAgU3RyaW5nIHN1YkRpcmVjdG9yeSA9IGdldFN1YkRpcmVjdG9yeShhbGxvd2VkUmVhZGVycyk7CisgICAgcmV0dXJuIGdldEJhc2VEb3dubG9hZERpcmVjdG9yeShjb250ZXh0LCBpbnN0YW5jZUlkKQorICAgICAgICAuYnVpbGRVcG9uKCkKKyAgICAgICAgLmFwcGVuZFBhdGgoc3ViRGlyZWN0b3J5KQorICAgICAgICAuYnVpbGQoKTsKKyAgfQorCisgIC8qKiBSZXR1cm5zIHRoZSBkaXJlY3RvcnkgdXJpIGJhc2UgZm9yIG1kZCBzeW1saW5rcy4gKi8KKyAgcHVibGljIHN0YXRpYyBVcmkgZ2V0QmFzZURvd25sb2FkU3ltbGlua0RpcmVjdG9yeShDb250ZXh0IGNvbnRleHQsIE9wdGlvbmFsPFN0cmluZz4gaW5zdGFuY2VJZCkgeworICAgIHJldHVybiBnZXRCYXNlRG93bmxvYWREaXJlY3RvcnkoY29udGV4dCwgaW5zdGFuY2VJZCkKKyAgICAgICAgLmJ1aWxkVXBvbigpCisgICAgICAgIC5hcHBlbmRQYXRoKE1ERF9TVE9SQUdFX1NZTUxJTktTKQorICAgICAgICAuYnVpbGQoKTsKKyAgfQorCisgIC8qKiBSZXR1cm5zIHRoZSBkaXJlY3RvcnkgdXJpIGZvciBtZGQgc3ltbGlua3MgYmFzZWQgb24gdGhlIGFsbG93ZWQgcmVhZGVycy4gKi8KKyAgcHVibGljIHN0YXRpYyBVcmkgZ2V0RG93bmxvYWRTeW1saW5rRGlyZWN0b3J5KAorICAgICAgQ29udGV4dCBjb250ZXh0LCBBbGxvd2VkUmVhZGVycyBhbGxvd2VkUmVhZGVycywgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkKSB7CisgICAgU3RyaW5nIHN1YkRpcmVjdG9yeSA9IGdldFN1YkRpcmVjdG9yeShhbGxvd2VkUmVhZGVycyk7CisgICAgcmV0dXJuIGdldEJhc2VEb3dubG9hZFN5bWxpbmtEaXJlY3RvcnkoY29udGV4dCwgaW5zdGFuY2VJZCkKKyAgICAgICAgLmJ1aWxkVXBvbigpCisgICAgICAgIC5hcHBlbmRQYXRoKHN1YkRpcmVjdG9yeSkKKyAgICAgICAgLmJ1aWxkKCk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB0aGUgb24gZGV2aWNlIHVyaSBmb3IgdGhlIHNwZWNpZmllZCBmaWxlLgorICAgKgorICAgKiBAcGFyYW0gYW5kcm9pZFNoYXJlZCBpZiBzZXRzIHRvIHRydWUsIHtAY29kZSBnZXRPbkRldmljZVVyaX0gcmV0dXJucyB0aGUgImJsb2JzdG9yZSIgc2NoZW1lCisgICAqICAgICBVUkksIG90aGVyd2lzZSBpdCByZXR1cm5zIHRoZSAiYW5kcm9pZCIgc2NoZW1lIFVSSS4KKyAgICovCisgIC8vIFRPRE8oYi8xMTgxMzc2NzIpOiBnZXRPbkRldmljZVVyaSBzaG91bGRuJ3QgcmV0dXJuIG51bGwgb24gZXJyb3IuCisgIEBOdWxsYWJsZQorICBwdWJsaWMgc3RhdGljIFVyaSBnZXRPbkRldmljZVVyaSgKKyAgICAgIENvbnRleHQgY29udGV4dCwKKyAgICAgIEFsbG93ZWRSZWFkZXJzIGFsbG93ZWRSZWFkZXJzLAorICAgICAgU3RyaW5nIGZpbGVOYW1lLAorICAgICAgU3RyaW5nIGNoZWNrc3VtLAorICAgICAgU2lsZW50RmVlZGJhY2sgc2lsZW50RmVlZGJhY2ssCisgICAgICBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQsCisgICAgICBib29sZWFuIGFuZHJvaWRTaGFyZWQpIHsKKworICAgIHRyeSB7CisgICAgICBpZiAoYW5kcm9pZFNoYXJlZCkgeworICAgICAgICByZXR1cm4gZ2V0QmxvYlVyaShjb250ZXh0LCBjaGVja3N1bSk7CisgICAgICB9CisgICAgICBVcmkgZGlyZWN0b3J5VXJpID0gZ2V0RG93bmxvYWREaXJlY3RvcnkoY29udGV4dCwgYWxsb3dlZFJlYWRlcnMsIGluc3RhbmNlSWQpOworICAgICAgcmV0dXJuIGRpcmVjdG9yeVVyaS5idWlsZFVwb24oKS5hcHBlbmRQYXRoKGZpbGVOYW1lKS5idWlsZCgpOworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CisgICAgICAvLyBDYXRjaCBhbGwgZXhjZXB0aW9ucyBoZXJlIGFzIHRoZSBhYm92ZSBjb2RlIGNhbiB0aHJvdyBhbiBleGNlcHRpb24gaWYKKyAgICAgIC8vIGNvbnRleHQuZ2V0RmlsZXNEaXIgcmV0dXJucyBudWxsLgorICAgICAgTG9nVXRpbC5lKGUsICIlczogVW5hYmxlIHRvIGNyZWF0ZSBtb2JzdG9yZSB1cmkgZm9yIGZpbGUgJXMuIiwgVEFHLCBmaWxlTmFtZSk7CisgICAgICBzaWxlbnRGZWVkYmFjay5zZW5kKGUsICJVbmFibGUgdG8gY3JlYXRlIG1vYnN0b3JlIHVyaSBmb3IgZmlsZSIpOworCisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyB0aGUgImJsb2JzdG9yZSIgc2NoZW1lIFVSSSBvZiB0aGUgZmlsZSB3aXRoIGZpbmFsIGNoZWNrc3VtIHtAY29kZSBjaGVja3N1bX0uCisgICAqCisgICAqIDx1bD4KKyAgICogICBJbiBvcmRlciB0byBiZSBhYmxlIHRvIGFjY2VzcyB0aGUgZmlsZSBpbiB0aGUgYmxvYiBzdG9yZSwgdGhlIGNoZWNrc3VtIG5lZWRzIHRvIGNvbXBseSB0byB0aGUKKyAgICogICBmb2xsb3dpbmcgcnVsZXM6CisgICAqICAgPGxpPmF0IHRoZSBtb21lbnQsIG9ubHkgY2hlY2tzdW1zIG9mIHR5cGUgU0hBMjU2IGFyZSBhY2NlcHRlZC4KKyAgICogICA8bGk+dGhlIGNoZWNrc3VtIG11c3QgYmUgdGhlIGZpbGUgZmluYWwgY2hlY2tzdW0sIGkuZS4gYWZ0ZXIgdGhlIGRvd25sb2FkIHRyYW5zZm9ybXMgaGF2ZQorICAgKiAgICAgICBiZWVuIGFwcGxpZWQgaWYgYW55LgorICAgKiA8L3VsPgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBVcmkgZ2V0QmxvYlVyaShDb250ZXh0IGNvbnRleHQsIFN0cmluZyBjaGVja3N1bSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEJsb2JQYXJhbWV0ZXJzKGNoZWNrc3VtKS5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMgdGhlICJibG9ic3RvcmUiIHNjaGVtZSBVUkkgdXNlZCB0byBhY3F1aXJlIGEgbGVhc2Ugb24gdGhlIGZpbGUgd2l0aCBmaW5hbCBjaGVja3N1bQorICAgKiB7QGNvZGUgY2hlY2tzdW19LgorICAgKgorICAgKiA8dWw+CisgICAqICAgSW4gb3JkZXIgdG8gYmUgYWJsZSB0byBhY3F1aXJlIHRoZSBsZWFzZSBvZiB0aGUgZmlsZSBpbiB0aGUgYmxvYiBzdG9yZSwgdGhlIGNoZWNrc3VtIG5lZWRzIHRvCisgICAqICAgY29tcGx5IHRvIHRoZSBmb2xsb3dpbmcgcnVsZXM6CisgICAqICAgPGxpPmF0IHRoZSBtb21lbnQsIG9ubHkgY2hlY2tzdW1zIG9mIHR5cGUgU0hBMjU2IGFyZSBhY2NlcHRlZC4KKyAgICogICA8bGk+dGhlIGNoZWNrc3VtIG11c3QgYmUgdGhlIGZpbGUgZmluYWwgY2hlY2tzdW0sIGkuZS4gZm9yIGZpbGVzIHdpdGggZG93bmxvYWRfdHJhbnNmb3JtLCBpdAorICAgKiAgICAgICBzaG91bGQgY29udGFpbiB0aGUgdHJhbnNmb3JtIG9mIHRoZSBmaWxlIGFmdGVyIHRoZSB0cmFuc2Zvcm1zIGhhdmUgYmVlbiBhcHBsaWVkLgorICAgKiA8L3VsPgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBVcmkgZ2V0QmxvYlN0b3JlTGVhc2VVcmkoQ29udGV4dCBjb250ZXh0LCBTdHJpbmcgY2hlY2tzdW0sIGxvbmcgZXhwaXJ5RGF0ZVNlY3MpCisgICAgICB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHJldHVybiBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0TGVhc2VQYXJhbWV0ZXJzKGNoZWNrc3VtLCBleHBpcnlEYXRlU2VjcykuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSAiYmxvYnN0b3JlIiBzY2hlbWUgVVJJIHVzZWQgdG8gcmVsZWFzZSBhbGwgdGhlIGxlYXNlcyBvd25lZCBieSB0aGUgY2FsbGluZyBwYWNrYWdlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBVcmkgZ2V0QmxvYlN0b3JlQWxsTGVhc2VzVXJpKENvbnRleHQgY29udGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEFsbExlYXNlc1BhcmFtZXRlcnMoKS5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIFJldHVybnMge0Bjb2RlIGJhc2VuYW1lLmV4dGVuc2lvbn0sIHdpdGgge0Bjb2RlIGluc3RhbmNlSWR9IGFwcGVuZGVkIHRvIGJhc2VuYW1lIGlmIHByZXNlbnQuCisgICAqCisgICAqIDxwPlVzZWZ1bCBmb3IgYnVpbGRpbmcgZmlsZW5hbWVzIHRoYXQgbXVzdCBiZSBkaXN0aW5ndWlzaGVkIGJ5IEluc3RhbmNlSWQgd2hpbGUga2VlcGluZyB0aGUKKyAgICogc2FtZSBiYXNlbmFtZSBhbmQgZmlsZSBleHRlbnNpb24uCisgICAqLworICBwdWJsaWMgc3RhdGljIFN0cmluZyBidWlsZEZpbGVuYW1lKAorICAgICAgU3RyaW5nIGJhc2VuYW1lLCBTdHJpbmcgZXh0ZW5zaW9uLCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQpIHsKKyAgICBTdHJpbmcgcmVzdWx0QmFzZW5hbWUgPSBiYXNlbmFtZTsKKyAgICBpZiAoaW5zdGFuY2VJZCAhPSBudWxsICYmIGluc3RhbmNlSWQuaXNQcmVzZW50KCkpIHsKKyAgICAgIHJlc3VsdEJhc2VuYW1lICs9IGluc3RhbmNlSWQuZ2V0KCk7CisgICAgfQorICAgIHJldHVybiByZXN1bHRCYXNlbmFtZSArICIuIiArIGV4dGVuc2lvbjsKKyAgfQorCisgIC8qKiBDb252ZW5pZW5jZSBtZXRob2QgdG8gZ2V0IHRoZSBzdG9yYWdlIHN1YmRpcmVjdG9yeSBiYXNlZCBvbiB0aGUgYWxsb3dlZCByZWFkZXJzLiAqLworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0U3ViRGlyZWN0b3J5KEFsbG93ZWRSZWFkZXJzIGFsbG93ZWRSZWFkZXJzKSB7CisgICAgc3dpdGNoIChhbGxvd2VkUmVhZGVycykgeworICAgICAgY2FzZSBBTExfR09PR0xFX0FQUFM6CisgICAgICAgIHJldHVybiBNRERfU1RPUkFHRV9BTExfR09PR0xFX0FQUFM7CisgICAgICBjYXNlIE9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVM6CisgICAgICAgIHJldHVybiBNRERfU1RPUkFHRV9PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTOworICAgICAgY2FzZSBBTExfQVBQUzoKKyAgICAgICAgcmV0dXJuIE1ERF9TVE9SQUdFX0FMTF9BUFBTOworICAgIH0KKyAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJpbnZhbGlkIGFsbG93ZWQgcmVhZGVycyB2YWx1ZSIpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRWl0aGVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRWl0aGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTgwZjc5ZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9FaXRoZXIuamF2YQpAQCAtMCwwICsxLDExNCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbDsKKworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgb3JnLmNoZWNrZXJmcmFtZXdvcmsuY2hlY2tlci5udWxsbmVzcy5xdWFsLk51bGxhYmxlOworCisvKiogQW4gb2JqZWN0IHRoYXQgY29udGFpbnMgZWl0aGVyIG9uZSBvZiB0aGUgbGVmdCBmaWVsZCBvciByaWdodCBmaWVsZCwgYnV0IG5vdCBib3RoLiAqLworcHVibGljIGZpbmFsIGNsYXNzIEVpdGhlcjxBLCBCPiB7CisKKyAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIGhhc0xlZnQ7CisgIHByaXZhdGUgZmluYWwgQE51bGxhYmxlIEEgbGVmdDsKKyAgcHJpdmF0ZSBmaW5hbCBATnVsbGFibGUgQiByaWdodDsKKworICBwcml2YXRlIEVpdGhlcihib29sZWFuIGhhc0xlZnQsIEBOdWxsYWJsZSBBIGxlZnQsIEBOdWxsYWJsZSBCIHJpZ2h0KSB7CisgICAgdGhpcy5oYXNMZWZ0ID0gaGFzTGVmdDsKKyAgICB0aGlzLmxlZnQgPSBsZWZ0OworICAgIHRoaXMucmlnaHQgPSByaWdodDsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgPEEsIEI+IEVpdGhlcjxBLCBCPiBtYWtlTGVmdChBIGxlZnQpIHsKKyAgICByZXR1cm4gbmV3IEVpdGhlcjw+KHRydWUsIGxlZnQsIG51bGwpOworICB9CisKKyAgcHVibGljIHN0YXRpYyA8QSwgQj4gRWl0aGVyPEEsIEI+IG1ha2VSaWdodChCIHJpZ2h0KSB7CisgICAgcmV0dXJuIG5ldyBFaXRoZXI8PihmYWxzZSwgbnVsbCwgcmlnaHQpOworICB9CisKKyAgcHVibGljIGJvb2xlYW4gaGFzTGVmdCgpIHsKKyAgICByZXR1cm4gaGFzTGVmdDsKKyAgfQorCisgIHB1YmxpYyBib29sZWFuIGhhc1JpZ2h0KCkgeworICAgIHJldHVybiAhaGFzTGVmdDsKKyAgfQorCisgIHB1YmxpYyBATnVsbGFibGUgQSBnZXRMZWZ0KCkgeworICAgIGlmICghaGFzTGVmdCgpKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJFaXRoZXIgd2FzIG5vdCBsZWZ0Iik7CisgICAgfQorICAgIHJldHVybiBsZWZ0OworICB9CisKKyAgcHVibGljIEBOdWxsYWJsZSBCIGdldFJpZ2h0KCkgeworICAgIGlmICghaGFzUmlnaHQoKSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRWl0aGVyIHdhcyBub3QgcmlnaHQiKTsKKyAgICB9CisgICAgcmV0dXJuIHJpZ2h0OworICB9CisKKyAgQE92ZXJyaWRlCisgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQorICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoQE51bGxhYmxlIE9iamVjdCBvYmopIHsKKyAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBFaXRoZXIpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIEVpdGhlcjxBLCBCPiBlaXRoZXIgPSAoRWl0aGVyPEEsIEI+KSBvYmo7CisgICAgaWYgKGhhc0xlZnQoKSkgeworICAgICAgcmV0dXJuIGVpdGhlci5oYXNMZWZ0KCkgJiYgZXF1YWxzKGdldExlZnQoKSwgZWl0aGVyLmdldExlZnQoKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBlaXRoZXIuaGFzUmlnaHQoKSAmJiBlcXVhbHMoZ2V0UmlnaHQoKSwgZWl0aGVyLmdldFJpZ2h0KCkpOworICAgIH0KKyAgfQorCisgIC8qKiBDb21wYXJlcyB0d28gTGlzdC1iYXNlZCBFaXRoZXIgYnkgKGEgY29weSBvZikgdGhlaXIgc29ydGVkIGlubmVyIExpc3QuICovCisgIHB1YmxpYyBzdGF0aWMgPEEsIEI+IGJvb2xlYW4gc29ydGVkRXF1YWxzKAorICAgICAgQE51bGxhYmxlIEVpdGhlcjxMaXN0PEE+LCBCPiBmaXJzdCwKKyAgICAgIEBOdWxsYWJsZSBFaXRoZXI8TGlzdDxBPiwgQj4gc2Vjb25kLAorICAgICAgQ29tcGFyYXRvcjxBPiBjb21wYXJhdG9yRm9yU29ydGluZykgeworICAgIC8vIE9ubHkgc29ydCBpZiB0aGUgTGlzdHMgd2lsbCBhY3R1YWxseSBiZSBjb21wYXJlZC4gVGhpcyB1c2VzIGZpbmFsIHZhcmlhYmxlICJsZWZ0IiByYXRoZXIgdGhhbgorICAgIC8vIGdldExlZnQoKSAod2hpY2ggImNvdWxkIiBjaGFuZ2UgYmV0d2VlbiBpbnZvY2F0aW9ucykgdG8gc2F0aXNmeSB0aGUgTnVsbG5lc3MgQ2hlY2tlci4KKyAgICBpZiAoZmlyc3QgIT0gbnVsbAorICAgICAgICAmJiBmaXJzdC5oYXNMZWZ0KCkKKyAgICAgICAgJiYgZmlyc3QubGVmdCAhPSBudWxsCisgICAgICAgICYmIHNlY29uZCAhPSBudWxsCisgICAgICAgICYmIHNlY29uZC5oYXNMZWZ0KCkKKyAgICAgICAgJiYgc2Vjb25kLmxlZnQgIT0gbnVsbCkgeworICAgICAgTGlzdDxBPiBzb3J0ZWRGaXJzdExlZnQgPSBuZXcgQXJyYXlMaXN0PD4oZmlyc3QubGVmdCk7CisgICAgICBMaXN0PEE+IHNvcnRlZFNlY29uZExlZnQgPSBuZXcgQXJyYXlMaXN0PD4oc2Vjb25kLmxlZnQpOworICAgICAgQ29sbGVjdGlvbnMuc29ydChzb3J0ZWRGaXJzdExlZnQsIGNvbXBhcmF0b3JGb3JTb3J0aW5nKTsKKyAgICAgIENvbGxlY3Rpb25zLnNvcnQoc29ydGVkU2Vjb25kTGVmdCwgY29tcGFyYXRvckZvclNvcnRpbmcpOworICAgICAgcmV0dXJuIHNvcnRlZEZpcnN0TGVmdC5lcXVhbHMoc29ydGVkU2Vjb25kTGVmdCk7CisgICAgfQorCisgICAgcmV0dXJuIGVxdWFscyhmaXJzdCwgc2Vjb25kKTsKKyAgfQorCisgIC8vIElubGluZSBkZWZpbml0aW9uIG9mIE9iamVjdHMuZXF1YWxzKCkgc2luY2UgaXQncyBub3QgYXZhaWxhYmxlIG9uIGFsbCBBUEkgbGV2ZWxzLgorICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZXF1YWxzKEBOdWxsYWJsZSBPYmplY3QgYSwgQE51bGxhYmxlIE9iamVjdCBiKSB7CisgICAgcmV0dXJuIChhID09IGIpIHx8IChhICE9IG51bGwgJiYgYS5lcXVhbHMoYikpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CisgICAgcmV0dXJuIEFycmF5cy5oYXNoQ29kZShuZXcgT2JqZWN0W10ge2hhc0xlZnQsIGxlZnQsIHJpZ2h0fSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9GaWxlR3JvdXBVdGlsLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRmlsZUdyb3VwVXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVlZDVkYTAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRmlsZUdyb3VwVXRpbC5qYXZhCkBAIC0wLDAgKzEsMjk2IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQuVkVSU0lPTjsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkLlZFUlNJT05fQ09ERVM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGltZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLlJlY3Vyc2l2ZURlbGV0ZU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZGRDb25zdGFudHM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5Bc2NpaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuUHJlY29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN0cmluZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVTZXQ7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZS5BbmRyb2lkU2hhcmluZ1R5cGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwQm9va2tlZXBpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwSW50ZXJuYWw7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CisKKy8qKiBBIGNvbGxlY3Rpb24gb2YgdXRpbCBtZXRob2RzIGZvciBpbnRlcmFjdGlvbiB3aXRoIGEgRGF0YUZpbGVHcm91cCBwcm90by4gKi8KK3B1YmxpYyBjbGFzcyBGaWxlR3JvdXBVdGlsIHsKKworICAvKioKKyAgICogQHJldHVybiB0aGUgZXhwaXJhdGlvbiBkYXRlIG9mIHRoaXMgYWN0aXZlIGZpbGUgZ3JvdXAgaW4gbWlsbGlzIG9yIExvbmcuTUFYX1ZBTFVFIGlmIG5vCisgICAqICAgICBleHBpcmF0aW9uIGRhdGUgaXMgc2V0LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBsb25nIGdldEV4cGlyYXRpb25EYXRlTWlsbGlzKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXApIHsKKyAgICByZXR1cm4gKGZpbGVHcm91cC5nZXRFeHBpcmF0aW9uRGF0ZVNlY3MoKSA9PSAwKQorICAgICAgICA/IExvbmcuTUFYX1ZBTFVFCisgICAgICAgIDogVGltZVVuaXQuU0VDT05EUy50b01pbGxpcyhmaWxlR3JvdXAuZ2V0RXhwaXJhdGlvbkRhdGVTZWNzKCkpOworICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gdGhlIGV4cGlyYXRpb24gZGF0ZSBvZiB0aGlzIHN0YWxlIGZpbGUgZ3JvdXAgaW4gbWlsbGlzCisgICAqLworICBwdWJsaWMgc3RhdGljIGxvbmcgZ2V0U3RhbGVFeHBpcmF0aW9uRGF0ZU1pbGxpcyhEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwKSB7CisgICAgcmV0dXJuIFRpbWVVbml0LlNFQ09ORFMudG9NaWxsaXMoZmlsZUdyb3VwLmdldEJvb2trZWVwaW5nKCkuZ2V0U3RhbGVFeHBpcmF0aW9uRGF0ZSgpKTsKKyAgfQorCisgIC8qKgorICAgKiBAcmV0dXJuIGlmIHRoZSBhY3RpdmUgZ3JvdXAncyBleHBpcmF0aW9uIGRhdGUgaGFzIHBhc3NlZC4gRmFsc2UgaWYgbm8gZXhwaXJhdGlvbiBkYXRlIGlzIHNldC4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0FjdGl2ZUdyb3VwRXhwaXJlZCgKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAsIFRpbWVTb3VyY2UgdGltZVNvdXJjZSkgeworICAgIHJldHVybiBpc0V4cGlyZWQoZ2V0RXhwaXJhdGlvbkRhdGVNaWxsaXMoZmlsZUdyb3VwKSwgdGltZVNvdXJjZSk7CisgIH0KKworICAvKioKKyAgICogQHBhcmFtIGV4cGlyYXRpb25EYXRlTWlsbGlzIHRoZSBkYXRlIChpbiBtaWxsaXMgc2luY2UgZXBvY2gpIGF0IHdoaWNoIGV4cGlyYXRpb24gc2hvdWxkIG9jY3VyLgorICAgKiBAcmV0dXJuIGlmIGV4cGlyYXRpb25EYXRlIGhhcyBwYXNzZWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNFeHBpcmVkKGxvbmcgZXhwaXJhdGlvbkRhdGVNaWxsaXMsIFRpbWVTb3VyY2UgdGltZVNvdXJjZSkgeworICAgIHJldHVybiBleHBpcmF0aW9uRGF0ZU1pbGxpcyA8PSB0aW1lU291cmNlLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyBmaWxlIGdyb3VwIGtleSB3aGljaCB1bmlxdWVseSBpZGVudGlmeSBhIGZpbGUgZ3JvdXAuCisgICAqCisgICAqIEBwYXJhbSBncm91cE5hbWUgVGhlIGZpbGUgZ3JvdXAgbmFtZQorICAgKiBAcGFyYW0gb3duZXJQYWNrYWdlIEZpbGUgR3JvdXAgb3duZXIgcGFja2FnZS4gRm9yIGxlZ2FjeSByZWFzb25zLCB0aGlzIG1pZ2h0IG5vdCBiZSBzZXQgaW4gc29tZQorICAgKiAgICAgZ3JvdXBzLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBHcm91cEtleSBjcmVhdGVHcm91cEtleShTdHJpbmcgZ3JvdXBOYW1lLCBATnVsbGFibGUgU3RyaW5nIG93bmVyUGFja2FnZSkgeworICAgIEdyb3VwS2V5LkJ1aWxkZXIgZ3JvdXBLZXkgPSBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKGdyb3VwTmFtZSk7CisKKyAgICBpZiAoU3RyaW5ncy5pc051bGxPckVtcHR5KG93bmVyUGFja2FnZSkpIHsKKyAgICAgIGdyb3VwS2V5LnNldE93bmVyUGFja2FnZShNZGRDb25zdGFudHMuR01TX1BBQ0tBR0UpOworICAgIH0gZWxzZSB7CisgICAgICBncm91cEtleS5zZXRPd25lclBhY2thZ2Uob3duZXJQYWNrYWdlKTsKKyAgICB9CisKKyAgICByZXR1cm4gZ3JvdXBLZXkuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSBEYXRhRmlsZSB3aXRoaW4gZGF0YUZpbGVHcm91cCB3aXRoIHRoZSBtYXRjaGluZyBmaWxlSWQuIG51bGwgaWYgdGhlIGdyb3VwIG5vIHN1Y2gKKyAgICogRGF0YUZpbGUgZXhpc3RzLgorICAgKi8KKyAgQE51bGxhYmxlCisgIHB1YmxpYyBzdGF0aWMgRGF0YUZpbGUgZ2V0RmlsZUZyb21Hcm91cFdpdGhJZCgKKyAgICAgIEBOdWxsYWJsZSBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCwgU3RyaW5nIGZpbGVJZCkgeworICAgIGlmIChkYXRhRmlsZUdyb3VwID09IG51bGwpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgICBmb3IgKERhdGFGaWxlIGRhdGFGaWxlIDogZGF0YUZpbGVHcm91cC5nZXRGaWxlTGlzdCgpKSB7CisgICAgICBpZiAoZmlsZUlkLmVxdWFscyhkYXRhRmlsZS5nZXRGaWxlSWQoKSkpIHsKKyAgICAgICAgcmV0dXJuIGRhdGFGaWxlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgRGF0YUZpbGVHcm91cEludGVybmFsIHNldFN0YWxlRXhwaXJhdGlvbkRhdGUoCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCwgbG9uZyB0aW1lU2luY2VFcG9jaCkgeworICAgIERhdGFGaWxlR3JvdXBCb29ra2VlcGluZyBib29ra2VlcGluZyA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0Qm9va2tlZXBpbmcoKS50b0J1aWxkZXIoKS5zZXRTdGFsZUV4cGlyYXRpb25EYXRlKHRpbWVTaW5jZUVwb2NoKS5idWlsZCgpOworICAgIGRhdGFGaWxlR3JvdXAgPSBkYXRhRmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldEJvb2trZWVwaW5nKGJvb2trZWVwaW5nKS5idWlsZCgpOworICAgIHJldHVybiBkYXRhRmlsZUdyb3VwOworICB9CisKKyAgcHVibGljIHN0YXRpYyBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgc2V0R3JvdXBOZXdGaWxlc1JlY2VpdmVkVGltZXN0YW1wKAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAsIGxvbmcgdGltZVNpbmNlRXBvY2gpIHsKKyAgICBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcgYm9va2tlZXBpbmcgPQorICAgICAgICBkYXRhRmlsZUdyb3VwLmdldEJvb2trZWVwaW5nKCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXAodGltZVNpbmNlRXBvY2gpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBkYXRhRmlsZUdyb3VwID0gZGF0YUZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRCb29ra2VlcGluZyhib29ra2VlcGluZykuYnVpbGQoKTsKKyAgICByZXR1cm4gZGF0YUZpbGVHcm91cDsKKyAgfQorCisgIC8qKiBTZXRzIHRoZSBnaXZlbiBkb3dubG9hZGVkIHRpbWVzdGFtcCBpbiB0aGUgZ2l2ZW4gZ3JvdXAgKi8KKyAgcHVibGljIHN0YXRpYyBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgc2V0RG93bmxvYWRlZFRpbWVzdGFtcEluTWlsbGlzKAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAsIGxvbmcgdGltZVNpbmNlRXBvY2hJbk1pbGxpcykgeworICAgIERhdGFGaWxlR3JvdXBCb29ra2VlcGluZyBib29ra2VlcGluZyA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0Qm9va2tlZXBpbmcoKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwRG93bmxvYWRlZFRpbWVzdGFtcEluTWlsbGlzKHRpbWVTaW5jZUVwb2NoSW5NaWxsaXMpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBkYXRhRmlsZUdyb3VwID0gZGF0YUZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRCb29ra2VlcGluZyhib29ra2VlcGluZykuYnVpbGQoKTsKKyAgICByZXR1cm4gZGF0YUZpbGVHcm91cDsKKyAgfQorCisgIC8qKiBTZXRzIHRoZSBnaXZlbiBkb3dubG9hZCBzdGFydGVkIHRpbWVzdGFtcCBpbiB0aGUgZ2l2ZW4gZ3JvdXAuICovCisgIHB1YmxpYyBzdGF0aWMgRGF0YUZpbGVHcm91cEludGVybmFsIHNldERvd25sb2FkU3RhcnRlZFRpbWVzdGFtcEluTWlsbGlzKAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAsIGxvbmcgdGltZVNpbmNlRXBvY2hJbk1pbGxpcykgeworICAgIERhdGFGaWxlR3JvdXBCb29ra2VlcGluZyBib29ra2VlcGluZyA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0Qm9va2tlZXBpbmcoKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwRG93bmxvYWRTdGFydGVkVGltZXN0YW1wSW5NaWxsaXModGltZVNpbmNlRXBvY2hJbk1pbGxpcykKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGRhdGFGaWxlR3JvdXAgPSBkYXRhRmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldEJvb2trZWVwaW5nKGJvb2trZWVwaW5nKS5idWlsZCgpOworICAgIHJldHVybiBkYXRhRmlsZUdyb3VwOworICB9CisKKyAgLyoqIFNoYXJlZCBtZXRob2QgdG8gdGVzdCB3aGV0aGVyIHRoZSBnaXZlbiBmaWxlIGdyb3VwIHN1cHBvcnRzIGlzb2xhdGVkIGZpbGUgc3RydWN0dXJlcy4gKi8KKyAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzSXNvbGF0ZWRTdHJ1Y3R1cmVBbGxvd2VkKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwSW50ZXJuYWwpIHsKKyAgICBpZiAoVkVSU0lPTi5TREtfSU5UIDwgVkVSU0lPTl9DT0RFUy5MT0xMSVBPUAorICAgICAgICB8fCAhZGF0YUZpbGVHcm91cEludGVybmFsLmdldFByZXNlcnZlRmlsZW5hbWVzQW5kSXNvbGF0ZUZpbGVzKCkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisKKyAgICAvLyBJZiBhbnkgZGF0YSBmaWxlIHVzZXMgYW5kcm9pZCBibG9iIHNoYXJpbmcsIGRvbid0IGNyZWF0ZSBpc29sYXRlZCBmaWxlIHN0cnVjdHVyZS4KKyAgICBmb3IgKERhdGFGaWxlIGRhdGFGaWxlIDogZGF0YUZpbGVHcm91cEludGVybmFsLmdldEZpbGVMaXN0KCkpIHsKKyAgICAgIGlmIChkYXRhRmlsZS5nZXRBbmRyb2lkU2hhcmluZ1R5cGUoKSA9PSBBbmRyb2lkU2hhcmluZ1R5cGUuQU5EUk9JRF9CTE9CX1dIRU5fQVZBSUxBQkxFKSB7CisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8qKgorICAgKiBHZXRzIHRoZSByb290IGRpcmVjdG9yeSB3aGVyZSBpc29sYXRlZCBmaWxlcyBzaG91bGQgYmUgd2hlbiB0aGUgZ2l2ZW4gZmlsZSBncm91cCBzdXBwb3J0cworICAgKiBwcmVzZXJ2aW5nIHJlbGF0aXZlIGZpbGUgcGF0aHMuCisgICAqLworICBwdWJsaWMgc3RhdGljIFVyaSBnZXRJc29sYXRlZFJvb3REaXJlY3RvcnkoCisgICAgICBDb250ZXh0IGNvbnRleHQsIE9wdGlvbmFsPFN0cmluZz4gaW5zdGFuY2VJZCwgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cEludGVybmFsKSB7CisgICAgcmV0dXJuIERpcmVjdG9yeVV0aWwuZ2V0RG93bmxvYWRTeW1saW5rRGlyZWN0b3J5KAorICAgICAgICAgICAgY29udGV4dCwgZmlsZUdyb3VwSW50ZXJuYWwuZ2V0QWxsb3dlZFJlYWRlcnNFbnVtKCksIGluc3RhbmNlSWQpCisgICAgICAgIC5idWlsZFVwb24oKQorICAgICAgICAuYXBwZW5kUGF0aChmaWxlR3JvdXBJbnRlcm5hbC5nZXRHcm91cE5hbWUoKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgIH0KKworICAvKioKKyAgICogR2V0cyB0aGUgaXNvbGF0ZWQgbG9jYXRpb24gb2YgYSBnaXZlbiBEYXRhRmlsZSB3aGVuIHRoZSBwYXJlbnQgZmlsZSBncm91cCBzdXBwb3J0cyBwcmVzZXJ2aW5nCisgICAqIHJlbGF0aXZlIGZpbGUgcGF0aHMuCisgICAqLworICBwdWJsaWMgc3RhdGljIFVyaSBnZXRJc29sYXRlZEZpbGVVcmkoCisgICAgICBDb250ZXh0IGNvbnRleHQsCisgICAgICBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQsCisgICAgICBEYXRhRmlsZSBkYXRhRmlsZSwKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwYXJlbnRGaWxlR3JvdXApIHsKKyAgICBVcmkuQnVpbGRlciBmaWxlVXJpQnVpbGRlciA9CisgICAgICAgIGdldElzb2xhdGVkUm9vdERpcmVjdG9yeShjb250ZXh0LCBpbnN0YW5jZUlkLCBwYXJlbnRGaWxlR3JvdXApLmJ1aWxkVXBvbigpOworICAgIGlmIChkYXRhRmlsZS5nZXRSZWxhdGl2ZUZpbGVQYXRoKCkuaXNFbXB0eSgpKSB7CisgICAgICAvLyBJZiBubyByZWxhdGl2ZSBwYXRoIHNwZWNpZmllZCBnZXQgdGhlIGxhc3Qgc2VnbWVudCBmcm9tIHRoZQorICAgICAgLy8gdXJsVG9Eb3dubG9hZC4KKyAgICAgIFN0cmluZyB1cmxUb0Rvd25sb2FkID0gZGF0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpOworICAgICAgZmlsZVVyaUJ1aWxkZXIuYXBwZW5kUGF0aCh1cmxUb0Rvd25sb2FkLnN1YnN0cmluZyh1cmxUb0Rvd25sb2FkLmxhc3RJbmRleE9mKCIvIikgKyAxKSk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFVzZSBnaXZlIHJlbGF0aXZlIHBhdGggdG8gZ2V0IHBhcnRzCisgICAgICBmb3IgKFN0cmluZyBwYXJ0IDogZGF0YUZpbGUuZ2V0UmVsYXRpdmVGaWxlUGF0aCgpLnNwbGl0KCIvIiwgLTEpKSB7CisgICAgICAgIGlmICghcGFydC5pc0VtcHR5KCkpIHsKKyAgICAgICAgICBmaWxlVXJpQnVpbGRlci5hcHBlbmRQYXRoKHBhcnQpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmaWxlVXJpQnVpbGRlci5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIFJlbW92ZXMgdGhlIGlzb2xhdGVkIGZpbGUgc3RydWN0dXJlIGZvciB0aGUgZ2l2ZW4gZmlsZSBncm91cC4KKyAgICoKKyAgICogPHA+SWYgdGhlIGlzb2xhdGVkIHN0cnVjdHVyZSBoYXMgYWxyZWFkeSBiZWVuIGRlbGV0ZWQgb3Igd2FzIG5ldmVyIGNyZWF0ZWQsIHRoaXMgbWV0aG9kIGlzIGEKKyAgICogbm8tb3AuCisgICAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgcmVtb3ZlSXNvbGF0ZWRGaWxlU3RydWN0dXJlKAorICAgICAgQ29udGV4dCBjb250ZXh0LAorICAgICAgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkLAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAsCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBVcmkgaXNvbGF0ZWRSb290RGlyID0KKyAgICAgICAgRmlsZUdyb3VwVXRpbC5nZXRJc29sYXRlZFJvb3REaXJlY3RvcnkoY29udGV4dCwgaW5zdGFuY2VJZCwgZGF0YUZpbGVHcm91cCk7CisgICAgaWYgKGZpbGVTdG9yYWdlLmV4aXN0cyhpc29sYXRlZFJvb3REaXIpKSB7CisgICAgICBWb2lkIHVudXNlZCA9IGZpbGVTdG9yYWdlLm9wZW4oaXNvbGF0ZWRSb290RGlyLCBSZWN1cnNpdmVEZWxldGVPcGVuZXIuY3JlYXRlKCkpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBoYXNaaXBEb3dubG9hZFRyYW5zZm9ybShEYXRhRmlsZSBkYXRhRmlsZSkgeworICAgIGlmIChkYXRhRmlsZS5oYXNEb3dubG9hZFRyYW5zZm9ybXMoKSkgeworICAgICAgZm9yIChUcmFuc2Zvcm0gdHJhbnNmb3JtIDogZGF0YUZpbGUuZ2V0RG93bmxvYWRUcmFuc2Zvcm1zKCkuZ2V0VHJhbnNmb3JtTGlzdCgpKSB7CisgICAgICAgIGlmICh0cmFuc2Zvcm0uaGFzWmlwKCkpIHsKKyAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gaGFzQ29tcHJlc3NEb3dubG9hZFRyYW5zZm9ybShEYXRhRmlsZSBkYXRhRmlsZSkgeworICAgIGlmIChkYXRhRmlsZS5oYXNEb3dubG9hZFRyYW5zZm9ybXMoKSkgeworICAgICAgZm9yIChUcmFuc2Zvcm0gdHJhbnNmb3JtIDogZGF0YUZpbGUuZ2V0RG93bmxvYWRUcmFuc2Zvcm1zKCkuZ2V0VHJhbnNmb3JtTGlzdCgpKSB7CisgICAgICAgIGlmICh0cmFuc2Zvcm0uaGFzQ29tcHJlc3MoKSkgeworICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEZpbGVDaGVja3N1bShEYXRhRmlsZSBkYXRhRmlsZSkgeworICAgIHJldHVybiBoYXNaaXBEb3dubG9hZFRyYW5zZm9ybShkYXRhRmlsZSkKKyAgICAgICAgPyBkYXRhRmlsZS5nZXREb3dubG9hZGVkRmlsZUNoZWNrc3VtKCkKKyAgICAgICAgOiBkYXRhRmlsZS5nZXRDaGVja3N1bSgpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzU2lkZWxvYWRlZEZpbGUoRGF0YUZpbGUgZGF0YUZpbGUpIHsKKyAgICByZXR1cm4gaXNGaWxlV2l0aE1hdGNoaW5nU2NoZW1lKAorICAgICAgICBkYXRhRmlsZSwKKyAgICAgICAgSW1tdXRhYmxlU2V0Lm9mKAorICAgICAgICAgICAgTWRkQ29uc3RhbnRzLlNJREVMT0FEX0ZJTEVfVVJMX1NDSEVNRSwgTWRkQ29uc3RhbnRzLkVNQkVEREVEX0FTU0VUX1VSTF9TQ0hFTUUpKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0lubGluZUZpbGUoRGF0YUZpbGUgZGF0YUZpbGUpIHsKKyAgICByZXR1cm4gaXNGaWxlV2l0aE1hdGNoaW5nU2NoZW1lKGRhdGFGaWxlLCBJbW11dGFibGVTZXQub2YoTWRkQ29uc3RhbnRzLklOTElORV9GSUxFX1VSTF9TQ0hFTUUpKTsKKyAgfQorCisgIC8vIEhlbHBlciBtZXRob2QgdG8gdGVzdCB3aGV0aGVyIGEgRGF0YUZpbGUncyB1cmwgc2NoZW1lIGlzIGNvbnRhaW5lZCBpbiB0aGUgZ2l2ZW4gc2NoZW1lIHNldC4KKyAgcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBpc0ZpbGVXaXRoTWF0Y2hpbmdTY2hlbWUoRGF0YUZpbGUgZGF0YUZpbGUsIEltbXV0YWJsZVNldDxTdHJpbmc+IHNjaGVtZXMpIHsKKyAgICBpZiAoIWRhdGFGaWxlLmhhc1VybFRvRG93bmxvYWQoKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICBpbnQgY29sb24gPSBkYXRhRmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkuaW5kZXhPZignOicpOworICAgIC8vIFRPRE8oYi8xOTY1OTMyNDApOiBFbnN1cmUgdGhpcyBpcyBhbHdheXMgaGFuZGxlZCwgb3IgcmVwbGFjZSB3aXRoIGEgY2hlY2tlZCBleGNlcHRpb24KKyAgICBQcmVjb25kaXRpb25zLmNoZWNrU3RhdGUoY29sb24gPiAtMSwgIkludmFsaWQgdXJsOiAlcyIsIGRhdGFGaWxlLmdldFVybFRvRG93bmxvYWQoKSk7CisgICAgU3RyaW5nIGZpbGVTY2hlbWUgPSBkYXRhRmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkuc3Vic3RyaW5nKDAsIGNvbG9uKTsKKyAgICBmb3IgKFN0cmluZyBzY2hlbWUgOiBzY2hlbWVzKSB7CisgICAgICBpZiAoQXNjaWkuZXF1YWxzSWdub3JlQ2FzZShmaWxlU2NoZW1lLCBzY2hlbWUpKSB7CisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBwdWJsaWMgc3RhdGljIGludCBnZXRJbmxpbmVGaWxlQ291bnQoRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCkgeworICAgIGludCBpbmxpbmVGaWxlQ291bnQgPSAwOworICAgIGZvciAoRGF0YUZpbGUgZmlsZSA6IGZpbGVHcm91cC5nZXRGaWxlTGlzdCgpKSB7CisgICAgICBpZiAoaXNJbmxpbmVGaWxlKGZpbGUpKSB7CisgICAgICAgIGlubGluZUZpbGVDb3VudCsrOworICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBpbmxpbmVGaWxlQ291bnQ7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9GaWxlR3JvdXBzTWV0YWRhdGFVdGlsLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRmlsZUdyb3Vwc01ldGFkYXRhVXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZkYTNiMWUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRmlsZUdyb3Vwc01ldGFkYXRhVXRpbC5qYXZhCkBAIC0wLDAgKzEsMTIwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC51dGlsLkJhc2U2NDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwSW50ZXJuYWw7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKiogU3RvcmVzIGFuZCBwcm92aWRlcyBhY2Nlc3MgdG8gZmlsZSBncm91cCBtZXRhZGF0YSB1c2luZyBTaGFyZWRQcmVmZXJlbmNlcy4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIkZpbGVHcm91cHNNZXRhZGF0YVV0aWwiOworCisgIC8vIE5hbWUgb2YgZmlsZSBncm91cHMgU2hhcmVkUHJlZmVyZW5jZXMuCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIE1ERF9GSUxFX0dST1VQUyA9ICJnbXNfaWNpbmdfbWRkX2dyb3VwcyI7CisKKyAgLy8gTmFtZSBvZiBmaWxlIGdyb3VwcyBncm91cCBrZXkgcHJvcGVydGllcyBTaGFyZWRQcmVmZXJlbmNlcy4KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTUREX0ZJTEVfR1JPVVBfS0VZX1BST1BFUlRJRVMgPSAiZ21zX2ljaW5nX21kZF9ncm91cF9rZXlfcHJvcGVydGllcyI7CisKKyAgLy8gVE9ETyhiLzE0NDAzMzE2Myk6IE1pZ3JhdGUgdGhlIEdhcmJhZ2UgQ29sbGVjdG9yIEZpbGUgdG8gUERTLgorICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfR0FSQkFHRV9DT0xMRUNUSU9OX0ZJTEUgPSAiZ21zX2ljaW5nX21kZF9nYXJiYWdlX2ZpbGUiOworCisgIC8qKiBHcm91cCBrZXkgRGVzZXJpYWxpemF0aW9uIGV4Y2VwdGlvbi4gKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBHcm91cEtleURlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbiBleHRlbmRzIEV4Y2VwdGlvbiB7CisgICAgR3JvdXBLZXlEZXNlcmlhbGl6YXRpb25FeGNlcHRpb24oU3RyaW5nIG1zZywgVGhyb3dhYmxlIGNhdXNlKSB7CisgICAgICBzdXBlcihtc2csIGNhdXNlKTsKKyAgICB9CisgIH0KKworICAvLyBUT0RPKGIvMTQ0MDMzMTYzKTogTWlncmF0ZSB0aGUgR2FyYmFnZSBDb2xsZWN0b3IgRmlsZSB0byBQRFMuCisgIHB1YmxpYyBzdGF0aWMgTGlzdDxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGdldEFsbFN0YWxlR3JvdXBzKEZpbGUgZ2FyYmFnZUNvbGxlY3RvckZpbGUpIHsKKyAgICBGaWxlSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW07CisgICAgdHJ5IHsKKyAgICAgIGlucHV0U3RyZWFtID0gbmV3IEZpbGVJbnB1dFN0cmVhbShnYXJiYWdlQ29sbGVjdG9yRmlsZSk7CisgICAgfSBjYXRjaCAoRmlsZU5vdEZvdW5kRXhjZXB0aW9uIGUpIHsKKyAgICAgIExvZ1V0aWwuZCgiRmlsZSAlcyBub3QgZm91bmQgd2hpbGUgcmVhZGluZy4iLCBnYXJiYWdlQ29sbGVjdG9yRmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSk7CisgICAgICByZXR1cm4gSW1tdXRhYmxlTGlzdC5vZigpOworICAgIH0KKworICAgIEJ5dGVCdWZmZXIgYnVmOworICAgIHRyeSB7CisgICAgICBidWYgPSBCeXRlQnVmZmVyLmFsbG9jYXRlKChpbnQpIGdhcmJhZ2VDb2xsZWN0b3JGaWxlLmxlbmd0aCgpKTsKKyAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSkgeworICAgICAgTG9nVXRpbC5lKGUsICIlczogRXhjZXB0aW9uIHdoaWxlIHJlYWRpbmcgZnJvbSBzdGFsZSBncm91cHMgaW50byBidWZmZXIuIiwgVEFHKTsKKyAgICAgIHJldHVybiBJbW11dGFibGVMaXN0Lm9mKCk7CisgICAgfQorCisgICAgTGlzdDxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGZpbGVHcm91cHMgPSBudWxsOworICAgIHRyeSB7CisgICAgICBpbnB1dFN0cmVhbS5nZXRDaGFubmVsKCkucmVhZChidWYpOworICAgICAgLy8gUmV3aW5kIHNvIHRoYXQgd2UgY2FuIHJlYWQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIGJ1ZmZlci4KKyAgICAgIGJ1Zi5yZXdpbmQoKTsKKyAgICAgIC8vIHRhaWxfY3JjID09IGZhbHNlLCBtZWFucyB0aGF0IGVhY2ggbWVzc2FnZSBoYXMgaXRzIG93biBjcmMKKyAgICAgIGZpbGVHcm91cHMgPQorICAgICAgICAgIFByb3RvTGl0ZVV0aWwucmVhZEZyb21CdWZmZXIoCisgICAgICAgICAgICAgIGJ1ZiwgRGF0YUZpbGVHcm91cEludGVybmFsLmNsYXNzLCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwucGFyc2VyKCksIGZhbHNlIC8qdGFpbCBjcmMqLyk7CisgICAgICBpbnB1dFN0cmVhbS5jbG9zZSgpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExvZ1V0aWwuZShlLCAiJXM6IElPRXhjZXB0aW9uIG9jY3VycmVkIHdoaWxlIHJlYWRpbmcgZmlsZSBncm91cHMuIiwgVEFHKTsKKyAgICB9CisgICAgcmV0dXJuIGZpbGVHcm91cHMgPT0gbnVsbCA/IEltbXV0YWJsZUxpc3Qub2YoKSA6IGZpbGVHcm91cHM7CisgIH0KKworICBwdWJsaWMgc3RhdGljIEZpbGUgZ2V0R2FyYmFnZUNvbGxlY3RvckZpbGUoQ29udGV4dCBjb250ZXh0LCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQpIHsKKyAgICBTdHJpbmcgZmlsZU5hbWUgPQorICAgICAgICBpbnN0YW5jZUlkICE9IG51bGwgJiYgaW5zdGFuY2VJZC5pc1ByZXNlbnQoKQorICAgICAgICAgICAgPyBNRERfR0FSQkFHRV9DT0xMRUNUSU9OX0ZJTEUgKyBpbnN0YW5jZUlkLmdldCgpCisgICAgICAgICAgICA6IE1ERF9HQVJCQUdFX0NPTExFQ1RJT05fRklMRTsKKyAgICByZXR1cm4gbmV3IEZpbGUoY29udGV4dC5nZXRGaWxlc0RpcigpLCBmaWxlTmFtZSk7CisgIH0KKworICAvLyBUT0RPKGIvMTI5NzAyMjg3KTogTW92ZSBhd2F5IGZyb20gcHJvdG8gYmFzZWQgc2VyaWFsaXphdGlvbi4KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U2VyaWFsaXplZEdyb3VwS2V5KEdyb3VwS2V5IGdyb3VwS2V5LCBDb250ZXh0IGNvbnRleHQpIHsKKyAgICBieXRlW10gYnl0ZVZhbHVlID0gZ3JvdXBLZXkudG9CeXRlQXJyYXkoKTsKKyAgICByZXR1cm4gQmFzZTY0LmVuY29kZVRvU3RyaW5nKGJ5dGVWYWx1ZSwgQmFzZTY0Lk5PX1BBRERJTkcgfCBCYXNlNjQuTk9fV1JBUCk7CisgIH0KKworICAvKioKKyAgICogQ29udmVydHMgYSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgc2VyaWFsaXplZCBHcm91cEtleSBpbnRvIGEgR3JvdXBLZXkuCisgICAqCisgICAqIEByZXR1cm4gLSBncm91cEtleSBpZiBhYmxlIHRvIHBhcnNlIHN0cmluZ0tleSBwcm9wZXJseS4gbnVsbCBpZiBwYXJzaW5nIGZhaWxzLgorICAgKi8KKyAgLy8gVE9ETyhiLzEyOTcwMjI4Nyk6IE1vdmUgYXdheSBmcm9tIHByb3RvIGJhc2VkIGRlc2VyaWFsaXphdGlvbi4KKyAgcHVibGljIHN0YXRpYyBHcm91cEtleSBkZXNlcmlhbGl6ZUdyb3VwS2V5KFN0cmluZyBzZXJpYWxpemVkR3JvdXBLZXkpCisgICAgICB0aHJvd3MgR3JvdXBLZXlEZXNlcmlhbGl6YXRpb25FeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICByZXR1cm4gU2hhcmVkUHJlZmVyZW5jZXNVdGlsLnBhcnNlTGl0ZUZyb21FbmNvZGVkU3RyaW5nKAorICAgICAgICAgIHNlcmlhbGl6ZWRHcm91cEtleSwgR3JvdXBLZXkucGFyc2VyKCkpOworICAgIH0gY2F0Y2ggKEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CisgICAgICB0aHJvdyBuZXcgR3JvdXBLZXlEZXNlcmlhbGl6YXRpb25FeGNlcHRpb24oCisgICAgICAgICAgIkZhaWxlZCB0byBkZXNlcmlhbGl6ZSBrZXk6IiArIHNlcmlhbGl6ZWRHcm91cEtleSwgZSk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsKCkge30KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9GdXR1cmVzVXRpbC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL0Z1dHVyZXNVdGlsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2RmMWVhMwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9GdXR1cmVzVXRpbC5qYXZhCkBAIC0wLDAgKzEsMTQwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuYW5ub3RhdGlvbnMuU2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLkZ1bmN0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CisKKy8qKiBVdGlsaXRpZXMgZm9yIG1hbmlwdWxhdGluZyBmdXR1cmVzLiAqLworcHVibGljIGZpbmFsIGNsYXNzIEZ1dHVyZXNVdGlsIHsKKworICBwcml2YXRlIGZpbmFsIEV4ZWN1dG9yIHNlcXVlbnRpYWxFeGVjdXRvcjsKKworICBwdWJsaWMgRnV0dXJlc1V0aWwoQFNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IgRXhlY3V0b3Igc2VxdWVudGlhbEV4ZWN1dG9yKSB7CisgICAgdGhpcy5zZXF1ZW50aWFsRXhlY3V0b3IgPSBzZXF1ZW50aWFsRXhlY3V0b3I7CisgIH0KKworICAvKioKKyAgICogUmV0dXJucyBhIFNlcXVlbnRpYWxGdXR1cmVDaGFpbiB3aGljaCBjYW4gdGFrZXMgYSBudW1iZXIgb2YgYXN5bmNocm9ub3VzIG9wZXJhdGlvbiBhbmQgdHVybnMKKyAgICogdGhlbSBpbnRvIGEgc2luZ2xlIGFzeW5jaHJvbm91cyBvcGVyYXRpb24uCisgICAqCisgICAqIDxwPlNlcXVlbnRpYWxGdXR1cmVDaGFpbiBwcm92aWRlcyBhIGNsZWFyZXIgd2F5IG9mIHdyaXRpbmcgYSBjb21tb24gaWRpb20gdXNlZCB0byBzZXF1ZW5jZSBhCisgICAqIG51bWJlciBvZiBhc3luY2hyb3Vub3VzIG9wZXJhdGlvbnMuIFRoZSBmcmFnbWVudAorICAgKgorICAgKiA8cHJlPntAY29kZQorICAgKiBMaXN0ZW5hYmxlRnV0dXJlPFQ+IGZ1dHVyZSA9IGltbWVkaWF0ZUZ1dHVyZShpbml0KTsKKyAgICogZnV0dXJlID0gdHJhbnNmb3JtQXN5bmMoZnV0dXJlLCBhcmcgLT4gYXN5bmNPcDEsIHNlcXVlbnRpYWxFeGVjdXRvcik7CisgICAqIGZ1dHVyZSA9IHRyYW5zZm9ybShmdXR1cmUsIGFyZyAtPiBvcDIsIHNlcXVlbnRpYWxFeGVjdXRvcik7CisgICAqIGZ1dHVyZSA9IHRyYW5zZm9ybUFzeW5jKGZ1dHVyZSwgYXJnIC0+IGFzeW5jT3AzLCBzZXF1ZW50aWFsRXhlY3V0b3IpOworICAgKiByZXR1cm4gZnV0dXJlOworICAgKiB9PC9wcmU+CisgICAqCisgICAqIDxwPmNhbiBiZSByZXdyaXR0ZW4gYXMKKyAgICoKKyAgICogPHByZT57QGNvZGUKKyAgICogcmV0dXJuIG5ldyBGdXR1cmVzVXRpbChzZXF1ZW50aWFsRXhlY3V0b3IpCisgICAqICAgICAubmV3U2VxdWVudGlhbENoYWluKGluaXQpCisgICAqICAgICAuY2hhaW5Bc3luYyhhcmcgLT4gYXN5bmNPcDEpCisgICAqICAgICAuY2hhaW4oYXJnIC0+IG9wMikKKyAgICogICAgIC5jaGFpbkFzeW5jKGFyZyAtPiBhc3luY09wMykKKyAgICogICAgIC5zdGFydCgpOworICAgKiB9PC9wcmU+CisgICAqCisgICAqIDxwPklmIGFueSBpbnRlcm1lZGlhdGUgb3BlcmF0aW9uIHJhaXNlcyBhbiBleGNlcHRpb24sIHRoZSB3aG9sZSBjaGFpbiByYWlzZXMgYW4gZXhjZXB0aW9uLgorICAgKgorICAgKiA8cD5Ob3RlIHRoYXQgc2VxdWVudGlhbEV4ZWN1dG9yIG11c3QgYmUgYSBzZXF1ZW50aWFsIGV4ZWN1dG9yLCBpLmUuIHByb3ZpZGUgdGhlIHNlcXVlbnRpYWxpdHkKKyAgICogZ3VhcmFudGVlcyBwcm92aWRlZCBieSB7QGxpbmsgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LlNlcXVlbnRpYWxFeGVjdXRvcn0uCisgICAqLworICBwdWJsaWMgPFQ+IFNlcXVlbnRpYWxGdXR1cmVDaGFpbjxUPiBuZXdTZXF1ZW50aWFsQ2hhaW4oVCBpbml0KSB7CisgICAgcmV0dXJuIG5ldyBTZXF1ZW50aWFsRnV0dXJlQ2hhaW48Pihpbml0KTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGUgYSBTZXF1ZW50aWFsRnV0dXJlQ2hhaW4gdGhhdCBkb2Vzbid0IGNvbXB1dGUgYSByZXN1bHQuCisgICAqCisgICAqIDxwPklmIGFueSBpbnRlcm1lZGlhdGUgb3BlcmF0aW9uIHJhaXNlcyBhbiBleGNlcHRpb24sIHRoZSB3aG9sZSBjaGFpbiByYWlzZXMgYW4gZXhjZXB0aW9uLgorICAgKgorICAgKiA8cD5Ob3RlIHRoYXQgc2VxdWVudGlhbEV4ZWN1dG9yIG11c3QgYmUgYSBzZXF1ZW50aWFsIGV4ZWN1dG9yLCBpLmUuIHByb3ZpZGUgdGhlIHNlcXVlbnRpYWxpdHkKKyAgICogZ3VhcmFudGVlcyBwcm92aWRlZCBieSB7QGxpbmsgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LlNlcXVlbnRpYWxFeGVjdXRvcn0uCisgICAqLworICBwdWJsaWMgU2VxdWVudGlhbEZ1dHVyZUNoYWluPFZvaWQ+IG5ld1NlcXVlbnRpYWxDaGFpbigpIHsKKyAgICByZXR1cm4gbmV3IFNlcXVlbnRpYWxGdXR1cmVDaGFpbjw+KG51bGwpOworICB9CisKKyAgLyoqIEJ1aWxkcyBhIGxpc3Qgb2YgRnV0dXJzZSB0byBiZSBleGVjdXRlZCBzZXF1ZW50aWFsbHkuICovCisgIHB1YmxpYyBmaW5hbCBjbGFzcyBTZXF1ZW50aWFsRnV0dXJlQ2hhaW48VD4geworICAgIHByaXZhdGUgZmluYWwgTGlzdDxGdXR1cmVDaGFpbkVsZW1lbnQ8VD4+IG9wZXJhdGlvbnM7CisgICAgcHJpdmF0ZSBmaW5hbCBUIGluaXQ7CisKKyAgICBwcml2YXRlIFNlcXVlbnRpYWxGdXR1cmVDaGFpbihUIGluaXQpIHsKKyAgICAgIHRoaXMub3BlcmF0aW9ucyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgdGhpcy5pbml0ID0gaW5pdDsKKyAgICB9CisKKyAgICBwdWJsaWMgU2VxdWVudGlhbEZ1dHVyZUNoYWluPFQ+IGNoYWluKEZ1bmN0aW9uPFQsIFQ+IG9wZXJhdGlvbikgeworICAgICAgb3BlcmF0aW9ucy5hZGQobmV3IERpcmVjdEZ1dHVyZUNoYWluRWxlbWVudDw+KG9wZXJhdGlvbikpOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIFNlcXVlbnRpYWxGdXR1cmVDaGFpbjxUPiBjaGFpbkFzeW5jKEZ1bmN0aW9uPFQsIExpc3RlbmFibGVGdXR1cmU8VD4+IG9wZXJhdGlvbikgeworICAgICAgb3BlcmF0aW9ucy5hZGQobmV3IEFzeW5jRnV0dXJlQ2hhaW5FbGVtZW50PD4ob3BlcmF0aW9uKSk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxUPiBzdGFydCgpIHsKKyAgICAgIExpc3RlbmFibGVGdXR1cmU8VD4gcmVzdWx0ID0gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoaW5pdCk7CisgICAgICBmb3IgKEZ1dHVyZUNoYWluRWxlbWVudDxUPiBvcGVyYXRpb24gOiBvcGVyYXRpb25zKSB7CisgICAgICAgIHJlc3VsdCA9IG9wZXJhdGlvbi5hcHBseShyZXN1bHQpOworICAgICAgfQorICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgIH0KKworICBwcml2YXRlIGludGVyZmFjZSBGdXR1cmVDaGFpbkVsZW1lbnQ8VD4geworICAgIGFic3RyYWN0IExpc3RlbmFibGVGdXR1cmU8VD4gYXBwbHkoTGlzdGVuYWJsZUZ1dHVyZTxUPiBpbnB1dCk7CisgIH0KKworICBwcml2YXRlIGZpbmFsIGNsYXNzIERpcmVjdEZ1dHVyZUNoYWluRWxlbWVudDxUPiBpbXBsZW1lbnRzIEZ1dHVyZUNoYWluRWxlbWVudDxUPiB7CisgICAgcHJpdmF0ZSBmaW5hbCBGdW5jdGlvbjxULCBUPiBvcGVyYXRpb247CisKKyAgICBwcml2YXRlIERpcmVjdEZ1dHVyZUNoYWluRWxlbWVudChGdW5jdGlvbjxULCBUPiBvcGVyYXRpb24pIHsKKyAgICAgIHRoaXMub3BlcmF0aW9uID0gb3BlcmF0aW9uOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFQ+IGFwcGx5KExpc3RlbmFibGVGdXR1cmU8VD4gaW5wdXQpIHsKKyAgICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybShpbnB1dCwgb3BlcmF0aW9uOjphcHBseSwgc2VxdWVudGlhbEV4ZWN1dG9yKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIGZpbmFsIGNsYXNzIEFzeW5jRnV0dXJlQ2hhaW5FbGVtZW50PFQ+IGltcGxlbWVudHMgRnV0dXJlQ2hhaW5FbGVtZW50PFQ+IHsKKyAgICBwcml2YXRlIGZpbmFsIEZ1bmN0aW9uPFQsIExpc3RlbmFibGVGdXR1cmU8VD4+IG9wZXJhdGlvbjsKKworICAgIHByaXZhdGUgQXN5bmNGdXR1cmVDaGFpbkVsZW1lbnQoRnVuY3Rpb248VCwgTGlzdGVuYWJsZUZ1dHVyZTxUPj4gb3BlcmF0aW9uKSB7CisgICAgICB0aGlzLm9wZXJhdGlvbiA9IG9wZXJhdGlvbjsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxUPiBhcHBseShMaXN0ZW5hYmxlRnV0dXJlPFQ+IGlucHV0KSB7CisgICAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYyhpbnB1dCwgb3BlcmF0aW9uOjphcHBseSwgc2VxdWVudGlhbEV4ZWN1dG9yKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9NZGRMaXRlQ29udmVyc2lvblV0aWwuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9NZGRMaXRlQ29udmVyc2lvblV0aWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMWE3Mzc1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL01kZExpdGVDb252ZXJzaW9uVXRpbC5qYXZhCkBAIC0wLDAgKzEsMTAwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuU2luZ2xlRmlsZURvd25sb2FkTGlzdGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuU2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlLkRvd25sb2FkTGlzdGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubGl0ZS5Eb3dubG9hZFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKKworLyoqCisgKiBVdGlsaXR5IENsYXNzIHRvIGhlbHAgY29udmVydGluZyBNREQgTGliJ3MgU2luZ2xlRmlsZSBjbGFzc2VzL2ludGVyZmFjZXMgdG8gdGhlIE1ERCBMaXRlCisgKiBlcXVpdmFsZW50LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgTWRkTGl0ZUNvbnZlcnNpb25VdGlsIHsKKworICBwcml2YXRlIE1kZExpdGVDb252ZXJzaW9uVXRpbCgpIHt9CisKKyAgLyoqIENvbnZlcnQge0BsaW5rIFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3R9IHRvIE1ERCBMaXRlJ3Mge0BsaW5rIERvd25sb2FkUmVxdWVzdH0uICovCisgIC8vIFRPRE8oYi8xNzYxMDM2MzkpOiBVc2UgQXV0b0NvbnZlcnRlciBpZiBAQXV0b1ZhbHVlIHRvIEBBdXRvVmFsdWUgaXMgc3VwcG9ydGVkCisgIHB1YmxpYyBzdGF0aWMgRG93bmxvYWRSZXF1ZXN0IGNvbnZlcnRUb0Rvd25sb2FkUmVxdWVzdCgKKyAgICAgIFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3Qgc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCkgeworICAgIHJldHVybiBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXREZXN0aW5hdGlvbkZpbGVVcmkoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKSkKKyAgICAgICAgLnNldFVybFRvRG93bmxvYWQoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdC51cmxUb0Rvd25sb2FkKCkpCisgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QuZG93bmxvYWRDb25zdHJhaW50cygpKQorICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbCgKKyAgICAgICAgICAgIGNvbnZlcnRUb0Rvd25sb2FkTGlzdGVuZXJPcHRpb25hbChzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKSkpCisgICAgICAgIC5zZXRUcmFmZmljVGFnKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QudHJhZmZpY1RhZygpKQorICAgICAgICAuc2V0RXh0cmFIdHRwSGVhZGVycyhzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0LmV4dHJhSHR0cEhlYWRlcnMoKSkKKyAgICAgICAgLnNldEZpbGVTaXplQnl0ZXMoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdC5maWxlU2l6ZUJ5dGVzKCkpCisgICAgICAgIC5zZXROb3RpZmljYXRpb25Db250ZW50VGl0bGUoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdC5ub3RpZmljYXRpb25Db250ZW50VGl0bGUoKSkKKyAgICAgICAgLnNldE5vdGlmaWNhdGlvbkNvbnRlbnRUZXh0T3B0aW9uYWwoCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0Lm5vdGlmaWNhdGlvbkNvbnRlbnRUZXh0T3B0aW9uYWwoKSkKKyAgICAgICAgLnNldFNob3dEb3dubG9hZGVkTm90aWZpY2F0aW9uKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3Quc2hvd0Rvd25sb2FkZWROb3RpZmljYXRpb24oKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgIH0KKworICAvKiogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBoYW5kbGluZyBvcHRpb25hbHMuICovCisgIHB1YmxpYyBzdGF0aWMgT3B0aW9uYWw8RG93bmxvYWRMaXN0ZW5lcj4gY29udmVydFRvRG93bmxvYWRMaXN0ZW5lck9wdGlvbmFsKAorICAgICAgT3B0aW9uYWw8U2luZ2xlRmlsZURvd25sb2FkTGlzdGVuZXI+IHNpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyT3B0aW9uYWwpIHsKKyAgICBpZiAoIXNpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyT3B0aW9uYWwuaXNQcmVzZW50KCkpIHsKKyAgICAgIHJldHVybiBPcHRpb25hbC5hYnNlbnQoKTsKKyAgICB9CisKKyAgICByZXR1cm4gT3B0aW9uYWwub2YoY29udmVydFRvRG93bmxvYWRMaXN0ZW5lcihzaW5nbGVGaWxlRG93bmxvYWRMaXN0ZW5lck9wdGlvbmFsLmdldCgpKSk7CisgIH0KKworICAvKiogQ29udmVydCB7QGxpbmsgU2luZ2xlRmlsZURvd25sb2FkTGlzdGVuZXJ9IHRvIE1ERCBMaXRlJ3Mge0BsaW5rIERvd25sb2FkTGlzdGVuZXJ9LiAqLworICBwdWJsaWMgc3RhdGljIERvd25sb2FkTGlzdGVuZXIgY29udmVydFRvRG93bmxvYWRMaXN0ZW5lcigKKyAgICAgIFNpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyIHNpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyKSB7CisgICAgcmV0dXJuIG5ldyBDb252ZXJ0ZWRTaW5nbGVGaWxlRG93bmxvYWRMaXN0ZW5lcihzaW5nbGVGaWxlRG93bmxvYWRMaXN0ZW5lcik7CisgIH0KKworICAvKioKKyAgICogV3JhcHBlciBhcm91bmQgZ2l2ZW4ge0BsaW5rIFNpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyfSB0aGF0IGltcGxlbWVudHMgTUREIExpdGUncyB7QGxpbmsKKyAgICogRG93bmxvYWRMaXN0ZW5lcn0gaW50ZXJmYWNlLgorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQ29udmVydGVkU2luZ2xlRmlsZURvd25sb2FkTGlzdGVuZXIgaW1wbGVtZW50cyBEb3dubG9hZExpc3RlbmVyIHsKKyAgICBwcml2YXRlIGZpbmFsIFNpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyIHNvdXJjZUxpc3RlbmVyOworCisgICAgcHJpdmF0ZSBDb252ZXJ0ZWRTaW5nbGVGaWxlRG93bmxvYWRMaXN0ZW5lcihTaW5nbGVGaWxlRG93bmxvYWRMaXN0ZW5lciBzb3VyY2VMaXN0ZW5lcikgeworICAgICAgdGhpcy5zb3VyY2VMaXN0ZW5lciA9IHNvdXJjZUxpc3RlbmVyOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIG9uUHJvZ3Jlc3MobG9uZyBjdXJyZW50U2l6ZSkgeworICAgICAgc291cmNlTGlzdGVuZXIub25Qcm9ncmVzcyhjdXJyZW50U2l6ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gb25Db21wbGV0ZSgpIHsKKyAgICAgIHJldHVybiBzb3VyY2VMaXN0ZW5lci5vbkNvbXBsZXRlKCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KSB7CisgICAgICBzb3VyY2VMaXN0ZW5lci5vbkZhaWx1cmUodCk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgb25QYXVzZWRGb3JDb25uZWN0aXZpdHkoKSB7CisgICAgICBzb3VyY2VMaXN0ZW5lci5vblBhdXNlZEZvckNvbm5lY3Rpdml0eSgpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL1Byb3RvQ29udmVyc2lvblV0aWwuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9Qcm90b0NvbnZlcnNpb25VdGlsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDRlMzQ0NgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9Qcm90b0NvbnZlcnNpb25VdGlsLmphdmEKQEAgLTAsMCArMSwxMzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWw7CisKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRlbHRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRvd25sb2FkQ29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworCisvKiogVGhlIHV0aWwgY2xhc3MgdGhhdCBkb2VzIGNvbnZlcnNpb24gYmV0d2VlbiBwcm90b3MuICovCitwdWJsaWMgZmluYWwgY2xhc3MgUHJvdG9Db252ZXJzaW9uVXRpbCB7CisgIHByaXZhdGUgUHJvdG9Db252ZXJzaW9uVXRpbCgpIHt9CisKKyAgLyoqCisgICAqIENvbnZlcnRzIGV4dGVybmFsIGNvbmZpZ3VyYXRpb24gcHJvdG8ge0BsaW5rIERhdGFGaWxlR3JvdXB9IGludG8gaW50ZXJuYWwgc3RvcmFnZSBwcm90byB7QGxpbmsKKyAgICogRGF0YUZpbGVHcm91cEludGVybmFsfS4KKyAgICovCisgIC8vIFRPRE8oYi8xNzYxMDM2MzkpOiBVc2UgYXV0b21hdGVkIHByb3RvIGNvbnZlcnRlciBpbnN0ZWFkCisgIHB1YmxpYyBzdGF0aWMgRGF0YUZpbGVHcm91cEludGVybmFsIGNvbnZlcnQoRGF0YUZpbGVHcm91cCBncm91cCkKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIC8vIENhbm5vdCB1c2UgZ2VuZXJhdGVkIHJlZ2lzdHJ5IGhlcmUsIGJlY2F1c2UgaXQgbWF5IGNhdXNlIE5QRSB0byBjbGllbnRzLgorICAgIC8vIEZvciBtb3JlIGRldGFpbCwgc2VlIGIvMTQwMTM1MDU5LgorICAgIHJldHVybiBEYXRhRmlsZUdyb3VwSW50ZXJuYWwucGFyc2VGcm9tKAorICAgICAgICBncm91cC50b0J5dGVBcnJheSgpLCBFeHRlbnNpb25SZWdpc3RyeUxpdGUuZ2V0RW1wdHlSZWdpc3RyeSgpKTsKKyAgfQorCisgIC8qKgorICAgKiBDb252ZXJ0cyBleHRlcm5hbCBwcm90byB7QGxpbmsgRG93bmxvYWRDb25kaXRpb25zfSBpbnRvIGludGVybmFsIHByb3RvIHtAbGluaworICAgKiBNZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9uc30uCisgICAqLworICAvLyBUT0RPKGIvMTc2MTAzNjM5KTogVXNlIGF1dG9tYXRlZCBwcm90byBjb252ZXJ0ZXIgaW5zdGVhZAorICBwdWJsaWMgc3RhdGljIE1ldGFkYXRhUHJvdG8uRG93bmxvYWRDb25kaXRpb25zIGNvbnZlcnQoRG93bmxvYWRDb25kaXRpb25zIGRvd25sb2FkQ29uZGl0aW9ucykKKyAgICAgIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIC8vIENhbm5vdCB1c2UgZ2VuZXJhdGVkIHJlZ2lzdHJ5IGhlcmUsIGJlY2F1c2UgaXQgbWF5IGNhdXNlIE5QRSB0byBjbGllbnRzLgorICAgIC8vIEZvciBtb3JlIGRldGFpbCwgc2VlIGIvMTQwMTM1MDU5LgorICAgIHJldHVybiBNZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5wYXJzZUZyb20oCisgICAgICAgIGRvd25sb2FkQ29uZGl0aW9ucy50b0J5dGVBcnJheSgpLCBFeHRlbnNpb25SZWdpc3RyeUxpdGUuZ2V0RW1wdHlSZWdpc3RyeSgpKTsKKyAgfQorCisgIC8qKgorICAgKiBDb252ZXJ0cyBleHRlcm5hbCBjb25maWd1cmF0aW9uIHByb3RvIHtAbGluayBEYXRhRmlsZX0gdG8gaW50ZXJuYWwgc3RvcmFnZSBwcm90byB7QGxpbmsKKyAgICogTWV0YWRhdGFQcm90by5EYXRhRmlsZX0uCisgICAqLworICAvLyBUT0RPKGIvMTc2MTAzNjM5KTogVXNlIGF1dG9tYXRlZCBwcm90byBjb252ZXJ0ZXIgaW5zdGVhZAorICAvLyBMSU5ULklmQ2hhbmdlKGRhdGFfZmlsZV9jb252ZXJ0KQorICBwdWJsaWMgc3RhdGljIE1ldGFkYXRhUHJvdG8uRGF0YUZpbGUgY29udmVydERhdGFGaWxlKERhdGFGaWxlIGRhdGFGaWxlKSB7CisgICAgTWV0YWRhdGFQcm90by5EYXRhRmlsZS5CdWlsZGVyIGRhdGFGaWxlQnVpbGRlciA9CisgICAgICAgIE1ldGFkYXRhUHJvdG8uRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZUlkKGRhdGFGaWxlLmdldEZpbGVJZCgpKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoZGF0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpKQorICAgICAgICAgICAgLnNldEJ5dGVTaXplKGRhdGFGaWxlLmdldEJ5dGVTaXplKCkpCisgICAgICAgICAgICAuc2V0Q2hlY2tzdW1UeXBlKAorICAgICAgICAgICAgICAgIE1ldGFkYXRhUHJvdG8uRGF0YUZpbGUuQ2hlY2tzdW1UeXBlLmZvck51bWJlcigKKyAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0Q2hlY2tzdW1UeXBlKCkuZ2V0TnVtYmVyKCkpKQorICAgICAgICAgICAgLnNldENoZWNrc3VtKGRhdGFGaWxlLmdldENoZWNrc3VtKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bShkYXRhRmlsZS5nZXREb3dubG9hZGVkRmlsZUNoZWNrc3VtKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRlZEZpbGVCeXRlU2l6ZShkYXRhRmlsZS5nZXREb3dubG9hZGVkRmlsZUJ5dGVTaXplKCkpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJpbmdUeXBlKAorICAgICAgICAgICAgICAgIE1ldGFkYXRhUHJvdG8uRGF0YUZpbGUuQW5kcm9pZFNoYXJpbmdUeXBlLmZvck51bWJlcigKKyAgICAgICAgICAgICAgICAgICAgZGF0YUZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdUeXBlKCkuZ2V0TnVtYmVyKCkpKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW1UeXBlKAorICAgICAgICAgICAgICAgIE1ldGFkYXRhUHJvdG8uRGF0YUZpbGUuQW5kcm9pZFNoYXJpbmdDaGVja3N1bVR5cGUuZm9yTnVtYmVyKAorICAgICAgICAgICAgICAgICAgICBkYXRhRmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtVHlwZSgpLmdldE51bWJlcigpKSkKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKGRhdGFGaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSkKKyAgICAgICAgICAgIC5zZXRSZWxhdGl2ZUZpbGVQYXRoKGRhdGFGaWxlLmdldFJlbGF0aXZlRmlsZVBhdGgoKSk7CisKKyAgICBpZiAoZGF0YUZpbGUuaGFzQ3VzdG9tTWV0YWRhdGEoKSkgeworICAgICAgZGF0YUZpbGVCdWlsZGVyLnNldEN1c3RvbU1ldGFkYXRhKGRhdGFGaWxlLmdldEN1c3RvbU1ldGFkYXRhKCkpOworICAgIH0KKyAgICBpZiAoZGF0YUZpbGUuaGFzRG93bmxvYWRUcmFuc2Zvcm1zKCkpIHsKKyAgICAgIGRhdGFGaWxlQnVpbGRlci5zZXREb3dubG9hZFRyYW5zZm9ybXMoZGF0YUZpbGUuZ2V0RG93bmxvYWRUcmFuc2Zvcm1zKCkpOworICAgIH0KKworICAgIGlmIChkYXRhRmlsZS5oYXNSZWFkVHJhbnNmb3JtcygpKSB7CisgICAgICBkYXRhRmlsZUJ1aWxkZXIuc2V0UmVhZFRyYW5zZm9ybXMoZGF0YUZpbGUuZ2V0UmVhZFRyYW5zZm9ybXMoKSk7CisgICAgfQorCisgICAgZm9yIChEZWx0YUZpbGUgZGVsdGFGaWxlIDogZGF0YUZpbGUuZ2V0RGVsdGFGaWxlTGlzdCgpKSB7CisgICAgICBkYXRhRmlsZUJ1aWxkZXIuYWRkRGVsdGFGaWxlKGNvbnZlcnREZWx0YUZpbGUoZGVsdGFGaWxlKSk7CisgICAgfQorCisgICAgcmV0dXJuIGRhdGFGaWxlQnVpbGRlci5idWlsZCgpOworICB9CisgIC8vIExJTlQuVGhlbkNoYW5nZSgKKyAgLy8KKyAgLy8gPGludGVybmFsPiwKKyAgLy8KKyAgLy8gPGludGVybmFsPikKKworICAvKioKKyAgICogQ29udmVydHMgZXh0ZXJuYWwgY29uZmlndXJhdGlvbiBwcm90byB7QGxpbmsgRGVsdGFGaWxlfSB0byBpbnRlcm5hbCBzdG9yYWdlIHByb3RvIHtAbGluaworICAgKiBEZWx0YUZpbGV9LgorICAgKi8KKyAgLy8gVE9ETyhiLzE3NjEwMzYzOSk6IFVzZSBhdXRvbWF0ZWQgcHJvdG8gY29udmVydGVyIGluc3RlYWQKKyAgLy8gTElOVC5JZkNoYW5nZShkZWx0YV9maWxlX2NvbnZlcnQpCisgIHB1YmxpYyBzdGF0aWMgTWV0YWRhdGFQcm90by5EZWx0YUZpbGUgY29udmVydERlbHRhRmlsZShEZWx0YUZpbGUgZGVsdGFGaWxlKSB7CisgICAgcmV0dXJuIE1ldGFkYXRhUHJvdG8uRGVsdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChkZWx0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpKQorICAgICAgICAuc2V0Qnl0ZVNpemUoZGVsdGFGaWxlLmdldEJ5dGVTaXplKCkpCisgICAgICAgIC5zZXRDaGVja3N1bShkZWx0YUZpbGUuZ2V0Q2hlY2tzdW0oKSkKKyAgICAgICAgLnNldERpZmZEZWNvZGVyKAorICAgICAgICAgICAgTWV0YWRhdGFQcm90by5EZWx0YUZpbGUuRGlmZkRlY29kZXIuZm9yTnVtYmVyKGRlbHRhRmlsZS5nZXREaWZmRGVjb2RlcigpLmdldE51bWJlcigpKSkKKyAgICAgICAgLnNldEJhc2VGaWxlKAorICAgICAgICAgICAgTWV0YWRhdGFQcm90by5CYXNlRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oZGVsdGFGaWxlLmdldEJhc2VGaWxlKCkuZ2V0Q2hlY2tzdW0oKSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgIH0KKyAgLy8gTElOVC5UaGVuQ2hhbmdlKAorICAvLworICAvLyA8aW50ZXJuYWw+LAorICAvLworICAvLyA8aW50ZXJuYWw+KQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL1Byb3RvTGl0ZVV0aWwuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9Qcm90b0xpdGVVdGlsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWYwMmNhZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9Qcm90b0xpdGVVdGlsLmphdmEKQEAgLTAsMCArMSwzNDYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWw7CisKK2ltcG9ydCBhbmRyb2lkLnRleHQuVGV4dFV0aWxzOworaW1wb3J0IGFuZHJvaWQudXRpbC5Mb2c7CitpbXBvcnQgYW5kcm9pZHguYW5ub3RhdGlvbi5OdWxsYWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGU7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CdWZmZXJPdmVyZmxvd0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CdWZmZXJVbmRlcmZsb3dFeGNlcHRpb247CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFyc2V0LkNoYXJzZXQ7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC56aXAuQ1JDMzI7CisKKy8qKiBVdGlscyBmb3IgbW92aW5nIFByb3RvYnVmIG1lc3NhZ2VzIGluIGFuZCBvdXQgb2YgQnl0ZUJ1ZmZlcnMuICovCisvLyBMSU5ULklmQ2hhbmdlCitwdWJsaWMgY2xhc3MgUHJvdG9MaXRlVXRpbCB7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJQcm90b0xpdGVVdGlsIjsKKworICAvKgorICAgKiBGaWxlIGZvcm1hdCAod2l0aCB0YWlsIGNyYyk6CisgICAqICgKKyAgICogICAgaW50OiBudW1iZXIgb2YgYnl0ZXMgaW4gbWVzc2FnZTsKKyAgICogICAgYnl0ZVtudW1iZXIgb2YgYnl0ZXMgaW4gbWVzc2FnZV06IGJ5dGVzIG9mIG1lc3NhZ2U7CisgICAqICkuLi46IG1lc3NhZ2UgYmxvY2tzOworICAgKiBsb25nOiBDUkMgb2YgdGhlIGFib3ZlIGRhdGEKKyAgICoKKyAgICogRmlsZSBmb3JtYXQgKHdpdGhvdXQgdGFpbCBjcmMpOgorICAgKiAoCisgICAqICAgIGludDogbnVtYmVyIG9mIGJ5dGVzIGluIG1lc3NhZ2U7CisgICAqICAgIGJ5dGVbbnVtYmVyIG9mIGJ5dGVzIGluIG1lc3NhZ2VdOiBieXRlcyBvZiBtZXNzYWdlOworICAgKiAgICBsb25nOiB0aGUgQ1JDIG9mIHRoZSBieXRlcyBvZiB0aGUgbWVzc2FnZSBhYm92ZQorICAgKiApLi4uOiBtZXNzYWdlIGJsb2NrczsKKyAgICovCisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZSBJTlRfQllURV9TSVpFID0gSW50ZWdlci5TSVpFIC8gQnl0ZS5TSVpFOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIExPTkdfQllURV9TSVpFID0gTG9uZy5TSVpFIC8gQnl0ZS5TSVpFOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlIENSQ19MRU4gPSBMT05HX0JZVEVfU0laRTsKKworICAvLyBVc2VkIHRvIGhlbHAgZ3Vlc3MgYSBnb29kIGluaXRpYWwgY2FwYWNpdHkgZm9yIHRoZSBBcnJheUxpc3QKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEVYUEVDVEVEX01FU1NfU0laRSA9IDEwMDA7CisKKyAgLyoqCisgICAqIEBwYXJhbSBidWYgTVVTVCBiZSBhIDAgYmFzZWQgYXJyYXkgYnVmZmVyIChha2EsIGJ1Zi5hcnJheU9mZnNldCgpIG11c3QgcmV0dXJuIDApIGFuZCBiZSBtdXRhYmxlCisgICAqICAgICAoYWthLCBidWYuaXNSZWFkT25seSgpIG11c3QgcmV0dXJuIGZhbHNlKQorICAgKiBAcGFyYW0gbWVzc2FnZVR5cGUgVGhlIHR5cGUgb2YgdGhlIHByb3RvCisgICAqIEBwYXJhbSB0YWlsQ3JjIFRydWUgaWYgdGhlcmUgaXMgYSBzaW5nbGUgQ1JDIGF0IHRoZSBlbmQgb2YgdGhlIGZpbGUgZm9yIHRoZSB3aG9sZSBjb250ZW50LAorICAgKiAgICAgZmFsc2UgaWYgdGhlcmUgaXMgYSBDUkMgYWZ0ZXIgZXZlcnkgcmVjb3JkLgorICAgKiBAcmV0dXJuIEEgbGlzdCBvZiBwcm90byBtZXNzYWdlcyByZWFkIGZyb20gdGhlIGJ1ZmZlciwgb3IgbnVsbCBvbiBmYWlsdXJlLgorICAgKi8KKyAgQE51bGxhYmxlCisgIHB1YmxpYyBzdGF0aWMgPFQgZXh0ZW5kcyBNZXNzYWdlTGl0ZT4gTGlzdDxUPiByZWFkRnJvbUJ1ZmZlcigKKyAgICAgIEJ5dGVCdWZmZXIgYnVmLCBDbGFzczxUPiBtZXNzYWdlVHlwZSwgUGFyc2VyPFQ+IG1lc3NhZ2VQYXJzZXIsIGJvb2xlYW4gdGFpbENyYykgeworICAgIC8vIGFzc2VydCBidWYuYXJyYXlPZmZzZXQoKSA9PSAwOworICAgIC8vIGFubm95aW5nbHksIEJ5dGVCdWZmZXIjYXJyYXkoKSB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZSBCeXRlQnVmZmVyIHdhcyByZWFkb25seQorICAgIC8vIGFzc2VydCAhYnVmLmlzUmVhZE9ubHkoKTsKKyAgICBTdHJpbmcgdHlwZW5hbWUgPSBtZXNzYWdlVHlwZS50b1N0cmluZygpOworCisgICAgaWYgKHRhaWxDcmMpIHsKKyAgICAgIC8vIFZhbGlkYXRlIHRoZSB0YWlsIENSQyBiZWZvcmUgcmVhZGluZyBhbnkgbWVzc2FnZXMuCisgICAgICBpbnQgY3JjUG9zID0gYnVmLmxpbWl0KCkgLSBDUkNfTEVOOworICAgICAgaWYgKGNyY1BvcyA8IDApIHsgLy8gRXF1aXZhbGVudGx5LCBidWYubGltaXQoKSA8IENSQ19MRU4KKyAgICAgICAgTG9nLmUoVEFHLCAiUHJvdG9idWYgZGF0YSB0b28gc2hvcnQgdG8gYmUgdmFsaWQiKTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgICAvLyBGaXJzdCBvZmYsIGNoZWNrIHRoZSBjcmMKKyAgICAgIGxvbmcgY3JjID0gYnVmLmdldExvbmcoY3JjUG9zKTsKKyAgICAgIC8vIFBvc2l0aW9uIHNob3VsZCBzdGlsbCBiZSBhdCB0aGUgYmVnaW5uaW5nOworICAgICAgLy8gdGhlIHJlYWQgYW5kIHdyaXRlIG9wZXJhdGlvbnMgdGhhdCB0YWtlIGFuIGluZGV4IGV4cGxpY2l0bHkgZG8gbm90IHRvdWNoIHRoZQorICAgICAgLy8gcG9zaXRpb24KKyAgICAgIGlmICghdmFsaWRhdGVDUkMoYnVmLmFycmF5KCksIGJ1Zi5hcnJheU9mZnNldCgpLCBjcmNQb3MsIGNyYykpIHsKKyAgICAgICAgTG9nLmUoVEFHLCAiSWdub3JpbmcgY29ycnVwdCBwcm90b2J1ZiBkYXRhIik7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgaWYgKGNyY1BvcyA9PSAwKSB7IC8vIElmIHRoZSBvbmx5IHRoaW5nIGluIHRoZXJlIHdhcyB0aGUgQ1JDLCB0aGVuIHRoZXJlIGFyZSBubyBtZXNzYWdlcworICAgICAgICByZXR1cm4gbmV3IEFycmF5TGlzdDxUPigwKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpbnQgZW5kID0gdGFpbENyYyA/IGJ1Zi5saW1pdCgpIC0gQ1JDX0xFTiA6IGJ1Zi5saW1pdCgpOworCisgICAgTGlzdDxUPiB0b1JldHVybiA9IG5ldyBBcnJheUxpc3Q8VD4oKGJ1Zi5saW1pdCgpIC8gRVhQRUNURURfTUVTU19TSVpFKSArIDEpOworICAgIHdoaWxlIChidWYucG9zaXRpb24oKSA8IGVuZCkgeworICAgICAgVCBkZXN0OworICAgICAgaW50IGJ5dGVzSW5NZXNzYWdlOworICAgICAgdHJ5IHsKKyAgICAgICAgYnl0ZXNJbk1lc3NhZ2UgPSBidWYuZ2V0SW50KCk7CisgICAgICB9IGNhdGNoIChCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgaGFuZGxlQnVmZmVyVW5kZXJmbG93KGV4LCB0eXBlbmFtZSk7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgaWYgKGJ5dGVzSW5NZXNzYWdlIDwgMCkgeworICAgICAgICAvLyBUaGlzIGFjdHVhbGx5IGNhbiBoYXBwZW4gZXZlbiBpZiB0aGUgQ1JDIGNoZWNrIHBhc3NlZCwKKyAgICAgICAgLy8gaWYgdGhlIHVzZXIgZ2F2ZSB0aGUgd3JvbmcgTWVzc2FnZUxpdGUgdHlwZS4KKyAgICAgICAgLy8gU2FtZSBnb2VzIGZvciBhbGwgb2YgdGhlIG90aGVyIGV4Y2VwdGlvbnMgdGhhdCBjYW4gYmUgdGhyb3duLgorICAgICAgICBMb2cuZSgKKyAgICAgICAgICAgIFRBRywKKyAgICAgICAgICAgIFN0cmluZy5mb3JtYXQoCisgICAgICAgICAgICAgICAgIkludmFsaWQgbWVzc2FnZSBzaXplOiAlZC4gTWF5IGhhdmUgZ2l2ZW4gdGhlIHdyb25nIG1lc3NhZ2UgdHlwZTogJXMiLAorICAgICAgICAgICAgICAgIGJ5dGVzSW5NZXNzYWdlLCB0eXBlbmFtZSkpOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKworICAgICAgaWYgKCF0YWlsQ3JjKSB7CisgICAgICAgIC8vIE1heSBoYXZlIHJlYWQgYSBnYXJiYWdlIHNpemUuIFJlYWQgY2FyZWZ1bGx5LgorICAgICAgICBpZiAoZW5kIDwgYnVmLnBvc2l0aW9uKCkgKyBieXRlc0luTWVzc2FnZSArIENSQ19MRU4pIHsKKyAgICAgICAgICBMb2cuZSgKKyAgICAgICAgICAgICAgVEFHLAorICAgICAgICAgICAgICBTdHJpbmcuZm9ybWF0KCJJbnZhbGlkIG1lc3NhZ2Ugc2l6ZTogJWQgKGJ1ZmZlciBlbmQgaXMgJWQpIiwgYnl0ZXNJbk1lc3NhZ2UsIGVuZCkpOworICAgICAgICAgIHJldHVybiB0b1JldHVybjsKKyAgICAgICAgfQorICAgICAgICBsb25nIGNyYyA9IGJ1Zi5nZXRMb25nKGJ1Zi5wb3NpdGlvbigpICsgYnl0ZXNJbk1lc3NhZ2UpOworICAgICAgICBpZiAoIXZhbGlkYXRlQ1JDKGJ1Zi5hcnJheSgpLCBidWYuYXJyYXlPZmZzZXQoKSArIGJ1Zi5wb3NpdGlvbigpLCBieXRlc0luTWVzc2FnZSwgY3JjKSkgeworICAgICAgICAgIC8vIFJldHVybiB0aGUgdmFsaWQgbWVzc2FnZXMgd2UgaGF2ZSByZWFkIHNvIGZhci4KKyAgICAgICAgICByZXR1cm4gdG9SZXR1cm47CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgLy8gQWNjb3JkaW5nIHRvIEJ5dGVCdWZmZXIjYXJyYXkoKSdzIHNwZWMsIHRoaXMgc2hvdWxkIG5vdCBjb3B5IHRoZSBiYWNraW5nIGFycmF5CisgICAgICBkZXN0ID0KKyAgICAgICAgICB0cnlDcmVhdGUoCisgICAgICAgICAgICAgIGJ1Zi5hcnJheSgpLAorICAgICAgICAgICAgICBidWYuYXJyYXlPZmZzZXQoKSArIGJ1Zi5wb3NpdGlvbigpLAorICAgICAgICAgICAgICBieXRlc0luTWVzc2FnZSwKKyAgICAgICAgICAgICAgbWVzc2FnZVR5cGUsCisgICAgICAgICAgICAgIG1lc3NhZ2VQYXJzZXIpOworICAgICAgaWYgKGRlc3QgPT0gbnVsbCkgeworICAgICAgICAvLyBTb21ldGhpbmcgaXMgc2VyaW91c2x5IGhvc2VkIGF0IHRoaXMgcG9pbnQsIHJldHVybiBub3RoaW5nLgorICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIHRvUmV0dXJuLmFkZChkZXN0KTsKKyAgICAgIC8vIEFkdmFuY2UgdGhlIGJ1ZmZlciBtYW51YWxseSwgc2luY2Ugd2UgcmVhZCBmcm9tIGl0ICJyYXciIGZyb20gdGhlIGFycmF5IGFib3ZlCisgICAgICBidWYucG9zaXRpb24oYnVmLnBvc2l0aW9uKCkgKyBieXRlc0luTWVzc2FnZSArICh0YWlsQ3JjID8gMCA6IENSQ19MRU4pKTsKKyAgICB9CisgICAgcmV0dXJuIHRvUmV0dXJuOworICB9CisKKyAgQE51bGxhYmxlCisgIHByaXZhdGUgc3RhdGljIDxUIGV4dGVuZHMgTWVzc2FnZUxpdGU+IFQgdHJ5Q3JlYXRlKAorICAgICAgYnl0ZVtdIGFyciwgaW50IHBvcywgaW50IGxlbiwgQ2xhc3M8VD4gdHlwZSwgUGFyc2VyPFQ+IHBhcnNlcikgeworICAgIHRyeSB7CisgICAgICAvLyBDYW5ub3QgdXNlIGdlbmVyYXRlZCByZWdpc3RyeSBoZXJlLCBiZWNhdXNlIGl0IG1heSBjYXVzZSBOUEUgdG8gY2xpZW50cy4KKyAgICAgIC8vIEZvciBtb3JlIGRldGFpbCwgc2VlIGIvMTQwMTM1MDU5LgorICAgICAgcmV0dXJuIHBhcnNlci5wYXJzZUZyb20oYXJyLCBwb3MsIGxlbiwgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmdldEVtcHR5UmVnaXN0cnkoKSk7CisgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGV4KSB7CisgICAgICBMb2cuZShUQUcsICJDYW5ub3QgZGVzZXJpYWxpemUgbWVzc2FnZSBvZiB0eXBlICIgKyB0eXBlLCBleCk7CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogU2VyaWFsaXplcyB0aGUgZ2l2ZW4gTWVzc2FnZUxpdGUgbWVzc2FnZXMgaW50byBhIEJ5dGVCdWZmZXIsIHdpdGggZWl0aGVyIGEgQ1JDIG9mIHRoZSB3aG9sZQorICAgKiBjb250ZW50IGF0IHRoZSBlbmQgb2YgdGhlIGJ1ZmZlciAodGFpbCBDUkMpIG9yIGEgQ1JDIG9mIGV2ZXJ5IG1lc3NhZ2UgYXQgdGhlIGVuZCBvZiB0aGUKKyAgICogbWVzc2FnZS4KKyAgICoKKyAgICogQHBhcmFtIGNvbGwgVGhlIG1lc3NhZ2VzIHRvIHdyaXRlLgorICAgKiBAcGFyYW0gdGFpbENyYyB0cnVlIHRvIHVzZSBhIHRhaWwgQ1JDLCBmYWxzZSB0byBwdXQgYSBDUkMgYWZ0ZXIgZXZlcnkgbWVzc2FnZS4KKyAgICogQHJldHVybiBBIEJ5dGVCdWZmZXIgY29udGFpbmluZyB0aGUgc2VyaWFsaXplZCBtZXNzYWdlcy4KKyAgICovCisgIEBOdWxsYWJsZQorICBwdWJsaWMgc3RhdGljIDxUIGV4dGVuZHMgTWVzc2FnZUxpdGU+IEJ5dGVCdWZmZXIgZHVtcEludG9CdWZmZXIoCisgICAgICBJdGVyYWJsZTxUPiBjb2xsLCBib29sZWFuIHRhaWxDcmMpIHsKKyAgICBpbnQgY291bnQgPSAwOworICAgIGxvbmcgdG9Xcml0ZU91dCA9IHRhaWxDcmMgPyBDUkNfTEVOIDogMDsKKworICAgIGZpbmFsIGludCBleHRyYUJ5dGVzUGVyTWVzc2FnZSA9IHRhaWxDcmMgPyBJTlRfQllURV9TSVpFIDogSU5UX0JZVEVfU0laRSArIENSQ19MRU47CisgICAgLy8gRmlyc3QsIGdldCB0aGUgc2l6ZSBvZiBob3cgbXVjaCB3aWxsIGJlIHdyaXR0ZW4gb3V0CisgICAgLy8gVE9ETyBmaW5kIG91dCBpZiB0aGVyZSBpcyBhIGFkZGVyIHV0aWwgdGhpbmd5IEkgY2FuIHVzZSAoY291bGQgYmUgcGFyYWxsZWwpCisgICAgZm9yIChNZXNzYWdlTGl0ZSBtZXNzIDogY29sbCkgeworICAgICAgdG9Xcml0ZU91dCArPSBleHRyYUJ5dGVzUGVyTWVzc2FnZSArIG1lc3MuZ2V0U2VyaWFsaXplZFNpemUoKTsKKyAgICAgICsrY291bnQ7CisgICAgfQorICAgIGlmIChjb3VudCA9PSAwKSB7CisgICAgICAvLyBJZiB0aGVyZSBhcmUgbm8gY291bnRlcnMgdG8gd3JpdGUsIGRvbid0IGV2ZW4gYm90aGVyIHdpdGggdGhlIGNoZWNrc3VtLgorICAgICAgcmV0dXJuIEJ5dGVCdWZmZXIuYWxsb2NhdGUoMCk7CisgICAgfQorICAgIC8vIE5vdyB3ZSBnb3QgdGhpcywgbWFrZSBhIEJ5dGVCdWZmZXIgdG8gaG9sZCBhbGwgdGhhdCB3ZSBuZWVkIHRvCisgICAgQnl0ZUJ1ZmZlciBidWZmID0gbnVsbDsKKyAgICB0cnkgeworICAgICAgYnVmZiA9IEJ5dGVCdWZmZXIuYWxsb2NhdGUoKGludCkgdG9Xcml0ZU91dCk7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGV4KSB7CisgICAgICBMb2cuZShUQUcsIFN0cmluZy5mb3JtYXQoIlRvbyBiaWcgdG8gc2VyaWFsaXplLCAlcyIsIHByZXR0eVByaW50Qnl0ZXModG9Xcml0ZU91dCkpLCBleCk7CisgICAgICByZXR1cm4gbnVsbDsKKyAgICB9CisKKyAgICAvLyBBY2NvcmRpbmcgdG8gQnl0ZUJ1ZmZlciNhcnJheSgpJ3Mgc3BlYywgdGhpcyBzaG91bGQgbm90IGNvcHkgdGhlIGJhY2tpbmcgYXJyYXkKKyAgICBieXRlW10gYXJyID0gYnVmZi5hcnJheSgpOworICAgIC8vIEFsc28gY29udmVuaWVudGx5IGlzIHdoZXJlIHdlIG5lZWQgdG8gd3JpdGUgbmV4dAorICAgIGludCB3cml0dGVuU29GYXIgPSAwOworICAgIC8vIE5vdyBhZGQgaW4gdGhlIHNlcmlhbGl6ZWQgZm9ybXMKKyAgICBmb3IgKE1lc3NhZ2VMaXRlIG1lc3MgOiBjb2xsKSB7CisgICAgICAvLyBBcyB3ZSBjYWxsZWQgZ2V0U2VyaWFsaXplZFNpemUgYWJvdmUsIHRoaXMgaXMgYXNzdXJlZCB0byBnaXZlIHVzIGEgbm9uLWJvZ3VzIGFuc3dlcgorICAgICAgaW50IGJ5dGVzSW5NZXNzYWdlID0gbWVzcy5nZXRTZXJpYWxpemVkU2l6ZSgpOworICAgICAgdHJ5IHsKKyAgICAgICAgYnVmZi5wdXRJbnQoYnl0ZXNJbk1lc3NhZ2UpOworICAgICAgfSBjYXRjaCAoQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgaGFuZGxlQnVmZmVyT3ZlcmZsb3coZXgpOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICAgIHdyaXR0ZW5Tb0ZhciArPSBJTlRfQllURV9TSVpFOworICAgICAgLy8gV2UgYXJlIHdyaXRpbmcgcGFzdCB0aGUgZW5kIG9mIHdoZXJlIGJ1ZmYgaXMgY3VycmVudGx5ICJsb29raW5nIGF0IiwKKyAgICAgIC8vIFNvIHJldXNpbmcgdGhlIGJhY2tpbmcgYXJyYXkgaGVyZSBzaG91bGQgYmUgZmluZS4KKyAgICAgIHRyeSB7CisgICAgICAgIG1lc3Mud3JpdGVUbyhDb2RlZE91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZShhcnIsIHdyaXR0ZW5Tb0ZhciwgYnl0ZXNJbk1lc3NhZ2UpKTsKKyAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgTG9nLmUoVEFHLCAiRXhjZXB0aW9uIHdoaWxlIHdyaXRpbmcgdG8gYnVmZmVyLiIsIGUpOworICAgICAgfQorCisgICAgICAvLyBTYW1lIGFzIGFib3ZlLCBidXQgcmVhZGluZyBwYXN0IHRoZSBlbmQgdGhpcyB0aW1lLgorICAgICAgdHJ5IHsKKyAgICAgICAgYnVmZi5wdXQoYXJyLCB3cml0dGVuU29GYXIsIGJ5dGVzSW5NZXNzYWdlKTsKKyAgICAgIH0gY2F0Y2ggKEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uIGV4KSB7CisgICAgICAgIGhhbmRsZUJ1ZmZlck92ZXJmbG93KGV4KTsKKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgICB3cml0dGVuU29GYXIgKz0gYnl0ZXNJbk1lc3NhZ2U7CisgICAgICBpZiAoIXRhaWxDcmMpIHsKKyAgICAgICAgYXBwZW5kQ1JDKGJ1ZmYsIGFyciwgd3JpdHRlblNvRmFyIC0gYnl0ZXNJbk1lc3NhZ2UsIGJ5dGVzSW5NZXNzYWdlKTsKKyAgICAgICAgd3JpdHRlblNvRmFyICs9IENSQ19MRU47CisgICAgICB9CisgICAgfQorICAgIGlmICh0YWlsQ3JjKSB7CisgICAgICB0cnkgeworICAgICAgICBhcHBlbmRDUkMoYnVmZiwgYXJyLCAwLCB3cml0dGVuU29GYXIpOworICAgICAgfSBjYXRjaCAoQnVmZmVyT3ZlcmZsb3dFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgaGFuZGxlQnVmZmVyT3ZlcmZsb3coZXgpOworICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgIH0KKyAgICB9CisgICAgYnVmZi5yZXdpbmQoKTsKKyAgICByZXR1cm4gYnVmZjsKKyAgfQorCisgIC8qKiBSZXR1cm4gc3RyaW5nIGZyb20gcHJvdG8gYnl0ZXMgd2hlbiB3ZSBrbm93IGJ5dGVzIGFyZSBVVEYtOC4gKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0RGF0YVN0cmluZyhieXRlW10gZGF0YSkgeworICAgIHJldHVybiBuZXcgU3RyaW5nKGRhdGEsIENoYXJzZXQuZm9yTmFtZSgiVVRGLTgiKSk7CisgIH0KKworICAvKiogUmV0dXJuIG51bGwgaWYgaW5wdXQgaXMgZW1wdHkgKG9yIG51bGwpLiAqLworICBATnVsbGFibGUKKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgbnVsbElmRW1wdHkoU3RyaW5nIGlucHV0KSB7CisgICAgcmV0dXJuIFRleHRVdGlscy5pc0VtcHR5KGlucHV0KSA/IG51bGwgOiBpbnB1dDsKKyAgfQorCisgIC8qKiBSZXR1cm4gbnVsbCBpZiBpbnB1dCBhcnJheSBpcyBlbXB0eSAob3IgbnVsbCkuICovCisgIEBOdWxsYWJsZQorICBwdWJsaWMgc3RhdGljIDxUPiBUW10gbnVsbElmRW1wdHkoVFtdIGlucHV0KSB7CisgICAgcmV0dXJuIGlucHV0ID09IG51bGwgfHwgaW5wdXQubGVuZ3RoID09IDAgPyBudWxsIDogaW5wdXQ7CisgIH0KKworICAvKiogU2ltaWxhciB0byBPYmplY3RzLmVxdWFsIGJ1dCBhdmFpbGFibGUgcHJlLWtpdGthdC4gKi8KKyAgcHVibGljIHN0YXRpYyBib29sZWFuIHNhZmVFcXVhbChPYmplY3QgYSwgT2JqZWN0IGIpIHsKKyAgICByZXR1cm4gYSA9PSBudWxsID8gYiA9PSBudWxsIDogYS5lcXVhbHMoYik7CisgIH0KKworICAvKiogV3JhcHMgTWVzc2FnZUxpdGUudG9CeXRlQXJyYXkgdG8gY2hlY2sgZm9yIG51bGwgYW5kIHJldHVybiBudWxsIGlmIHRoYXQncyB0aGUgY2FzZS4gKi8KKyAgQE51bGxhYmxlCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZVtdIHNhZmVUb0J5dGVBcnJheShNZXNzYWdlTGl0ZSBtc2cpIHsKKyAgICByZXR1cm4gbXNnID09IG51bGwgPyBudWxsIDogbXNnLnRvQnl0ZUFycmF5KCk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyB2b2lkIGhhbmRsZUJ1ZmZlclVuZGVyZmxvdyhCdWZmZXJVbmRlcmZsb3dFeGNlcHRpb24gZXgsIFN0cmluZyB0eXBlbmFtZSkgeworICAgIExvZy5lKAorICAgICAgICBUQUcsCisgICAgICAgIFN0cmluZy5mb3JtYXQoIkJ1ZmZlciB1bmRlcmZsb3cuIE1heSBoYXZlIGdpdmVuIHRoZSB3cm9uZyBtZXNzYWdlIHR5cGU6ICVzIiwgdHlwZW5hbWUpLAorICAgICAgICBleCk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyB2b2lkIGhhbmRsZUJ1ZmZlck92ZXJmbG93KEJ1ZmZlck92ZXJmbG93RXhjZXB0aW9uIGV4KSB7CisgICAgTG9nLmUoCisgICAgICAgIFRBRywKKyAgICAgICAgIkJ1ZmZlciB1bmRlcmZsb3cuIEEgbWVzc2FnZSBtYXkgaGF2ZSBhbiBpbnZhbGlkIHNlcmlhbGl6ZWQgZm9ybSIKKyAgICAgICAgICAgICsgIiBvciBoYXMgYmVlbiBjb25jdXJyZW50bHkgbW9kaWZpZWQuIiwKKyAgICAgICAgZXgpOworICB9CisKKyAgLyoqCisgICAqIFJlYWRzIHRoZSBieXRlcyBnaXZlbiBpbiBhbiBhcnJheSBhbmQgYXBwZW5kcyB0aGUgQ1JDMzIgY2hlY2tzdW0gdG8gdGhlIEJ5dGVCdWZmZXIuIFRoZQorICAgKiBsb2NhdGlvbiB0aGUgQ1JDMzIgY2hlY2tzdW0gd2lsbCBiZSB3cml0dGVuIGlzIHRoZSB7QGxpbmsgQnl0ZUJ1ZmZlciNwb3NpdGlvbigpIGN1cnJlbnQKKyAgICogcG9zaXRpb259IGluIHRoZSBCeXRlQnVmZmVyLiBUaGUgZ2l2ZW4gQnl0ZUJ1ZmZlciBtdXN0IGhhdmUgbXVzdCBoYXZlIGVub3VnaCByb29tIChzdGFydGluZyBhdAorICAgKiBpdHMgcG9zaXRpb24pIHRvIGZpdCBhbiBhZGRpdG9uYWwge0BsaW5rICNDUkNfTEVOfSBieXRlcy4KKyAgICoKKyAgICogQHBhcmFtIGRlc3Qgd2hlcmUgdG8gd3JpdGUgdGhlIENSQzMyIGNoZWNrc3VtOyBtdXN0IGhhdmUgZW5vdWdoIHJvb20gdG8gZml0IGFuIGFkZGl0b25hbCB7QGxpbmsKKyAgICogICAgICNDUkNfTEVOfSBieXRlcworICAgKiBAcGFyYW0gc3JjIHRoZSBhcnJheSBvZiBieXRlcyBjb250YWluaW5nIHRoZSBkYXRhIHRvIGNoZWNrc3VtCisgICAqIEBwYXJhbSBvZmYgb2Zmc2V0IG9mIHdoZXJlIHRvIHN0YXJ0IHJlYWRpbmcgdGhlIGFycmF5CisgICAqIEBwYXJhbSBsZW4gbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQgaW4gdGhlIGFycmF5CisgICAqLworICBwcml2YXRlIHN0YXRpYyB2b2lkIGFwcGVuZENSQyhCeXRlQnVmZmVyIGRlc3QsIGJ5dGVbXSBzcmMsIGludCBvZmYsIGludCBsZW4pIHsKKyAgICBDUkMzMiBjcmMgPSBuZXcgQ1JDMzIoKTsKKyAgICBjcmMudXBkYXRlKHNyYywgb2ZmLCBsZW4pOworICAgIGRlc3QucHV0TG9uZyhjcmMuZ2V0VmFsdWUoKSk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBib29sZWFuIHZhbGlkYXRlQ1JDKGJ5dGVbXSBhcnIsIGludCBvZmYsIGludCBsZW4sIGxvbmcgZXhwZWN0ZWRDUkMpIHsKKyAgICBDUkMzMiBjcmMgPSBuZXcgQ1JDMzIoKTsKKyAgICBjcmMudXBkYXRlKGFyciwgb2ZmLCBsZW4pOworICAgIGxvbmcgY29tcHV0ZWRDUkMgPSBjcmMuZ2V0VmFsdWUoKTsKKyAgICBib29sZWFuIG1hdGNoZWQgPSBjb21wdXRlZENSQyA9PSBleHBlY3RlZENSQzsKKyAgICBpZiAoIW1hdGNoZWQpIHsKKyAgICAgIExvZy5lKAorICAgICAgICAgIFRBRywKKyAgICAgICAgICBTdHJpbmcuZm9ybWF0KAorICAgICAgICAgICAgICAiQ29ycnVwdCBwcm90b2J1ZiBkYXRhLCBleHBlY3RlZCBDUkM6ICVkIGNvbXB1dGVkIENSQzogJWQiLAorICAgICAgICAgICAgICBleHBlY3RlZENSQywgY29tcHV0ZWRDUkMpKTsKKyAgICB9CisgICAgcmV0dXJuIG1hdGNoZWQ7CisgIH0KKworICBwcml2YXRlIFByb3RvTGl0ZVV0aWwoKSB7CisgICAgLy8gTm8gaW5zdGFudGlhdGlvbi4KKyAgfQorCisgIHByaXZhdGUgc3RhdGljIFN0cmluZyBwcmV0dHlQcmludEJ5dGVzKGxvbmcgYnl0ZXMpIHsKKyAgICBpZiAoYnl0ZXMgPiAxMDI0TCAqIDEwMjQgKiAxMDI0KSB7CisgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdChMb2NhbGUuVVMsICIlLjJmR0IiLCAoZG91YmxlKSBieXRlcyAvICgxMDI0TCAqIDEwMjQgKiAxMDI0KSk7CisgICAgfSBlbHNlIGlmIChieXRlcyA+IDEwMjQgKiAxMDI0KSB7CisgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdChMb2NhbGUuVVMsICIlLjJmTUIiLCAoZG91YmxlKSBieXRlcyAvICgxMDI0ICogMTAyNCkpOworICAgIH0gZWxzZSBpZiAoYnl0ZXMgPiAxMDI0KSB7CisgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdChMb2NhbGUuVVMsICIlLjJmS0IiLCAoZG91YmxlKSBieXRlcyAvIDEwMjQpOworICAgIH0KKyAgICByZXR1cm4gU3RyaW5nLmZvcm1hdChMb2NhbGUuVVMsICIlZCBCeXRlcyIsIGJ5dGVzKTsKKyAgfQorfQorLy8gTElOVC5UaGVuQ2hhbmdlKDxpbnRlcm5hbD4pCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9TaGFyZWRGaWxlc01ldGFkYXRhVXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMyMzgxOWIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuamF2YQpAQCAtMCwwICsxLDE1NCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZGRDb25zdGFudHMuU1BMSVRfQ0hBUjsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlNpbGVudEZlZWRiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1pZ3JhdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5TcGxpdHRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm1zOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsLkFsbG93ZWRSZWFkZXJzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uTmV3RmlsZUtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqIFV0aWxpdGllcyBuZWVkZWQgYnkgbXVsdGlwbGUgaW1wbGVtZW50YXRpb25zIG9mIHtAbGluayBTaGFyZWRGaWxlc01ldGFkYXRhfS4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBTaGFyZWRGaWxlc01ldGFkYXRhVXRpbCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJTaGFyZWRGaWxlc01ldGFkYXRhVXRpbCI7CisKKyAgLy8gU3RvcmVzIHRoZSBtYXBwaW5nIGZyb20gRmlsZUtleTpTaGFyZWRGaWxlLgorICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNRERfU0hBUkVEX0ZJTEVTID0gImdtc19pY2luZ19tZGRfc2hhcmVkX2ZpbGVzIjsKKworICAvKiogRmlsZSBrZXkgRGVzZXJpYWxpemF0aW9uIGV4Y2VwdGlvbi4gKi8KKyAgcHVibGljIHN0YXRpYyBjbGFzcyBGaWxlS2V5RGVzZXJpYWxpemF0aW9uRXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKKyAgICBGaWxlS2V5RGVzZXJpYWxpemF0aW9uRXhjZXB0aW9uKFN0cmluZyBtc2cpIHsKKyAgICAgIHN1cGVyKG1zZyk7CisgICAgfQorCisgICAgRmlsZUtleURlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbihTdHJpbmcgbXNnLCBUaHJvd2FibGUgY2F1c2UpIHsKKyAgICAgIHN1cGVyKG1zZywgY2F1c2UpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFNlcmlhbGl6ZWRGaWxlS2V5KAorICAgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5LCBDb250ZXh0IGNvbnRleHQsIFNpbGVudEZlZWRiYWNrIHNpbGVudEZlZWRiYWNrKSB7CisgICAgc3dpdGNoIChNaWdyYXRpb25zLmdldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIHNpbGVudEZlZWRiYWNrKSkgeworICAgICAgY2FzZSBORVdfRklMRV9LRVk6CisgICAgICAgIHJldHVybiBzZXJpYWxpemVOZXdGaWxlS2V5KG5ld0ZpbGVLZXkpOworICAgICAgY2FzZSBBRERfRE9XTkxPQURfVFJBTlNGT1JNOgorICAgICAgICByZXR1cm4gc2VyaWFsaXplTmV3RmlsZUtleVdpdGhEb3dubG9hZFRyYW5zZm9ybShuZXdGaWxlS2V5KTsKKyAgICAgIGNhc2UgVVNFX0NIRUNLU1VNX09OTFk6CisgICAgICAgIHJldHVybiBzZXJpYWxpemVOZXdGaWxlS2V5V2l0aENoZWNrc3VtT25seShuZXdGaWxlS2V5KTsKKyAgICB9CisgICAgcmV0dXJuIHNlcmlhbGl6ZU5ld0ZpbGVLZXkobmV3RmlsZUtleSk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIFN0cmluZyBzZXJpYWxpemVOZXdGaWxlS2V5KE5ld0ZpbGVLZXkgbmV3RmlsZUtleSkgeworICAgIHJldHVybiBuZXcgU3RyaW5nQnVpbGRlcihuZXdGaWxlS2V5LmdldFVybFRvRG93bmxvYWQoKSkKKyAgICAgICAgLmFwcGVuZChTUExJVF9DSEFSKQorICAgICAgICAuYXBwZW5kKG5ld0ZpbGVLZXkuZ2V0Qnl0ZVNpemUoKSkKKyAgICAgICAgLmFwcGVuZChTUExJVF9DSEFSKQorICAgICAgICAuYXBwZW5kKG5ld0ZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSkKKyAgICAgICAgLmFwcGVuZChTUExJVF9DSEFSKQorICAgICAgICAuYXBwZW5kKG5ld0ZpbGVLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKS5nZXROdW1iZXIoKSkKKyAgICAgICAgLnRvU3RyaW5nKCk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIFN0cmluZyBzZXJpYWxpemVOZXdGaWxlS2V5V2l0aERvd25sb2FkVHJhbnNmb3JtKE5ld0ZpbGVLZXkgbmV3RmlsZUtleSkgeworICAgIHJldHVybiBuZXcgU3RyaW5nQnVpbGRlcihuZXdGaWxlS2V5LmdldFVybFRvRG93bmxvYWQoKSkKKyAgICAgICAgLmFwcGVuZChTUExJVF9DSEFSKQorICAgICAgICAuYXBwZW5kKG5ld0ZpbGVLZXkuZ2V0Qnl0ZVNpemUoKSkKKyAgICAgICAgLmFwcGVuZChTUExJVF9DSEFSKQorICAgICAgICAuYXBwZW5kKG5ld0ZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSkKKyAgICAgICAgLmFwcGVuZChTUExJVF9DSEFSKQorICAgICAgICAuYXBwZW5kKG5ld0ZpbGVLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKS5nZXROdW1iZXIoKSkKKyAgICAgICAgLmFwcGVuZChTUExJVF9DSEFSKQorICAgICAgICAuYXBwZW5kKAorICAgICAgICAgICAgbmV3RmlsZUtleS5oYXNEb3dubG9hZFRyYW5zZm9ybXMoKQorICAgICAgICAgICAgICAgID8gU2hhcmVkUHJlZmVyZW5jZXNVdGlsLnNlcmlhbGl6ZVByb3RvKG5ld0ZpbGVLZXkuZ2V0RG93bmxvYWRUcmFuc2Zvcm1zKCkpCisgICAgICAgICAgICAgICAgOiAiIikKKyAgICAgICAgLnRvU3RyaW5nKCk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIFN0cmluZyBzZXJpYWxpemVOZXdGaWxlS2V5V2l0aENoZWNrc3VtT25seShOZXdGaWxlS2V5IG5ld0ZpbGVLZXkpIHsKKyAgICByZXR1cm4gbmV3IFN0cmluZ0J1aWxkZXIobmV3RmlsZUtleS5nZXRDaGVja3N1bSgpKQorICAgICAgICAuYXBwZW5kKFNQTElUX0NIQVIpCisgICAgICAgIC5hcHBlbmQobmV3RmlsZUtleS5nZXRBbGxvd2VkUmVhZGVycygpLmdldE51bWJlcigpKQorICAgICAgICAudG9TdHJpbmcoKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgTmV3RmlsZUtleSBkZXNlcmlhbGl6ZU5ld0ZpbGVLZXkoCisgICAgICBTdHJpbmcgc2VyaWFsaXplZEZpbGVLZXksIENvbnRleHQgY29udGV4dCwgU2lsZW50RmVlZGJhY2sgc2lsZW50RmVlZGJhY2spCisgICAgICB0aHJvd3MgRmlsZUtleURlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbiB7CisgICAgTGlzdDxTdHJpbmc+IGZpbGVLZXlDb21wb25lbnRzID0gU3BsaXR0ZXIub24oU1BMSVRfQ0hBUikuc3BsaXRUb0xpc3Qoc2VyaWFsaXplZEZpbGVLZXkpOworICAgIE5ld0ZpbGVLZXkuQnVpbGRlciBuZXdGaWxlS2V5OworCisgICAgc3dpdGNoIChNaWdyYXRpb25zLmdldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIHNpbGVudEZlZWRiYWNrKSkgeworICAgICAgY2FzZSBBRERfRE9XTkxPQURfVFJBTlNGT1JNOgorICAgICAgICBpZiAoZmlsZUtleUNvbXBvbmVudHMuc2l6ZSgpICE9IDUpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgRmlsZUtleURlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgIkJhZC1mb3JtYXQiICsgIiBzZXJpYWxpemVkRmlsZUtleSIgKyAiID0gIiArIHNlcmlhbGl6ZWRGaWxlS2V5KTsKKyAgICAgICAgfQorICAgICAgICBuZXdGaWxlS2V5ID0KKyAgICAgICAgICAgIE5ld0ZpbGVLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoZmlsZUtleUNvbXBvbmVudHMuZ2V0KDApKQorICAgICAgICAgICAgICAgIC5zZXRCeXRlU2l6ZShJbnRlZ2VyLnBhcnNlSW50KGZpbGVLZXlDb21wb25lbnRzLmdldCgxKSkpCisgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKGZpbGVLZXlDb21wb25lbnRzLmdldCgyKSkKKyAgICAgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnMoCisgICAgICAgICAgICAgICAgICAgIEFsbG93ZWRSZWFkZXJzLmZvck51bWJlcihJbnRlZ2VyLnBhcnNlSW50KGZpbGVLZXlDb21wb25lbnRzLmdldCgzKSkpKTsKKyAgICAgICAgaWYgKGZpbGVLZXlDb21wb25lbnRzLmdldCg0KSAhPSBudWxsICYmICFmaWxlS2V5Q29tcG9uZW50cy5nZXQoNCkuaXNFbXB0eSgpKSB7CisgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgIG5ld0ZpbGVLZXkuc2V0RG93bmxvYWRUcmFuc2Zvcm1zKAorICAgICAgICAgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5wYXJzZUxpdGVGcm9tRW5jb2RlZFN0cmluZygKKyAgICAgICAgICAgICAgICAgICAgZmlsZUtleUNvbXBvbmVudHMuZ2V0KDQpLCBUcmFuc2Zvcm1zLnBhcnNlcigpKSk7CisgICAgICAgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBGaWxlS2V5RGVzZXJpYWxpemF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gZGVzZXJpYWxpemUga2V5OiIgKyBzZXJpYWxpemVkRmlsZUtleSwgZSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBVU0VfQ0hFQ0tTVU1fT05MWToKKyAgICAgICAgaWYgKGZpbGVLZXlDb21wb25lbnRzLnNpemUoKSAhPSAyKSB7CisgICAgICAgICAgdGhyb3cgbmV3IEZpbGVLZXlEZXNlcmlhbGl6YXRpb25FeGNlcHRpb24oCisgICAgICAgICAgICAgICJCYWQtZm9ybWF0IiArICIgc2VyaWFsaXplZEZpbGVLZXkiICsgIiA9IHMiICsgc2VyaWFsaXplZEZpbGVLZXkpOworICAgICAgICB9CisgICAgICAgIG5ld0ZpbGVLZXkgPQorICAgICAgICAgICAgTmV3RmlsZUtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oZmlsZUtleUNvbXBvbmVudHMuZ2V0KDApKQorICAgICAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVycygKKyAgICAgICAgICAgICAgICAgICAgQWxsb3dlZFJlYWRlcnMuZm9yTnVtYmVyKEludGVnZXIucGFyc2VJbnQoZmlsZUtleUNvbXBvbmVudHMuZ2V0KDEpKSkpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6IC8vIEZhbGwgdGhyb3VnaAorICAgICAgICBpZiAoZmlsZUtleUNvbXBvbmVudHMuc2l6ZSgpICE9IDQpIHsKKyAgICAgICAgICB0aHJvdyBuZXcgRmlsZUtleURlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgIkJhZC1mb3JtYXQiICsgIiBzZXJpYWxpemVkRmlsZUtleSIgKyAiID0gIiArIHNlcmlhbGl6ZWRGaWxlS2V5KTsKKyAgICAgICAgfQorICAgICAgICBuZXdGaWxlS2V5ID0KKyAgICAgICAgICAgIE5ld0ZpbGVLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoZmlsZUtleUNvbXBvbmVudHMuZ2V0KDApKQorICAgICAgICAgICAgICAgIC5zZXRCeXRlU2l6ZShJbnRlZ2VyLnBhcnNlSW50KGZpbGVLZXlDb21wb25lbnRzLmdldCgxKSkpCisgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKGZpbGVLZXlDb21wb25lbnRzLmdldCgyKSkKKyAgICAgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnMoCisgICAgICAgICAgICAgICAgICAgIEFsbG93ZWRSZWFkZXJzLmZvck51bWJlcihJbnRlZ2VyLnBhcnNlSW50KGZpbGVLZXlDb21wb25lbnRzLmdldCgzKSkpKTsKKyAgICB9CisgICAgcmV0dXJuIG5ld0ZpbGVLZXkuYnVpbGQoKTsKKyAgfQorCisgIHByaXZhdGUgU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwoKSB7fQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL1NoYXJlZFByZWZlcmVuY2VzVXRpbC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL1NoYXJlZFByZWZlcmVuY2VzVXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU0MzQxYTIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmphdmEKQEAgLTAsMCArMSwxNjQgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWw7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuU2hhcmVkUHJlZmVyZW5jZXM7CitpbXBvcnQgYW5kcm9pZC51dGlsLkJhc2U2NDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DaGVja1JldHVyblZhbHVlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGU7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworCisvKioKKyAqIFNpbXBsZSB1dGlsIHRvIHJlYWQvd3JpdGUgcHJvdG9zIGZyb20vdG8ge0BsaW5rIFNoYXJlZFByZWZlcmVuY2VzfS4KKyAqCisgKiA8cD5Qcm90b3MgYXJlIHNlcmlhbGl6ZWQsIGFuZCB0aGUgYmluYXJ5IHZhbHVlIGlzIGJhc2UtNjQgZW5jb2RlZCB3aXRob3V0IHBhZGRpbmcgb3Igd3JhcHBpbmcuCisgKi8KK0BDaGVja1JldHVyblZhbHVlCitwdWJsaWMgY2xhc3MgU2hhcmVkUHJlZmVyZW5jZXNVdGlsIHsKKworICAvKioKKyAgICogUmVhZHMgdGhlIHNoYXJlZCBwcmVmIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNwZWNpZmllZCBrZXkgYXMgYSBsaXRlIHByb3RvIG9mIHR5cGUgJ1QnLiBUaGUKKyAgICogcmVhZCB2YWx1ZSBpcyBwb3B1bGF0ZWQgdG8gJ3Byb3RvVmFsdWUnIHdoaWNoIHNob3VsZCBhbHJlYWR5IGJlIGNvbnN0cnVjdGVkIGJ5IHRoZSBjYWxsZXIuCisgICAqCisgICAqIEByZXR1cm4gdGhlIHByb3RvIG9yIG51bGwgaWYgbm8gc3VjaCBlbGVtZW50IHdhcyBmb3VuZCBvciBjb3VsZCBub3QgYmUgcGFyc2VkLgorICAgKi8KKyAgQE51bGxhYmxlCisgIHB1YmxpYyBzdGF0aWMgPEsgZXh0ZW5kcyBNZXNzYWdlTGl0ZSwgViBleHRlbmRzIE1lc3NhZ2VMaXRlPiBWIHJlYWRQcm90bygKKyAgICAgIFNoYXJlZFByZWZlcmVuY2VzIHByZWZzLCBLIGxpdGVLZXksIFBhcnNlcjxWPiBwYXJzZXIpIHsKKyAgICByZXR1cm4gcmVhZFByb3RvKHByZWZzLCBzZXJpYWxpemVQcm90byhsaXRlS2V5KSwgcGFyc2VyKTsKKyAgfQorCisgIC8qKgorICAgKiBSZWFkcyB0aGUgc2hhcmVkIHByZWYgdmFsdWUgY29ycmVzcG9uZGluZyB0byB0aGUgc3BlY2lmaWVkIGtleSBhcyBhIGxpdGUgcHJvdG8gb2YgdHlwZSAnVCcuIFRoZQorICAgKiByZWFkIHZhbHVlIGlzIHBvcHVsYXRlZCB0byAncHJvdG9WYWx1ZScgd2hpY2ggc2hvdWxkIGFscmVhZHkgYmUgY29uc3RydWN0ZWQgYnkgdGhlIGNhbGxlci4KKyAgICoKKyAgICogQHJldHVybiB0aGUgcHJvdG8gb3IgbnVsbCBpZiBubyBzdWNoIGVsZW1lbnQgd2FzIGZvdW5kIG9yIGNvdWxkIG5vdCBiZSBwYXJzZS4KKyAgICovCisgIEBOdWxsYWJsZQorICBwdWJsaWMgc3RhdGljIDxUIGV4dGVuZHMgTWVzc2FnZUxpdGU+IFQgcmVhZFByb3RvKAorICAgICAgU2hhcmVkUHJlZmVyZW5jZXMgcHJlZnMsIFN0cmluZyBrZXksIFBhcnNlcjxUPiBwYXJzZXIpIHsKKyAgICBTdHJpbmcgZW5jb2RlZExpdGVTdHJpbmcgPSBwcmVmcy5nZXRTdHJpbmcoa2V5LCBudWxsKTsKKyAgICBpZiAoZW5jb2RlZExpdGVTdHJpbmcgPT0gbnVsbCkgeworICAgICAgcmV0dXJuIG51bGw7CisgICAgfQorICAgIHRyeSB7CisgICAgICByZXR1cm4gcGFyc2VMaXRlRnJvbUVuY29kZWRTdHJpbmcoZW5jb2RlZExpdGVTdHJpbmcsIHBhcnNlcik7CisgICAgfSBjYXRjaCAoSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKKyAgICAgIHJldHVybiBudWxsOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSBhbmQgY29tbWl0IHRoZSBzZXJpYWxpemVkIGZvcm0gb2YgdGhlIHByb3RvIGludG8gcHJlZiwgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZSBwcm90bworICAgKiBrZXkuCisgICAqLworICBwdWJsaWMgc3RhdGljIDxUIGV4dGVuZHMgTWVzc2FnZUxpdGU+IGJvb2xlYW4gd3JpdGVQcm90bygKKyAgICAgIFNoYXJlZFByZWZlcmVuY2VzIHByZWZzLCBmaW5hbCBTdHJpbmcga2V5LCBmaW5hbCBUIHByb3RvVmFsdWUpIHsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcy5FZGl0b3IgZWRpdG9yID0gcHJlZnMuZWRpdCgpOworICAgIHdyaXRlUHJvdG8oZWRpdG9yLCBrZXksIHByb3RvVmFsdWUpOworICAgIHJldHVybiBlZGl0b3IuY29tbWl0KCk7CisgIH0KKworICAvKioKKyAgICogV3JpdGUgYW5kIGNvbW1pdCB0aGUgc2VyaWFsaXplZCBmb3JtIG9mIHRoZSBwcm90byBpbnRvIHByZWYsIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmUgcHJvdG8KKyAgICoga2V5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyA8SyBleHRlbmRzIE1lc3NhZ2VMaXRlLCBUIGV4dGVuZHMgTWVzc2FnZUxpdGU+IGJvb2xlYW4gd3JpdGVQcm90bygKKyAgICAgIFNoYXJlZFByZWZlcmVuY2VzIHByZWZzLCBmaW5hbCBLIHByb3RvS2V5LCBmaW5hbCBUIHByb3RvVmFsdWUpIHsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcy5FZGl0b3IgZWRpdG9yID0gcHJlZnMuZWRpdCgpOworICAgIHdyaXRlUHJvdG8oZWRpdG9yLCBwcm90b0tleSwgcHJvdG9WYWx1ZSk7CisgICAgcmV0dXJuIGVkaXRvci5jb21taXQoKTsKKyAgfQorCisgIC8qKgorICAgKiBXcml0ZSB0aGUgc2VyaWFsaXplZCBmb3JtIG9mIHRoZSBwcm90byBpbnRvIHNoYXJlZCBwcmVmLCBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBwcm90byBrZXkuCisgICAqLworICBwdWJsaWMgc3RhdGljIDxLIGV4dGVuZHMgTWVzc2FnZUxpdGUsIFQgZXh0ZW5kcyBNZXNzYWdlTGl0ZT4gdm9pZCB3cml0ZVByb3RvKAorICAgICAgU2hhcmVkUHJlZmVyZW5jZXMuRWRpdG9yIGVkaXRvciwgZmluYWwgSyBwcm90b0tleSwgZmluYWwgVCBwcm90b1ZhbHVlKSB7CisgICAgd3JpdGVQcm90byhlZGl0b3IsIHNlcmlhbGl6ZVByb3RvKHByb3RvS2V5KSwgcHJvdG9WYWx1ZSk7CisgIH0KKworICAvKioKKyAgICogV3JpdGUgdGhlIHNlcmlhbGl6ZWQgZm9ybSBvZiB0aGUgcHJvdG8gaW50byBzaGFyZWQgcHJlZiwgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gc3RyaW5nIGtleS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgPFQgZXh0ZW5kcyBNZXNzYWdlTGl0ZT4gdm9pZCB3cml0ZVByb3RvKAorICAgICAgU2hhcmVkUHJlZmVyZW5jZXMuRWRpdG9yIGVkaXRvciwgZmluYWwgU3RyaW5nIGtleSwgZmluYWwgVCBwcm90b1ZhbHVlKSB7CisgICAgZWRpdG9yLnB1dFN0cmluZyhrZXksIHNlcmlhbGl6ZVByb3RvKHByb3RvVmFsdWUpKTsKKyAgfQorCisgIC8qKiBSZW1vdmVzIHdoYXRldmVyIHZhbHVlIGNvcnJlc3BvbmRzIHRoZSBwcm90b0tleSBmcm9tIHNoYXJlZCBwcmVmcy4gKi8KKyAgcHVibGljIHN0YXRpYyA8SyBleHRlbmRzIE1lc3NhZ2VMaXRlPiBib29sZWFuIHJlbW92ZVByb3RvKAorICAgICAgU2hhcmVkUHJlZmVyZW5jZXMgcHJlZnMsIFN0cmluZyBwcm90b0tleSkgeworICAgIHJldHVybiBwcmVmcy5lZGl0KCkucmVtb3ZlKHByb3RvS2V5KS5jb21taXQoKTsKKyAgfQorCisgIC8qKiBSZW1vdmVzIHdoYXRldmVyIHZhbHVlIGNvcnJlc3BvbmRzIHRoZSBwcm90b0tleSBmcm9tIHNoYXJlZCBwcmVmcy4gKi8KKyAgcHVibGljIHN0YXRpYyA8SyBleHRlbmRzIE1lc3NhZ2VMaXRlPiB2b2lkIHJlbW92ZVByb3RvKAorICAgICAgU2hhcmVkUHJlZmVyZW5jZXMuRWRpdG9yIGVkaXRvciwgZmluYWwgSyBwcm90b0tleSkgeworICAgIGVkaXRvci5yZW1vdmUoc2VyaWFsaXplUHJvdG8ocHJvdG9LZXkpKTsKKyAgfQorCisgIC8qKiBSZW1vdmVzIHdoYXRldmVyIHZhbHVlIGNvcnJlc3BvbmRzIHRoZSBwcm90b0tleSBmcm9tIHNoYXJlZCBwcmVmcy4gKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHJlbW92ZVByb3RvKFNoYXJlZFByZWZlcmVuY2VzLkVkaXRvciBlZGl0b3IsIFN0cmluZyBwcm90b0tleSkgeworICAgIGVkaXRvci5yZW1vdmUocHJvdG9LZXkpOworICB9CisKKyAgLyoqIENvbnZlcnRzIGEgTWVzc2FnZUxpdGUgdG8gYSBzdHJpbmcgdGhhdCBjYW4gYmUgdXNlZCBhcyBhIGtleSBpbiBzaGFyZWQgcHJlZnMuICovCisgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNlcmlhbGl6ZVByb3RvKE1lc3NhZ2VMaXRlIGxpdGUpIHsKKyAgICBieXRlW10gYnl0ZVZhbHVlID0gbGl0ZS50b0J5dGVBcnJheSgpOworICAgIHJldHVybiBCYXNlNjQuZW5jb2RlVG9TdHJpbmcoYnl0ZVZhbHVlLCBCYXNlNjQuTk9fUEFERElORyB8IEJhc2U2NC5OT19XUkFQKTsKKyAgfQorCisgIC8qKgorICAgKiBQYXJzZXMgYSBNZXNzYWdlTGl0ZSBmcm9tIHRoZSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcuCisgICAqCisgICAqIEByZXR1cm4gdGhlIHByb3RvLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyA8VCBleHRlbmRzIE1lc3NhZ2VMaXRlPiBUIHBhcnNlTGl0ZUZyb21FbmNvZGVkU3RyaW5nKAorICAgICAgU3RyaW5nIGJhc2U2NEVuY29kZWQsIFBhcnNlcjxUPiBwYXJzZXIpIHRocm93cyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24geworICAgIGJ5dGVbXSBieXRlVmFsdWU7CisgICAgdHJ5IHsKKyAgICAgIGJ5dGVWYWx1ZSA9IEJhc2U2NC5kZWNvZGUoYmFzZTY0RW5jb2RlZCwgQmFzZTY0Lk5PX1BBRERJTkcgfCBCYXNlNjQuTk9fV1JBUCk7CisgICAgfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oCisgICAgICAgICAgIlVuYWJsZSB0byBkZWNvZGUgdG8gYnl0ZSBhcnJheSIsIG5ldyBJT0V4Y2VwdGlvbihlKSk7CisgICAgfQorCisgICAgLy8gQ2Fubm90IHVzZSBnZW5lcmF0ZWQgcmVnaXN0cnkgaGVyZSwgYmVjYXVzZSBpdCBtYXkgY2F1c2UgTlBFIHRvIGNsaWVudHMuCisgICAgLy8gRm9yIG1vcmUgZGV0YWlsLCBzZWUgYi8xNDAxMzUwNTkuCisgICAgcmV0dXJuIHBhcnNlci5wYXJzZUZyb20oYnl0ZVZhbHVlLCBFeHRlbnNpb25SZWdpc3RyeUxpdGUuZ2V0RW1wdHlSZWdpc3RyeSgpKTsKKyAgfQorCisgIC8qKiBSZXR1cm5zIHRoZSBTaGFyZWRQcmVmZXJlbmNlcyBuYW1lIGZvciB7QGNvZGUgaW5zdGFuY2VJZH0uICovCisgIC8vIFRPRE8oYi8yMDQwOTQ1OTEpOiBkZXRlcm1pbmUgd2hldGhlciBpbnN0YW5jZUlkIGlzIGV2ZXIgYWN0dWFsbHkgbnVsbC4KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U2hhcmVkUHJlZmVyZW5jZXNOYW1lKFN0cmluZyBiYXNlTmFtZSwgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkKSB7CisgICAgcmV0dXJuIGluc3RhbmNlSWQgIT0gbnVsbCAmJiBpbnN0YW5jZUlkLmlzUHJlc2VudCgpID8gYmFzZU5hbWUgKyBpbnN0YW5jZUlkLmdldCgpIDogYmFzZU5hbWU7CisgIH0KKworICAvKiogUmV0dXJuIHRoZSBTaGFyZWRQcmVmZXJlbmNlcyBmb3IgSW5zdGFuY2VJZCAqLworICAvLyBUT0RPKGIvMjA0MDk0NTkxKTogZGV0ZXJtaW5lIHdoZXRoZXIgaW5zdGFuY2VJZCBpcyBldmVyIGFjdHVhbGx5IG51bGwuCisgIHB1YmxpYyBzdGF0aWMgU2hhcmVkUHJlZmVyZW5jZXMgZ2V0U2hhcmVkUHJlZmVyZW5jZXMoCisgICAgICBDb250ZXh0IGNvbnRleHQsIFN0cmluZyBiYXNlTmFtZSwgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkKSB7CisgICAgcmV0dXJuIGNvbnRleHQuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoCisgICAgICAgIGdldFNoYXJlZFByZWZlcmVuY2VzTmFtZShiYXNlTmFtZSwgaW5zdGFuY2VJZCksIENvbnRleHQuTU9ERV9QUklWQVRFKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL1N5bWxpbmtVdGlsLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvU3ltbGlua1V0aWwuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZWM5MWU4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL1N5bWxpbmtVdGlsLmphdmEKQEAgLTAsMCArMSw5MyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbDsKKworaW1wb3J0IHN0YXRpYyBhbmRyb2lkLnN5c3RlbS5Pcy5yZWFkbGluazsKK2ltcG9ydCBzdGF0aWMgYW5kcm9pZC5zeXN0ZW0uT3Muc3ltbGluazsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkLlZFUlNJT05fQ09ERVM7CitpbXBvcnQgYW5kcm9pZC5zeXN0ZW0uRXJybm9FeGNlcHRpb247CitpbXBvcnQgYW5kcm9pZHguYW5ub3RhdGlvbi5SZXF1aXJlc0FwaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5BbmRyb2lkVXJpQWRhcHRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5NYWxmb3JtZWRVcmlFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKKworLyoqIFV0aWxpdHkgY2xhc3MgdG8gY3JlYXRlIHN5bWxpbmtzIChpZiBzdXBwb3J0ZWQpLiAqLworcHVibGljIGZpbmFsIGNsYXNzIFN5bWxpbmtVdGlsIHsKKyAgcHJpdmF0ZSBTeW1saW5rVXRpbCgpIHt9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSBzeW1saW5rIGF0IHRoZSBnaXZlbiBsaW5rIFVyaSB0byB0aGUgZ2l2ZW4gdGFyZ2V0IFVyaS4KKyAgICoKKyAgICogPHA+VGhpcyBtZXRob2Qgd2lsbCBvbmx5IHdvcmsgZm9yIEFQSSBsZXZlbCAyMSsgc2luY2UgdGhpcyBpcyB3aGVuIEFuZHJvaWQgYWRkZWQgYSBwbGF0Zm9ybQorICAgKiBsZXZlbCBzeW1saW5rIGZ1bmN0aW9uLgorICAgKgorICAgKiBAcGFyYW0gY29udGV4dCB0aGUgY2FsbGVyJ3MgY29udGV4dAorICAgKiBAcGFyYW0gbGlua1VyaSBsb2NhdGlvbiB0byBjcmVhdGUgdGhlIHN5bWxpbmsKKyAgICogQHBhcmFtIHRhcmdldFVyaSBsb2NhdGlvbiB3aGVyZSB0aGUgc3ltbGluayBzaG91bGQgcG9pbnQKKyAgICogQHRocm93cyBJT0V4Y2VwdGlvbiB3aGVuIHN5bWxpbmsgY291bGQgbm90IGJlIGNyZWF0ZWQKKyAgICovCisgIEBSZXF1aXJlc0FwaShWRVJTSU9OX0NPREVTLkxPTExJUE9QKQorICBwdWJsaWMgc3RhdGljIHZvaWQgY3JlYXRlU3ltbGluayhDb250ZXh0IGNvbnRleHQsIFVyaSBsaW5rVXJpLCBVcmkgdGFyZ2V0VXJpKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSB7CisgICAgICBBbmRyb2lkVXJpQWRhcHRlciBhZGFwdGVyID0gQW5kcm9pZFVyaUFkYXB0ZXIuZm9yQ29udGV4dChjb250ZXh0KTsKKyAgICAgIHN5bWxpbmsoCisgICAgICAgICAgYWRhcHRlci50b0ZpbGUodGFyZ2V0VXJpKS5nZXRBYnNvbHV0ZVBhdGgoKSwgYWRhcHRlci50b0ZpbGUobGlua1VyaSkuZ2V0QWJzb2x1dGVQYXRoKCkpOworICAgIH0gY2F0Y2ggKE1hbGZvcm1lZFVyaUV4Y2VwdGlvbiB8IEVycm5vRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIHdyYXAgdGhlIGV4Y2VwdGlvbiBzbyBpdCBpc24ndCBleHBsaWNpdGx5IHJlZmVyZW5jZWQgYXQgaGlnaGVyIGxldmVscyB0aGF0IHJ1biBvbgorICAgICAgLy8gQVBJIGxldmVsIDIxIG9yIGJlbG93LgorICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbmFibGUgdG8gY3JlYXRlIHN5bWxpbmsiLCBlKTsKKyAgICB9CisgIH0KKworICAvKioKKyAgICogUmVhZHMgdGhlIGdpdmVuIHN5bWxpbmsgVXJpIGFuZCByZXR1cm5zIGl0cyB0YXJnZXQgVXJpLgorICAgKgorICAgKiA8cD5UaGlzIG1ldGhvZCB3aWxsIG9ubHkgd29yayBmb3IgQVBJIGxldmVsIDIxKyBzaW5jZSB0aGlzIGlzIHdoZW4gQW5kcm9pZCBhZGRlZCBhIHBsYXRmb3JtCisgICAqIGxldmVsIHJlYWRsaW5rIGZ1bmN0aW9uLiBJdCB3cmFwcyBhcm91bmQgQW5kcm9pZCdzIHJlYWRsaW5rIGZ1bmN0aW9uIGFuZCBleHBvc2VzIGl0IGluIGEKKyAgICogdmVyc2lvbiBzYWZlIHdheSBiZWhpbmQgdGhlIEBSZXF1aXJlc0FwaSBhbm5vdGF0aW9uLgorICAgKgorICAgKiA8cD5OT1RFOiBUaGlzIG1ldGhvZCBvbmx5IHZlcmlmaWVzIHRoZSBnaXZlbiBpbnB1dCBhcyBhIHZhbGlkIHN5bWxpbmsgYW5kIHBvaW50cyB0byBhIHRhcmdldAorICAgKiB1cmkuIEhvd2V2ZXIsIGl0IG1ha2VzIG5vIGd1YXJhbnRlZXMgYWJvdXQgdGhlIHRhcmdldCB1cmkgKGkuZS4gd2hldGhlciB0aGUgdGFyZ2V0IGV4aXN0cykuCisgICAqCisgICAqIEBwYXJhbSBjb250ZXh0IHRoZSBjYWxsZXIncyBjb250ZXh0CisgICAqIEBwYXJhbSBzeW1saW5rVXJpIHRoZSBzeW1saW5rIGxvY2F0aW9uIHRoYXQgc2hvdWxkIGJlIGNoZWNrZWQKKyAgICogQHJldHVybiBVcmkgdG8gdGhlIHRhcmdldCBsb2NhdGlvbiBvZiB0aGUgc3ltbGluaworICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIHdoZW4gc3ltbGluayBpcyB1bmFibGUgdG8gYmUgY2hlY2tlZAorICAgKi8KKyAgQFJlcXVpcmVzQXBpKFZFUlNJT05fQ09ERVMuTE9MTElQT1ApCisgIHB1YmxpYyBzdGF0aWMgVXJpIHJlYWRTeW1saW5rKENvbnRleHQgY29udGV4dCwgVXJpIHN5bWxpbmtVcmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IHsKKyAgICAgIEFuZHJvaWRVcmlBZGFwdGVyIGFkYXB0ZXIgPSBBbmRyb2lkVXJpQWRhcHRlci5mb3JDb250ZXh0KGNvbnRleHQpOworICAgICAgU3RyaW5nIHRhcmdldFBhdGggPSByZWFkbGluayhhZGFwdGVyLnRvRmlsZShzeW1saW5rVXJpKS5nZXRBYnNvbHV0ZVBhdGgoKSk7CisKKyAgICAgIGlmICh0YXJnZXRQYXRoID09IG51bGwpIHsKKyAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJVbmFibGUgdG8gcmVhZCBzeW1saW5rIik7CisgICAgICB9CisKKyAgICAgIHJldHVybiBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkKKyAgICAgICAgICAuZnJvbUFic29sdXRlUGF0aCh0YXJnZXRQYXRoLCAvKiBhY2NvdW50TWFuYWdlcj0gKi8gbnVsbCkKKyAgICAgICAgICAuYnVpbGQoKTsKKyAgICB9IGNhdGNoIChNYWxmb3JtZWRVcmlFeGNlcHRpb24gfCBFcnJub0V4Y2VwdGlvbiBlKSB7CisgICAgICAvLyB3cmFwIHRoZSBleGNlcHRpb24gc28gaXQgaXNuJ3QgZXhwbGljaXRseSByZWZlcmVuY2VkIGF0IGhpZ2hlciBsZXZlbHMgdGhhdCBydW4gb24KKyAgICAgIC8vIEFQSSBsZXZlbCAyMSBvciBiZWxvdy4KKyAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiVW5hYmxlIHRvIHJlYWQgc3ltbGluayIsIGUpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL0JVSUxEIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxZWI4ZmIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvQlVJTEQKQEAgLTAsMCArMSw3NCBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKKyMgTUREIExpdGUgdmlzaWJpbGl0eSBpcyByZXN0cmljdGVkIHRvIHRoZSBmb2xsb3dpbmcgc2V0IG9mIHBhY2thZ2VzLiBBbnkKKyMgbmV3IGNsaWVudHMgbXVzdCBiZSBhZGRlZCB0byB0aGlzIGxpc3QgaW4gb3JkZXIgdG8gZ3JhbnQgYnVpbGQgdmlzaWJpbGl0eS4KK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImxpdGUiLAorICAgIHNyY3MgPSBnbG9iKAorICAgICAgICBbIiouamF2YSJdLAorICAgICAgICBleGNsdWRlID0gWworICAgICAgICAgICAgIkRvd25sb2FkTGlzdGVuZXIuamF2YSIsCisgICAgICAgICAgICAiRG93bmxvYWRQcm9ncmVzc01vbml0b3IuamF2YSIsCisgICAgICAgICAgICAiU2luZ2xlRmlsZURvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmphdmEiLAorICAgICAgICBdLAorICAgICksCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpEb3dubG9hZExpc3RlbmVyIiwKKyAgICAgICAgIjpEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXI6RmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZvcmVncm91bmQ6Tm90aWZpY2F0aW9uVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIkBhbmRyb2lkeF9jb3JlX2NvcmUiLAorICAgICAgICAiQGNvbV9nb29nbGVfYXV0b192YWx1ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9kYWdnZXIiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQG9yZ19jaGVja2VyZnJhbWV3b3JrX3F1YWwiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkRvd25sb2FkTGlzdGVuZXIiLAorICAgIHNyY3MgPSBbIkRvd25sb2FkTGlzdGVuZXIuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL3Byb3RvOmNsaWVudF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmphdmEiLAorICAgICAgICAiU2luZ2xlRmlsZURvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpEb3dubG9hZExpc3RlbmVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpUaW1lU291cmNlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvRG93bmxvYWRMaXN0ZW5lci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL0Rvd25sb2FkTGlzdGVuZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzAwODM5Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL0Rvd25sb2FkTGlzdGVuZXIuamF2YQpAQCAtMCwwICsxLDQ3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlOworCitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CisKKy8qKgorICogU3VwcG9ydHMgcmVnaXN0ZXJpbmcgZm9yIGRvd25sb2FkIHByb2dyZXNzIHVwZGF0ZS4gQ2FsbGJhY2tzIHdpbGwgYmUgZXhlY3V0ZWQKKyAqIG9uIEBNZGRDb250cm9sRXhlY3V0b3IuIElmIHlvdSBuZWVkIHRvIGRvIGhlYXZ5IHdvcmssIHBsZWFzZSBvZmZsb2FkIHRvIGEgYmFja2dyb3VuZCB0YXNrLgorICovCitwdWJsaWMgaW50ZXJmYWNlIERvd25sb2FkTGlzdGVuZXIgeworICBTdHJpbmcgVEFHID0gIkRvd25sb2FkTGlzdGVuZXIiOworCisgIC8qKgorICAgKiBXaWxsIGJlIHRyaWdnZXJlZCBwZXJpb2RpY2FsbHkgd2l0aCB0aGUgY3VycmVudCBkb3dubG9hZGVkIHNpemUgb2YgdGhlIGJlaW5nIGRvd25sb2FkZWQgZmlsZS4KKyAgICogVGhpcyBjb3VsZCBiZSB1c2VkIHRvIHNob3cgcHJvZ3Jlc3NiYXIgdG8gdXNlcnMuCisgICAqLworICB2b2lkIG9uUHJvZ3Jlc3MobG9uZyBjdXJyZW50U2l6ZSk7CisKKyAgLyoqCisgICAqIFRoaXMgd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgZG93bmxvYWQgaXMgY29tcGxldGVkIHN1Y2Nlc3NmdWxseS4gTUREIHdpbGwga2VlcCB0aGUgRm9yZWdyb3VuZAorICAgKiBEb3dubG9hZCBTZXJ2aWNlIGFsaXZlIHNvIHRoYXQgdGhlIG9uQ29tcGxldGUgY2FuIGZpbmlzaCB3aXRob3V0IGJlaW5nIGtpbGxlZCBieSBBbmRyb2lkLgorICAgKi8KKyAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBvbkNvbXBsZXRlKCk7CisKKyAgLyoqIFRoaXMgd2lsbCBiZSBjYWxsZWQgd2hlbiB0aGUgZG93bmxvYWQgZmFpbGVkLiAqLworICB2b2lkIG9uRmFpbHVyZShUaHJvd2FibGUgdCk7CisKKyAgLyoqCisgICAqIENhbGxiYWNrIHRyaWdnZXJlZCB3aGVuIGFsbCBkb3dubG9hZHMgYXJlIGluIGEgc3RhdGUgd2FpdGluZyBmb3IgY29ubmVjdGl2aXR5LCBhbmQgbm8gZG93bmxvYWQKKyAgICogcHJvZ3Jlc3MgaXMgaGFwcGVuaW5nIHVudGlsIGNvbm5lY3Rpdml0eSByZXN1bWVzLgorICAgKi8KKyAgdm9pZCBvblBhdXNlZEZvckNvbm5lY3Rpdml0eSgpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvRG93bmxvYWRQcm9ncmVzc01vbml0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMGZkNmZhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmphdmEKQEAgLTAsMCArMSwxNjcgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmxpdGU7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZHguYW5ub3RhdGlvbi5WaXNpYmxlRm9yVGVzdGluZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UaW1lU291cmNlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLk1vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNMb25nOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5jb25jdXJyZW50Lkd1YXJkZWRCeTsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLmNvbmN1cnJlbnQuVGhyZWFkU2FmZTsKKworLyoqIEEgRG93bmxvYWQgUHJvZ3Jlc3MgTW9uaXRvciB0byBzdXBwb3J0IHtAbGluayBEb3dubG9hZExpc3RlbmVyfS4gKi8KK0BUaHJlYWRTYWZlCitwdWJsaWMgY2xhc3MgRG93bmxvYWRQcm9ncmVzc01vbml0b3IgaW1wbGVtZW50cyBNb25pdG9yLCBTaW5nbGVGaWxlRG93bmxvYWRQcm9ncmVzc01vbml0b3IgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiRG93bmxvYWRQcm9ncmVzc01vbml0b3IiOworCisgIHByaXZhdGUgZmluYWwgVGltZVNvdXJjZSB0aW1lU291cmNlOworICBwcml2YXRlIGZpbmFsIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CisKKyAgLy8gTk9URTogR3VhcmRSYWlscyBwcm9oaWJpdHMgbXVsdGlwbGUgcHVibGljIGNvbnN0cnVjdG9ycworICBwcml2YXRlIERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKFRpbWVTb3VyY2UgdGltZVNvdXJjZSwgRXhlY3V0b3IgY29udHJvbEV4ZWN1dG9yKSB7CisgICAgdGhpcy50aW1lU291cmNlID0gdGltZVNvdXJjZTsKKworICAgIC8vIFdlIHdhbnQgb25Qcm9ncmVzcyB0byBiZSBleGVjdXRlZCBpbiBvcmRlciBvdGhlcndpc2UgY2xpZW50cyB3aWxsIG9ic2VydmUgb3V0IG9mIG9yZGVyCisgICAgLy8gdXBkYXRlcyAoYmlnZ2VyIGN1cnJlbnQgc2l6ZSB1cGRhdGUgYXBwZWFycyBiZWZvcmUgc21hbGxlciBjdXJyZW50IHNpemUgdXBkYXRlKS4KKyAgICAvLyBXZSB1c2UgU2VxdWVudGlhbCBFeGVjdXRvciB0byBlbnN1cmUgdGhlIG9uUHJvZ3Jlc3Mgd2lsbCBiZSBwcm9jZXNzZWQgc2VxdWVudGlhbGx5LgorICAgIHRoaXMuc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciA9IE1vcmVFeGVjdXRvcnMubmV3U2VxdWVudGlhbEV4ZWN1dG9yKGNvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvKiogQ29uc3RydWN0b3Igb3ZlcmxvYWQgd2l0aCB7QGxpbmsgVGltZVNvdXJjZX0uICovCisgIC8vIE5PVEU6IHRoaXMgaXMgbmVjZXNzYXJ5IGZvciB1c2UgYnkgb3RoZXIgTUREIGNvbXBvbmVudHMuCisgIHB1YmxpYyBzdGF0aWMgRG93bmxvYWRQcm9ncmVzc01vbml0b3IgY3JlYXRlKFRpbWVTb3VyY2UgdGltZVNvdXJjZSwgRXhlY3V0b3IgY29udHJvbEV4ZWN1dG9yKSB7CisgICAgcmV0dXJuIG5ldyBEb3dubG9hZFByb2dyZXNzTW9uaXRvcih0aW1lU291cmNlLCBjb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLy8gV2Ugd2lsbCBvbmx5IGJyb2FkY2FzdCBvbiBwcm9ncmVzcyBub3RpZmljYXRpb24gYXQgbW9zdCBvbmNlIGluIHRoaXMgdGltZSBmcmFtZS4KKyAgLy8gQ3VycmVudGx5IE1vYlN0b3JlIE1vbml0b3Igbm90aWZ5IGV2ZXJ5IDhLQiBvZiBkb3dubG9hZGVkIGJ5dGVzLiBUaGlzIG1heSBiZSB0b28gY2hhdHR5IG9uCisgIC8vIGZhc3QgbmV0d29yay4KKyAgLy8gMTAwMCB3YXMgY2hvc2VuIGFyYml0cmFyaWx5LgorICBAVmlzaWJsZUZvclRlc3Rpbmcgc3RhdGljIGZpbmFsIGxvbmcgQlVGRkVSRURfVElNRV9NUyA9IDEwMDA7CisKKyAgQEd1YXJkZWRCeSgiRG93bmxvYWRQcm9ncmVzc01vbml0b3IuY2xhc3MiKQorICBwcml2YXRlIGZpbmFsIEhhc2hNYXA8VXJpLCBEb3dubG9hZGVkQnl0ZXNDb3VudGVyPiB1cmlUb0Rvd25sb2FkZWRCeXRlc0NvdW50ZXIgPSBuZXcgSGFzaE1hcDw+KCk7CisKKyAgQE92ZXJyaWRlCisgIEBOdWxsYWJsZQorICBwdWJsaWMgTW9uaXRvci5JbnB1dE1vbml0b3IgbW9uaXRvclJlYWQoVXJpIHVyaSkgeworICAgIHJldHVybiBudWxsOworICB9CisKKyAgQE92ZXJyaWRlCisgIEBOdWxsYWJsZQorICBwdWJsaWMgTW9uaXRvci5PdXRwdXRNb25pdG9yIG1vbml0b3JXcml0ZShVcmkgdXJpKSB7CisgICAgc3luY2hyb25pemVkIChEb3dubG9hZFByb2dyZXNzTW9uaXRvci5jbGFzcykgeworICAgICAgaWYgKHVyaVRvRG93bmxvYWRlZEJ5dGVzQ291bnRlci5nZXQodXJpKSA9PSBudWxsKSB7CisgICAgICAgIC8vIEFsbCBtb25pdG9ycyBmb3IgYSBzaGFyZWQgRmlsZVN0b3JhZ2Ugd2lsbCBiZSBpbnZva2VkIGZvciBhbGwgZmlsZSBhY2Nlc3NlcyB0aHJvdWdoIHRoaXMKKyAgICAgICAgLy8gc2hhcmVkIEZpbGVTdG9yYWdlLiBTbyB0aGlzIG1vbml0b3IgY2FuIHJlY2VpdmUgbm9uLU1ERC1MaXRlIFVyaS4KKyAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICB9CisgICAgICByZXR1cm4gdXJpVG9Eb3dubG9hZGVkQnl0ZXNDb3VudGVyLmdldCh1cmkpOworICAgIH0KKyAgfQorCisgIEBPdmVycmlkZQorICBATnVsbGFibGUKKyAgcHVibGljIE1vbml0b3IuT3V0cHV0TW9uaXRvciBtb25pdG9yQXBwZW5kKFVyaSB1cmkpIHsKKyAgICByZXR1cm4gbW9uaXRvcldyaXRlKHVyaSk7CisgIH0KKworICBwdWJsaWMgdm9pZCBwYXVzZWRGb3JDb25uZWN0aXZpdHkoKSB7CisgICAgc3luY2hyb25pemVkIChEb3dubG9hZFByb2dyZXNzTW9uaXRvci5jbGFzcykgeworICAgICAgZm9yIChEb3dubG9hZGVkQnl0ZXNDb3VudGVyIGRvd25sb2FkZWRCeXRlc0NvdW50ZXIgOiB1cmlUb0Rvd25sb2FkZWRCeXRlc0NvdW50ZXIudmFsdWVzKCkpIHsKKyAgICAgICAgZG93bmxvYWRlZEJ5dGVzQ291bnRlci5wYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgYWRkRG93bmxvYWRMaXN0ZW5lcihVcmkgdXJpLCBEb3dubG9hZExpc3RlbmVyIGRvd25sb2FkTGlzdGVuZXIpIHsKKyAgICBzeW5jaHJvbml6ZWQgKERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmNsYXNzKSB7CisgICAgICBpZiAoIXVyaVRvRG93bmxvYWRlZEJ5dGVzQ291bnRlci5jb250YWluc0tleSh1cmkpKSB7CisgICAgICAgIHVyaVRvRG93bmxvYWRlZEJ5dGVzQ291bnRlci5wdXQodXJpLCBuZXcgRG93bmxvYWRlZEJ5dGVzQ291bnRlcih1cmksIGRvd25sb2FkTGlzdGVuZXIpKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIHZvaWQgcmVtb3ZlRG93bmxvYWRMaXN0ZW5lcihVcmkgdXJpKSB7CisgICAgc3luY2hyb25pemVkIChEb3dubG9hZFByb2dyZXNzTW9uaXRvci5jbGFzcykgeworICAgICAgdXJpVG9Eb3dubG9hZGVkQnl0ZXNDb3VudGVyLnJlbW92ZSh1cmkpOworICAgIH0KKyAgfQorCisgIC8vIEEgY291bnRlciBmb3IgYnl0ZXMgZG93bmxvYWRlZC4KKyAgcHJpdmF0ZSBmaW5hbCBjbGFzcyBEb3dubG9hZGVkQnl0ZXNDb3VudGVyIGltcGxlbWVudHMgTW9uaXRvci5PdXRwdXRNb25pdG9yIHsKKyAgICBwcml2YXRlIGZpbmFsIFVyaSB1cmk7CisgICAgcHJpdmF0ZSBmaW5hbCBEb3dubG9hZExpc3RlbmVyIGRvd25sb2FkTGlzdGVuZXI7CisKKyAgICBwcml2YXRlIGZpbmFsIEF0b21pY0xvbmcgYnl0ZUNvdW50ZXIgPSBuZXcgQXRvbWljTG9uZygpOworCisgICAgLy8gTGFzdCB0aW1lc3RhbXAgdGhhdCB3ZSBicm9hZGNhc3Qgb24gcHJvZ3Jlc3MuCisgICAgcHJpdmF0ZSBsb25nIGxhc3RCcm9hZGNhc3RPblByb2dyZXNzVGltZXN0YW1wTXM7CisKKyAgICBEb3dubG9hZGVkQnl0ZXNDb3VudGVyKFVyaSB1cmksIERvd25sb2FkTGlzdGVuZXIgZG93bmxvYWRMaXN0ZW5lcikgeworICAgICAgdGhpcy51cmkgPSB1cmk7CisgICAgICB0aGlzLmRvd25sb2FkTGlzdGVuZXIgPSBkb3dubG9hZExpc3RlbmVyOworICAgICAgbGFzdEJyb2FkY2FzdE9uUHJvZ3Jlc3NUaW1lc3RhbXBNcyA9IHRpbWVTb3VyY2UuY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBieXRlc1dyaXR0ZW4oYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHsKKyAgICAgIG5vdGlmeVByb2dyZXNzKGxlbik7CisgICAgfQorCisgICAgcHJpdmF0ZSB2b2lkIG5vdGlmeVByb2dyZXNzKGxvbmcgbGVuKSB7CisgICAgICAvLyBPbmx5IGJyb2FkY2FzdCBwcm9ncmVzcyB1cGRhdGUgZXZlcnkgQlVGRkVSRURfVElNRV9NUy4KKyAgICAgIC8vIEl0IHdpbGwgYmUgZmFzdCAobm8gbG9ja2luZykgd2hlbiB0aGVyZSBpcyBubyBuZWVkIHRvIGJyb2FkY2FzdCBwcm9ncmVzcy4KKyAgICAgIC8vIFdoZW4gdGhlcmUgaXMgYSBuZWVkIHRvIGJyb2FkY2FzdCBwcm9ncmVzcywgd2UgbmVlZCB0byBvYnRhaW4gdGhlIGxvY2sgZHVlIHRvIDIgcmVhc29uczoKKyAgICAgIC8vIDEtIENvbmN1cnJlbnQgYWNjZXNzIHRvIHVyaVRvRG93bmxvYWRlZEJ5dGVzQ291bnRlci4KKyAgICAgIC8vIDItIFByZXZlbnQgb3V0IG9mIG9yZGVyIHByb2dyZXNzIHVwZGF0ZS4KKyAgICAgIGlmICh0aW1lU291cmNlLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBsYXN0QnJvYWRjYXN0T25Qcm9ncmVzc1RpbWVzdGFtcE1zIDwgQlVGRkVSRURfVElNRV9NUykgeworICAgICAgICBieXRlQ291bnRlci5nZXRBbmRBZGQobGVuKTsKKyAgICAgICAgTG9nVXRpbC52KAorICAgICAgICAgICAgIiVzOiBSZWNlaXZlZCBkYXRhIGZvciB1cmkgPSAlcywgbGVuID0gJWQsIENvdW50ZXIgPSAlZCIsCisgICAgICAgICAgICBUQUcsIHVyaSwgbGVuLCBieXRlQ291bnRlci5nZXQoKSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzeW5jaHJvbml6ZWQgKERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmNsYXNzKSB7CisgICAgICAgICAgLy8gUmVzZXQgdGltZXN0YW1wLgorICAgICAgICAgIGxhc3RCcm9hZGNhc3RPblByb2dyZXNzVGltZXN0YW1wTXMgPSB0aW1lU291cmNlLmN1cnJlbnRUaW1lTWlsbGlzKCk7CisKKyAgICAgICAgICBieXRlQ291bnRlci5nZXRBbmRBZGQobGVuKTsKKyAgICAgICAgICBMb2dVdGlsLnYoCisgICAgICAgICAgICAgICIlczogUmVjZWl2ZWQgZGF0YSBmb3IgdXJpID0gJXMsIGxlbiA9ICVkLCBDb3VudGVyID0gJWQiLAorICAgICAgICAgICAgICBUQUcsIHVyaSwgbGVuLCBieXRlQ291bnRlci5nZXQoKSk7CisKKyAgICAgICAgICBpZiAodXJpVG9Eb3dubG9hZGVkQnl0ZXNDb3VudGVyLmNvbnRhaW5zS2V5KHVyaSkpIHsKKyAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IuZXhlY3V0ZSgoKSAtPiBkb3dubG9hZExpc3RlbmVyLm9uUHJvZ3Jlc3MoYnl0ZUNvdW50ZXIuZ2V0KCkpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCBwYXVzZWRGb3JDb25uZWN0aXZpdHkoKSB7CisgICAgICBkb3dubG9hZExpc3RlbmVyLm9uUGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvRG93bmxvYWRSZXF1ZXN0LmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvRG93bmxvYWRSZXF1ZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODQyYWM1NQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9Eb3dubG9hZFJlcXVlc3QuamF2YQpAQCAtMCwwICsxLDE0OSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubGl0ZTsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHM7CitpbXBvcnQgY29tLmdvb2dsZS5hdXRvLnZhbHVlLkF1dG9WYWx1ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKKworLyoqIFJlcXVlc3QgdG8gZG93bmxvYWQgYSBmaWxlLiAqLworQEF1dG9WYWx1ZQorcHVibGljIGFic3RyYWN0IGNsYXNzIERvd25sb2FkUmVxdWVzdCB7CisKKyAgLy8gRGVmYXVsdCB2YWx1ZSBmb3IgVHJhZmZpYyBUYWcgaWYgbm90IHNldCBieSBjbGllbnRzLgorICAvLyBNRERMaXRlIHdpbGwgbm90IHRhZyB0aGUgdHJhZmZpYyBpZiB0aGUgVHJhZmZpY1RhZyBpcyBub3Qgc2V0IHRvIGEgdmFsaWQgdmFsdWUgKD4wKS4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFVOU1BFQ0lGSUVEX1RSQUZGSUNfVEFHID0gLTE7CisKKyAgRG93bmxvYWRSZXF1ZXN0KCkge30KKworICAvLyBUaGUgRGVzdGluYXRpb24gRmlsZSBVcmkgdG8gZG93bmxvYWQgdGhlIGZpbGUgYXQuCisgIHB1YmxpYyBhYnN0cmFjdCBVcmkgZGVzdGluYXRpb25GaWxlVXJpKCk7CisKKyAgLy8gVGhlIHVybCB0byBkb3dubG9hZCB0aGUgZmlsZSBmcm9tLgorICBwdWJsaWMgYWJzdHJhY3QgU3RyaW5nIHVybFRvRG93bmxvYWQoKTsKKworICAvLyBDb25kaXRpb25zIHVuZGVyIHdoaWNoIHRoaXMgZmlsZSBzaG91bGQgYmUgZG93bmxvYWRlZC4KKyAgcHVibGljIGFic3RyYWN0IERvd25sb2FkQ29uc3RyYWludHMgZG93bmxvYWRDb25zdHJhaW50cygpOworCisgIC8qKiBJZiBwcmVzZW50LCB3aWxsIHJlY2VpdmUgZG93bmxvYWQgcHJvZ3Jlc3MgdXBkYXRlLiAqLworICBwdWJsaWMgYWJzdHJhY3QgT3B0aW9uYWw8RG93bmxvYWRMaXN0ZW5lcj4gbGlzdGVuZXJPcHRpb25hbCgpOworCisgIC8vIFRyYWZmaWMgdGFnIHVzZWQgZm9yIHRoaXMgcmVxdWVzdC4KKyAgLy8gSWYgbm90IHNldCwgaXQgd2lsbCB0YWtlIHRoZSBkZWZhdWx0IHZhbHVlIG9mIFVOU1BFQ0lGSUVEX1RSQUZGSUNfVEFHIGFuZCBNREQgd2lsbCBub3QgdGFnIHRoZQorICAvLyB0cmFmZmljLgorICBwdWJsaWMgYWJzdHJhY3QgaW50IHRyYWZmaWNUYWcoKTsKKworICAvLyBUaGUgZXh0cmEgSFRUUCBoZWFkZXJzIGZvciB0aGlzIHJlcXVlc3QuCisgIHB1YmxpYyBhYnN0cmFjdCBJbW11dGFibGVMaXN0PFBhaXI8U3RyaW5nLCBTdHJpbmc+PiBleHRyYUh0dHBIZWFkZXJzKCk7CisKKyAgLy8gVGhlIHNpemUgb2YgdGhlIGJlaW5nIGRvd25sb2FkZWQgZmlsZSBpbiBieXRlcy4KKyAgLy8gVGhpcyBpcyB1c2VkIHRvIGRpc3BsYXkgdGhlIHByb2dyZXNzYmFyLgorICAvLyBJZiBub3Qgc3BlY2lmaWVkLCBhbiBpbmRldGVybWluYXRlIHByb2dyZXNzYmFyIHdpbGwgYmUgZGlzcGxheWVkLgorICAvLyBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC9hcHAvTm90aWZpY2F0aW9uLkJ1aWxkZXIuaHRtbCNzZXRQcm9ncmVzcyhpbnQsJTIwaW50LCUyMGJvb2xlYW4pCisgIHB1YmxpYyBhYnN0cmFjdCBpbnQgZmlsZVNpemVCeXRlcygpOworCisgIC8vIFVzZWQgb25seSBieSBGb3JlZ3JvdW5kIGRvd25sb2FkLgorICAvLyBUaGUgQ29udGVudCBUaXRsZSBvZiB0aGUgYXNzb2NpYXRlZCBOb3RpZmljYXRpb24gZm9yIHRoaXMgZG93bmxvYWQuCisgIHB1YmxpYyBhYnN0cmFjdCBTdHJpbmcgbm90aWZpY2F0aW9uQ29udGVudFRpdGxlKCk7CisKKyAgLy8gVXNlZCBvbmx5IGJ5IEZvcmVncm91bmQgZG93bmxvYWQuCisgIC8vIElmIFByZXNlbnQsIHRoZSBDb250ZW50IFRleHQgKGRlc2NyaXB0aW9uKSBvZiB0aGUgYXNzb2NpYXRlZCBOb3RpZmljYXRpb24gZm9yIHRoaXMgZG93bmxvYWQuCisgIC8vIE90aGVyd2lzZSwgdGhlIENvbnRlbnQgVGV4dCB3aWxsIGJlIHRoZSB1cmwgdG8gZG93bmxvYWQuCisgIHB1YmxpYyBhYnN0cmFjdCBPcHRpb25hbDxTdHJpbmc+IG5vdGlmaWNhdGlvbkNvbnRlbnRUZXh0T3B0aW9uYWwoKTsKKworICAvLyBXaGV0aGVyIHRvIHNob3cgdGhlIGRvd25sb2FkZWQgbm90aWZpY2F0aW9uLiBJZiBmYWxzZSwgTUREIHdpbGwgYXV0b21hdGljYWxseSByZW1vdmUgdGhpcworICAvLyBub3RpZmljYXRpb24gd2hlbiB0aGUgZG93bmxvYWQgZmluaXNoZWQuCisgIHB1YmxpYyBhYnN0cmFjdCBib29sZWFuIHNob3dEb3dubG9hZGVkTm90aWZpY2F0aW9uKCk7CisKKyAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ldyBBdXRvVmFsdWVfRG93bmxvYWRSZXF1ZXN0LkJ1aWxkZXIoKQorICAgICAgICAuc2V0VHJhZmZpY1RhZyhVTlNQRUNJRklFRF9UUkFGRklDX1RBRykKKyAgICAgICAgLnNldEV4dHJhSHR0cEhlYWRlcnMoSW1tdXRhYmxlTGlzdC5vZigpKQorICAgICAgICAuc2V0RmlsZVNpemVCeXRlcygwKQorICAgICAgICAuc2V0U2hvd0Rvd25sb2FkZWROb3RpZmljYXRpb24odHJ1ZSk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIERvd25sb2FkUmVxdWVzdH0uICovCisgIEBBdXRvVmFsdWUuQnVpbGRlcgorICBwdWJsaWMgYWJzdHJhY3Qgc3RhdGljIGNsYXNzIEJ1aWxkZXIgeworICAgIEJ1aWxkZXIoKSB7fQorCisgICAgLyoqIFNldHMgdGhlIGRlc3RpbmF0aW9uIGZpbGUgdXJpLiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldERlc3RpbmF0aW9uRmlsZVVyaShVcmkgZmlsZVVyaSk7CisKKyAgICAvKiogU2V0cyB0aGUgdXJsIHRvIGRvd25sb2FkLiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldFVybFRvRG93bmxvYWQoU3RyaW5nIHVybFRvRG93bmxvYWQpOworCisgICAgLyoqIFNldHMgdGhlIERvd2xvYWRDb25zdHJhaW50cy4gKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMgZG93bmxvYWRDb25zdHJhaW50cyk7CisKKyAgICAvKiogU2V0cyB0aGUgb3B0aW9uYWwgZG93bmxvYWQgbGlzdGVuZXIuIElmIHByZXNlbnQsIHdpbGwgcmVjZWl2ZSBkb3dubG9hZCBwcm9ncmVzcyB1cGRhdGUuICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0TGlzdGVuZXJPcHRpb25hbChPcHRpb25hbDxEb3dubG9hZExpc3RlbmVyPiBsaXN0ZW5lck9wdGlvbmFsKTsKKworICAgIC8qKiBTZXRzIHRoZSB0cmFmZmljIHRhZyBmb3IgdGhpcyByZXF1ZXN0LiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldFRyYWZmaWNUYWcoaW50IHRyYWZmaWNUYWcpOworCisgICAgLyoqIFNldHMgdGhlIGV4dHJhIEhUVFAgaGVhZGVycyBmb3IgdGhpcyByZXF1ZXN0LiAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldEV4dHJhSHR0cEhlYWRlcnMoCisgICAgICAgIEltbXV0YWJsZUxpc3Q8UGFpcjxTdHJpbmcsIFN0cmluZz4+IGV4dHJhSHR0cEhlYWRlcnMpOworCisgICAgLyoqCisgICAgICogVGhlIHNpemUgb2YgdGhlIGJlaW5nIGRvd25sb2FkZWQgZmlsZSBpbiBieXRlcy4gVGhpcyBpcyB1c2VkIHRvIGRpc3BsYXkgdGhlIHByb2dyZXNzYmFyLiBJZgorICAgICAqIG5vdCBzcGVjaWZpZWQsIGEgaW5kZXRlcm1pbmF0ZSBwcm9ncmVzc2JhciB3aWxsIGJlIGRpc3BsYXllZC4KKyAgICAgKiBodHRwczovL2RldmVsb3Blci5hbmRyb2lkLmNvbS9yZWZlcmVuY2UvYW5kcm9pZC9hcHAvTm90aWZpY2F0aW9uLkJ1aWxkZXIuaHRtbCNzZXRQcm9ncmVzcyhpbnQsJTIwaW50LCUyMGJvb2xlYW4pCisgICAgICovCisgICAgcHVibGljIGFic3RyYWN0IEJ1aWxkZXIgc2V0RmlsZVNpemVCeXRlcyhpbnQgZmlsZVNpemVCeXRlcyk7CisKKyAgICAvKiogU2V0cyB0aGUgTm90aWZpY2F0aW9uIENvbnRlbnQgVGlsZSB3aGljaCB3aWxsIGJlIHVzZWQgZm9yIGZvcmVncm91bmQgZG93bmxvYWQgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXROb3RpZmljYXRpb25Db250ZW50VGl0bGUoU3RyaW5nIG5vdGlmaWNhdGlvbkNvbnRlbnRUaXRsZSk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBOb3RpZmljYXRpb24gQ29udGV4dCBUZXh0IHdoaWNoIHdpbGwgYmUgdXNlZCBmb3IgZm9yZWdyb3VuZCBkb3dubG9hZHMuCisgICAgICoKKyAgICAgKiA8cD5JZiBub3Qgc2V0LCB0aGUgdXJsIHRvIGRvd25sb2FkIHdpbGwgYmUgdXNlZCBpbnN0ZWFkLgorICAgICAqLworICAgIHB1YmxpYyBhYnN0cmFjdCBCdWlsZGVyIHNldE5vdGlmaWNhdGlvbkNvbnRlbnRUZXh0T3B0aW9uYWwoCisgICAgICAgIE9wdGlvbmFsPFN0cmluZz4gbm90aWZpY2F0aW9uQ29udGVudFRleHRPcHRpb25hbCk7CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRvIHNob3cgRG93bmxvYWRlZCBOb3RpZmljYXRpb24gYWZ0ZXIgdGhlIGRvd25sb2FkIGZpbmlzaGVkIHN1Y2Nlc3NmdWxseS4gVGhpcyBpcyBvbmx5CisgICAgICogYmUgdXNlZCBmb3IgZm9yZWdyb3VuZCBkb3dubG9hZC4gRGVmYXVsdCB2YWx1ZSBpcyB0byBzaG93IHRoZSBkb3dubG9hZGVkIG5vdGlmaWNhdGlvbi4KKyAgICAgKi8KKyAgICBwdWJsaWMgYWJzdHJhY3QgQnVpbGRlciBzZXRTaG93RG93bmxvYWRlZE5vdGlmaWNhdGlvbihib29sZWFuIHNob3dEb3dubG9hZGVkTm90aWZpY2F0aW9uKTsKKworICAgIC8qKiBCdWlsZHMge0BsaW5rIERvd25sb2FkUmVxdWVzdH0uICovCisgICAgcHVibGljIGZpbmFsIERvd25sb2FkUmVxdWVzdCBidWlsZCgpIHsKKyAgICAgIC8vIElmIG5vdGlmaWNhdGlvbiBjb250ZW50IHRpdGxlIGlzIG5vdCBwcm92aWRlZCwgdXNlIHVybFRvRG93bmxvYWQgYXMgYSBmYWxsYmFjaworICAgICAgaWYgKCFub3RpZmljYXRpb25Db250ZW50VGl0bGUoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICBzZXROb3RpZmljYXRpb25Db250ZW50VGl0bGUodXJsVG9Eb3dubG9hZCgpKTsKKyAgICAgIH0KKyAgICAgIC8vIFVzZSBBdXRvVmFsdWUncyBnZW5lcmF0ZWQgYnVpbGQgdG8gZmluaXNoIGJ1aWxkaW5nLgorICAgICAgcmV0dXJuIGF1dG9CdWlsZCgpOworICAgIH0KKworICAgIC8vIHByaXZhdGUgZ2V0dGVyIGdlbmVyYXRlZCBieSBBdXRvVmFsdWUgZm9yIGFjY2VzcyBpbiBidWlsZCgpLgorICAgIGFic3RyYWN0IFN0cmluZyB1cmxUb0Rvd25sb2FkKCk7CisKKyAgICAvLyBwcml2YXRlIGdldHRlciBnZW5lcmF0ZWQgYnkgQXV0b1ZhbHVlIGZvciBhY2Nlc3MgaW4gYnVpbGQoKS4KKyAgICBhYnN0cmFjdCBPcHRpb25hbDxTdHJpbmc+IG5vdGlmaWNhdGlvbkNvbnRlbnRUaXRsZSgpOworCisgICAgLy8gcHJpdmF0ZSBidWlsZCBtZXRob2QgdG8gYmUgZ2VuZXJhdGVkIGJ5IEF1dG9WYWx1ZS4KKyAgICBhYnN0cmFjdCBEb3dubG9hZFJlcXVlc3QgYXV0b0J1aWxkKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9Eb3dubG9hZGVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvRG93bmxvYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIwODEzMmMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvRG93bmxvYWRlci5qYXZhCkBAIC0wLDAgKzEsMTU1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuUHJlY29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DaGVja1JldHVyblZhbHVlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworCisvKiogVGhlIHJvb3Qgb2JqZWN0IGFuZCBlbnRyeSBwb2ludCBmb3IgdGhlIE1ERExpdGUgKDxpbnRlcm5hbD4pLiAqLworcHVibGljIGludGVyZmFjZSBEb3dubG9hZGVyIHsKKworICAvKioKKyAgICogRG93bmxvYWRzIGEgZmlsZSB3aXRoIHRoZSBnaXZlbiB7QGxpbmsgRG93bmxvYWRSZXF1ZXN0fS4KKyAgICoKKyAgICogPHA+VGhpcyBtZXRob2Qgd2lsbCBub3QgY3JlYXRlIGEgbm90aWZpY2F0aW9uIGFuZCB3aWxsIG5vdCBydW4gaW4gYSBGb3JlZ3JvdW5kU2VydmljZS4KKyAgICoKKyAgICogPHA+Tk9URTogVGhlIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3Iga2VlcGluZyB0aGUgZG93bmxvYWQgYWxpdmUuIFRoaXMgaXMgdHlwaWNhbGx5IHVzZWQgYnkKKyAgICogY2xpZW50cyB3aG8gdXNlIGEgc2VydmljZSB0aGUgcGxhdGZvcm0gYmluZHMgd2l0aCwgc28gYSBub3RpZmljYXRpb24gaXMgbm90IG5lZWRlZC4gSWYgeW91IGFyZQorICAgKiB1bnN1cmUgd2hldGhlciB0byB1c2UgdGhpcyBtZXRob2Qgb3Ige0BsaW5rICNkb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZX0sIGNvbnRhY3QgdGhlIE1ERAorICAgKiB0ZWFtICg8aW50ZXJuYWw+QCBvciB2aWEgPGEgaHJlZj0iPGludGVybmFsPiI+eWFxczwvYT4uCisgICAqLworICBAQ2hlY2tSZXR1cm5WYWx1ZQorICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkKERvd25sb2FkUmVxdWVzdCBkb3dubG9hZFJlcXVlc3QpOworCisgIC8qKgorICAgKiBEb3dubG9hZCBhIGZpbGUgYW5kIHNob3cgZm9yZWdyb3VuZCBkb3dubG9hZCBwcm9ncmVzcyBpbiBhIG5vdGlmaWNhdGlvbi4gVXNlciBjYW4gY2FuY2VsIHRoZQorICAgKiBkb3dubG9hZCBmcm9tIHRoZSBub3RpZmljYXRpb24gbWVudS4KKyAgICoKKyAgICogPHA+Tk9URTogQ2FsbGluZyBkb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZSB3aXRob3V0IGEgcHJvdmlkZWQgRm9yZWdyb3VuZFNlcnZpY2Ugd2lsbCByZXR1cm4KKyAgICogYSBmYWlsZWQgZnV0dXJlLgorICAgKgorICAgKiA8cD5UaGUgY2FuY2VsIGFjdGlvbiBpbiB0aGUgbm90aWZpY2F0aW9uIG1lbnUgcmVxdWlyZXMgdGhlIEZvcmVncm91bmRTZXJ2aWNlIHRvIGJlIHJlZ2lzdGVyZWQKKyAgICogd2l0aCB0aGUgYXBwbGljYXRpb24gKHZpYSB0aGUgQW5kcm9pZE1hbmlmZXN0LnhtbCkuIFRoaXMgYWxsb3dzIHRoZSBjYW5jZWxsYXRpb24gaW50ZW50cyB0byBiZQorICAgKiBwcm9wZXJseSBwaWNrZWQgdXAuIFRvIHJlZ2lzdGVyIHRoZSBzZXJ2aWNlLCB0aGUgZm9sbG93aW5nIGxpbmVzIG11c3QgYmUgaW5jbHVkZWQgaW4gdGhlIGFwcCdzCisgICAqIHtAY29kZSBBbmRyb2lkTWFuaWZlc3QueG1sfToKKyAgICoKKyAgICogPHByZT57QGNvZGUKKyAgICogPCEtLSBOZWVkZWQgYnkgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlIC0tPgorICAgKiA8dXNlcy1wZXJtaXNzaW9uIGFuZHJvaWQ6bmFtZT0iYW5kcm9pZC5wZXJtaXNzaW9uLkZPUkVHUk9VTkRfU0VSVklDRSIgLz4KKyAgICoKKyAgICogPCEtLSBTZXJ2aWNlIGZvciBNREQgTGl0ZSBmb3JlZ3JvdW5kIGRvd25sb2FkcyAtLT4KKyAgICogPHNlcnZpY2UKKyAgICogICBhbmRyb2lkOm5hbWU9ImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmxpdGUuc3RpbmcuRm9yZWdyb3VuZERvd25sb2FkU2VydmljZSIKKyAgICogICBhbmRyb2lkOmV4cG9ydGVkPSJmYWxzZSIgLz4KKyAgICogfTwvcHJlPgorICAgKgorICAgKiA8cD5OT1RFOiBUaGUgYWJvdmUgZXhjZXJwdCBpcyBmb3IgRnJhbWV3b3JrIGFuZCBTdGluZyBhcHBzLiBEYWdnZXIgYXBwcyBzaG91bGQgdXNlIHRoZSBzYW1lCisgICAqIGV4Y2VycHQsIGJ1dCBjaGFuZ2UgdGhlIHtAY29kZSBhbmRyb2lkOm5hbWV9IHByb3BlcnR5IHRvOgorICAgKgorICAgKiA8cHJlPntAY29kZQorICAgKiBhbmRyb2lkOm5hbWU9ImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmxpdGUuZGFnZ2VyLkZvcmVncm91bmREb3dubG9hZFNlcnZpY2UiCisgICAqIH08L3ByZT4KKyAgICovCisgIEBDaGVja1JldHVyblZhbHVlCisgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRXaXRoRm9yZWdyb3VuZFNlcnZpY2UoRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCk7CisKKyAgLyoqIENhbmNlbCBhbiBvbi1nb2luZyBmb3JlZ3JvdW5kIGRvd25sb2FkLiAqLworICB2b2lkIGNhbmNlbEZvcmVncm91bmREb3dubG9hZChTdHJpbmcgZGVzdGluYXRpb25GaWxlVXJpKTsKKworICBzdGF0aWMgRG93bmxvYWRlci5CdWlsZGVyIG5ld0J1aWxkZXIoKSB7CisgICAgcmV0dXJuIG5ldyBEb3dubG9hZGVyLkJ1aWxkZXIoKTsKKyAgfQorCisgIC8qKiBBIEJ1aWxkZXIgZm9yIHRoZSB7QGxpbmsgRG93bmxvYWRlcn0uICovCisgIGZpbmFsIGNsYXNzIEJ1aWxkZXIgeworCisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJCdWlsZGVyIjsKKyAgICBwcml2YXRlIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CisKKyAgICBwcml2YXRlIENvbnRleHQgY29udGV4dDsKKyAgICBwcml2YXRlIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyOworICAgIHByaXZhdGUgT3B0aW9uYWw8U2luZ2xlRmlsZURvd25sb2FkUHJvZ3Jlc3NNb25pdG9yPiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCA9IE9wdGlvbmFsLmFic2VudCgpOworICAgIHByaXZhdGUgT3B0aW9uYWw8Q2xhc3M8Pz4+IGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsID0gT3B0aW9uYWwuYWJzZW50KCk7CisKKyAgICBwdWJsaWMgQnVpbGRlciBzZXRDb250ZXh0KENvbnRleHQgY29udGV4dCkgeworICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dC5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKiBTZXQgdGhlIENvbnRyb2wgRXhlY3V0b3Igd2hpY2ggd2lsbCBydW4gTURETGl0ZSBjb250cm9sIGZsb3cuICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0Q29udHJvbEV4ZWN1dG9yKEV4ZWN1dG9yIGNvbnRyb2xFeGVjdXRvcikgeworICAgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwoY29udHJvbEV4ZWN1dG9yKTsKKyAgICAgIC8vIEV4ZWN1dG9yIHRoYXQgd2lsbCBleGVjdXRlIHRhc2tzIHNlcXVlbnRpYWxseS4KKyAgICAgIHRoaXMuc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciA9IE1vcmVFeGVjdXRvcnMubmV3U2VxdWVudGlhbEV4ZWN1dG9yKGNvbnRyb2xFeGVjdXRvcik7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIFNpbmdsZUZpbGVEb3dubG9hZFByb2dyZXNzTW9uaXRvci4gVGhpcyBpbnN0YW5jZSBtdXN0IGJlIHRoZSBzYW1lIGluc3RhbmNlIHRoYXQgaXMKKyAgICAgKiByZWdpc3RlcmVkIHdpdGggU3luY2hyb25vdXNGaWxlU3RvcmFnZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgcmVxdWlyZWQgdG8gdXNlIHtAbGluayBEb3dubG9hZGVyI2Rvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlfS4gTm90IHByb3ZpZGluZworICAgICAqIHRoaXMgd2lsbCByZXN1bHQgaW4gYSBmYWlsZWQgZnV0dXJlIHdoZW4gY2FsbGluZyBkb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZS4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgcmVxdWlyZWQgdG8gdHJhY2sgcHJvZ3Jlc3MgdXBkYXRlcyBhbmQgbmV0d29yayBwYXVzZXMgd2hlbiBwYXNzaW5nIGEge0BsaW5rCisgICAgICogRG93bmxvYWRMaXN0ZW5lcn0gdG8ge0BsaW5rIERvd25sb2FkZXIjZG93bmxvYWR9LiBUaGUgRG93bmxvYWRMaXN0ZW5lcidzIHtAY29kZSBvbkZhaWx1cmV9CisgICAgICogYW5kIHtAY29kZSBvbkNvbXBsZXRlfSB3aWxsIGJlIGludm9rZWQgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoaXMgaXMgc2V0LgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIHNldERvd25sb2FkTW9uaXRvcihTaW5nbGVGaWxlRG93bmxvYWRQcm9ncmVzc01vbml0b3IgZG93bmxvYWRNb25pdG9yKSB7CisgICAgICB0aGlzLmRvd25sb2FkTW9uaXRvck9wdGlvbmFsID0gT3B0aW9uYWwub2YoZG93bmxvYWRNb25pdG9yKTsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKgorICAgICAqIFNldCB0aGUgRm9yZWdyb3VuZCBEb3dubG9hZCBTZXJ2aWNlLiBUaGlzIGZvcmVncm91bmQgc2VydmljZSB3aWxsIGtlZXAgdGhlIGRvd25sb2FkIGFsaXZlCisgICAgICogZXZlbiBpZiB0aGUgdXNlciBuYXZpZ2F0ZXMgYXdheSBmcm9tIHRoZSBob3N0IGFwcC4gVGhpcyBlbnN1cmVzIGxvbmcgZG93bmxvYWQgY2FuIGZpbmlzaC4KKyAgICAgKgorICAgICAqIDxwPlRoaXMgaXMgcmVxdWlyZWQgdG8gdXNlIHtAbGluayBEb3dubG9hZGVyI2Rvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlfS4gTm90IHByb3ZpZGluZworICAgICAqIHRoaXMgd2lsbCByZXN1bHQgaW4gYSBmYWlsZWQgZnV0dXJlIHdoZW4gY2FsbGluZyBkb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVpbGRlciBzZXRGb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlKENsYXNzPD8+IGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzcykgeworICAgICAgdGhpcy5mb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbCA9IE9wdGlvbmFsLm9mKGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzcyk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXQgdGhlIEZpbGVEb3dubG9hZGVyIFN1cHBsaWVyLiBNRERMaXRlIHRha2VzIGluIGEgU3VwcGxpZXIgb2YgRmlsZURvd25sb2FkIHRvIHN1cHBvcnQgbGF6eQorICAgICAqIGluc3RhbnRpYXRpb24gb2YgdGhlIEZpbGVEb3dubG9hZGVyCisgICAgICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0RmlsZURvd25sb2FkZXJTdXBwbGllcihTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllcikgeworICAgICAgdGhpcy5maWxlRG93bmxvYWRlclN1cHBsaWVyID0gZmlsZURvd25sb2FkZXJTdXBwbGllcjsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIEJ1aWxkZXIoKSB7fQorCisgICAgcHVibGljIERvd25sb2FkZXIgYnVpbGQoKSB7CisgICAgICByZXR1cm4gbmV3IERvd25sb2FkZXJJbXBsKAorICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgZm9yZWdyb3VuZERvd25sb2FkU2VydmljZUNsYXNzT3B0aW9uYWwsCisgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciwKKyAgICAgICAgICBkb3dubG9hZE1vbml0b3JPcHRpb25hbCwKKyAgICAgICAgICBmaWxlRG93bmxvYWRlclN1cHBsaWVyKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9Eb3dubG9hZGVySW1wbC5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL0Rvd25sb2FkZXJJbXBsLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWMwY2I0OQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9Eb3dubG9hZGVySW1wbC5qYXZhCkBAIC0wLDAgKzEsNDQxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZHguYW5ub3RhdGlvbi5WaXNpYmxlRm9yVGVzdGluZzsKK2ltcG9ydCBhbmRyb2lkeC5jb3JlLmFwcC5Ob3RpZmljYXRpb25Db21wYXQ7CitpbXBvcnQgYW5kcm9pZHguY29yZS5hcHAuTm90aWZpY2F0aW9uTWFuYWdlckNvbXBhdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbi5Eb3dubG9hZFJlc3VsdENvZGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5mb3JlZ3JvdW5kLk5vdGlmaWNhdGlvblV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5QcmVjb25kaXRpb25zOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuU3VwcGxpZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZUNhbGxiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzOworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgb3JnLmNoZWNrZXJmcmFtZXdvcmsuY2hlY2tlci5udWxsbmVzcy5jb21wYXRxdWFsLk51bGxhYmxlRGVjbDsKKworZmluYWwgY2xhc3MgRG93bmxvYWRlckltcGwgaW1wbGVtZW50cyBEb3dubG9hZGVyIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJEb3dubG9hZGVySW1wIjsKKworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dDsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxDbGFzczw/Pj4gZm9yZWdyb3VuZERvd25sb2FkU2VydmljZUNsYXNzT3B0aW9uYWw7CisgIC8vIFRoaXMgZXhlY3V0b3Igd2lsbCBleGVjdXRlIHRhc2tzIHNlcXVlbnRpYWxseS4KKyAgcHJpdmF0ZSBmaW5hbCBFeGVjdXRvciBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworICBwcml2YXRlIGZpbmFsIE9wdGlvbmFsPFNpbmdsZUZpbGVEb3dubG9hZFByb2dyZXNzTW9uaXRvcj4gZG93bmxvYWRNb25pdG9yT3B0aW9uYWw7CisgIHByaXZhdGUgZmluYWwgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGZpbGVEb3dubG9hZGVyU3VwcGxpZXI7CisKKyAgLy8gU3luY2hyb25pemF0aW9uIHdpbGwgYmUgZG9uZSB0aHJvdWdoIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IKKyAgQFZpc2libGVGb3JUZXN0aW5nCisgIGZpbmFsIE1hcDxTdHJpbmcsIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4+IGtleVRvTGlzdGVuYWJsZUZ1dHVyZSA9IG5ldyBIYXNoTWFwPD4oKTsKKworICBEb3dubG9hZGVySW1wbCgKKyAgICAgIENvbnRleHQgY29udGV4dCwKKyAgICAgIE9wdGlvbmFsPENsYXNzPD8+PiBmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbCwKKyAgICAgIEV4ZWN1dG9yIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IsCisgICAgICBPcHRpb25hbDxTaW5nbGVGaWxlRG93bmxvYWRQcm9ncmVzc01vbml0b3I+IGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLAorICAgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGZpbGVEb3dubG9hZGVyU3VwcGxpZXIpIHsKKyAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OworICAgIHRoaXMuc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvciA9IHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3I7CisgICAgdGhpcy5mb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbCA9IGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsOworICAgIHRoaXMuZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgPSBkb3dubG9hZE1vbml0b3JPcHRpb25hbDsKKyAgICB0aGlzLmZpbGVEb3dubG9hZGVyU3VwcGxpZXIgPSBmaWxlRG93bmxvYWRlclN1cHBsaWVyOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkKERvd25sb2FkUmVxdWVzdCBkb3dubG9hZFJlcXVlc3QpIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBkb3dubG9hZCBmb3IgVXJpID0gJXMiLCBUQUcsIGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKTsKKyAgICByZXR1cm4gRnV0dXJlcy5zdWJtaXRBc3luYygKKyAgICAgICAgKCkgLT4geworICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIHRoZSBzYW1lIG9uLWdvaW5nIHJlcXVlc3QsIHJldHVybiB0aGF0IG9uZS4KKyAgICAgICAgICBpZiAoa2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmNvbnRhaW5zS2V5KGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKSkgeworICAgICAgICAgICAgLy8gdXJpVG9MaXN0ZW5hYmxlRnV0dXJlLmdldCBtdXN0IHJldHVybiBOb24tbnVsbCBzaW5jZSB3ZSBjaGVjayB0aGUgY29udGFpbnNLZXkgYWJvdmUuCisgICAgICAgICAgICAvLyBjaGVja05vdE51bGwgaXMgdG8gc3VwcHJlc3MgZmFsc2UgYWxhcm0gYWJvdXQgQE51bGxhYmxlIHJlc3VsdC4KKyAgICAgICAgICAgIHJldHVybiBQcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbCgKKyAgICAgICAgICAgICAgICBrZXlUb0xpc3RlbmFibGVGdXR1cmUuZ2V0KGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgLy8gUmVnaXN0ZXIgbGlzdGVuZXIgd2l0aCBtb25pdG9yIGlmIHByZXNlbnQKKyAgICAgICAgICBpZiAoZG93bmxvYWRSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgaWYgKGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICAgIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsCisgICAgICAgICAgICAgICAgICAuZ2V0KCkKKyAgICAgICAgICAgICAgICAgIC5hZGREb3dubG9hZExpc3RlbmVyKAorICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZFJlcXVlc3QubGlzdGVuZXJPcHRpb25hbCgpLmdldCgpKTsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgIExvZ1V0aWwudygKKyAgICAgICAgICAgICAgICAgICIlczogZG93bmxvYWQgcmVxdWVzdCBpbmNsdWRlZCBEb3dubG9hZExpc3RlbmVyLCBidXQgRG93bmxvYWRNb25pdG9yIGlzIG5vdCIKKyAgICAgICAgICAgICAgICAgICAgICArICIgcHJlc2VudCEgRG93bmxvYWRMaXN0ZW5lciB3aWxsIG9ubHkgYmUgaW52b2tlZCBmb3IgY29tcGxldGUvZmFpbHVyZS4iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICB9CisKKyAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0gc3RhcnREb3dubG9hZChkb3dubG9hZFJlcXVlc3QpOworCisgICAgICAgICAgRnV0dXJlcy5hZGRDYWxsYmFjaygKKyAgICAgICAgICAgICAgZG93bmxvYWRGdXR1cmUsCisgICAgICAgICAgICAgIG5ldyBGdXR1cmVDYWxsYmFjazxWb2lkPigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoVm9pZCByZXN1bHQpIHsKKyAgICAgICAgICAgICAgICAgIC8vIEN1cnJlbnRseSB0aGUgTW9iU3RvcmUgbW9uaXRvciBkb2VzIG5vdCBzdXBwb3J0IG9uU3VjY2VzcyBzbyB3ZSBoYXZlIHRvIGFkZAorICAgICAgICAgICAgICAgICAgLy8gY2FsbGJhY2sgdG8gdGhlIGRvd25sb2FkIGZ1dHVyZSBoZXJlLgorCisgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgZG93bmxvYWQgbGlzdGVuZXIgYW5kIHJlbW92ZSBkb3dubG9hZCBmdXR1cmUgZnJvbSBtYXAgYWZ0ZXIgbGlzdGVuZXIKKyAgICAgICAgICAgICAgICAgIC8vIGNvbXBsZXRlcworICAgICAgICAgICAgICAgICAgaWYgKGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuaXNQcmVzZW50KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgRnV0dXJlcy5hZGRDYWxsYmFjaygKKyAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkub25Db21wbGV0ZSgpLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEZ1dHVyZUNhbGxiYWNrPFZvaWQ+KCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25TdWNjZXNzKEBOdWxsYWJsZURlY2wgVm9pZCByZXN1bHQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlUb0xpc3RlbmFibGVGdXR1cmUucmVtb3ZlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZFJlcXVlc3QuZGVzdGluYXRpb25GaWxlVXJpKCkudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZE1vbml0b3JPcHRpb25hbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXQoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uRmFpbHVyZShUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZSh0LCAiJXM6IEZhaWxlZCB0byBydW4gY2xpZW50IG9uQ29tcGxldGUiLCBUQUcpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleVRvTGlzdGVuYWJsZUZ1dHVyZS5yZW1vdmUoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG93bmxvYWRNb25pdG9yT3B0aW9uYWwuaXNQcmVzZW50KCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoZG93bmxvYWRSZXF1ZXN0LmRlc3RpbmF0aW9uRmlsZVVyaSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBmcm9tIGZ1dHVyZSBtYXAgaW1tZWRpYXRlbHkKKyAgICAgICAgICAgICAgICAgICAga2V5VG9MaXN0ZW5hYmxlRnV0dXJlLnJlbW92ZShkb3dubG9hZFJlcXVlc3QuZGVzdGluYXRpb25GaWxlVXJpKCkudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUodCwgIiVzOiBEb3dubG9hZCBGdXR1cmUgZmFpbGVkIiwgVEFHKTsKKworICAgICAgICAgICAgICAgICAgLy8gQ3VycmVudGx5IHRoZSBNb2JTdG9yZSBtb25pdG9yIGRvZXMgbm90IHN1cHBvcnQgb25GYWlsdXJlIHNvIHdlIGhhdmUgdG8gYWRkCisgICAgICAgICAgICAgICAgICAvLyBjYWxsYmFjayB0byB0aGUgZG93bmxvYWQgZnV0dXJlIGhlcmUuCisgICAgICAgICAgICAgICAgICBpZiAoZG93bmxvYWRSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgICAgICBkb3dubG9hZFJlcXVlc3QubGlzdGVuZXJPcHRpb25hbCgpLmdldCgpLm9uRmFpbHVyZSh0KTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGRvd25sb2FkTW9uaXRvck9wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRNb25pdG9yT3B0aW9uYWwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKSk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIGtleVRvTGlzdGVuYWJsZUZ1dHVyZS5yZW1vdmUoZG93bmxvYWRSZXF1ZXN0LmRlc3RpbmF0aW9uRmlsZVVyaSgpLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgTW9yZUV4ZWN1dG9ycy5kaXJlY3RFeGVjdXRvcigpKTsKKworICAgICAgICAgIGtleVRvTGlzdGVuYWJsZUZ1dHVyZS5wdXQoCisgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpLCBkb3dubG9hZEZ1dHVyZSk7CisgICAgICAgICAgcmV0dXJuIGRvd25sb2FkRnV0dXJlOworICAgICAgICB9LAorICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBzdGFydERvd25sb2FkKERvd25sb2FkUmVxdWVzdCBkb3dubG9hZFJlcXVlc3QpIHsKKyAgICAvLyBUcmFuc2xhdGUgZnJvbSBNRERMaXRlIERvd25sb2FkUmVxdWVzdCB0byBNREREb3dubG9hZGVyIERvd25sb2FkUmVxdWVzdC4KKyAgICBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdAorICAgICAgICBmaWxlRG93bmxvYWRlclJlcXVlc3QgPQorICAgICAgICAgICAgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmkoZG93bmxvYWRSZXF1ZXN0LmRlc3RpbmF0aW9uRmlsZVVyaSgpKQorICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKGRvd25sb2FkUmVxdWVzdC5kb3dubG9hZENvbnN0cmFpbnRzKCkpCisgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoZG93bmxvYWRSZXF1ZXN0LnVybFRvRG93bmxvYWQoKSkKKyAgICAgICAgICAgICAgICAuc2V0RXh0cmFIdHRwSGVhZGVycyhkb3dubG9hZFJlcXVlc3QuZXh0cmFIdHRwSGVhZGVycygpKQorICAgICAgICAgICAgICAgIC5zZXRUcmFmZmljVGFnKGRvd25sb2FkUmVxdWVzdC50cmFmZmljVGFnKCkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgdHJ5IHsKKyAgICAgIHJldHVybiBmaWxlRG93bmxvYWRlclN1cHBsaWVyLmdldCgpLnN0YXJ0RG93bmxvYWRpbmcoZmlsZURvd25sb2FkZXJSZXF1ZXN0KTsKKyAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKKyAgICAgIC8vIENhdGNoIGFueSB1bmNoZWNrZWQgZXhjZXB0aW9ucyB0aGF0IHByZXZlbnRlZCB0aGUgZG93bmxvYWQgZnJvbSBzdGFydGluZy4KKyAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUikKKyAgICAgICAgICAgICAgLnNldENhdXNlKGUpCisgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRXaXRoRm9yZWdyb3VuZFNlcnZpY2UoRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCkgeworICAgIExvZ1V0aWwuZCgKKyAgICAgICAgIiVzOiBkb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZSBmb3IgVXJpID0gJXMiLAorICAgICAgICBUQUcsIGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKTsKKyAgICBpZiAoIWRvd25sb2FkTW9uaXRvck9wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgImRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlOiBEb3dubG9hZE1vbml0b3IgaXMgbm90IHByb3ZpZGVkISIpKTsKKyAgICB9CisgICAgaWYgKCFmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgIG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oCisgICAgICAgICAgICAgICJkb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZTogRm9yZWdyb3VuZERvd25sb2FkU2VydmljZSBpcyBub3QgcHJvdmlkZWQhIikpOworICAgIH0KKyAgICByZXR1cm4gRnV0dXJlcy5zdWJtaXRBc3luYygKKyAgICAgICAgKCkgLT4geworICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIHRoZSBzYW1lIG9uLWdvaW5nIHJlcXVlc3QsIHJldHVybiB0aGF0IG9uZS4KKyAgICAgICAgICBpZiAoa2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmNvbnRhaW5zS2V5KGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKSkgeworICAgICAgICAgICAgLy8gdXJpVG9MaXN0ZW5hYmxlRnV0dXJlLmdldCBtdXN0IHJldHVybiBOb24tbnVsbCBzaW5jZSB3ZSBjaGVjayB0aGUgY29udGFpbnNLZXkgYWJvdmUuCisgICAgICAgICAgICAvLyBjaGVja05vdE51bGwgaXMgdG8gc3VwcHJlc3MgZmFsc2UgYWxhcm0gYWJvdXQgQE51bGxhYmxlIHJlc3VsdC4KKyAgICAgICAgICAgIHJldHVybiBQcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbCgKKyAgICAgICAgICAgICAgICBrZXlUb0xpc3RlbmFibGVGdXR1cmUuZ2V0KGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKSk7CisgICAgICAgICAgfQorCisgICAgICAgICAgLy8gSXQncyBPSyB0byByZWNyZWF0ZSB0aGUgTm90aWZpY2F0aW9uQ2hhbm5lbCBzaW5jZSBpdCBjYW4gYWxzbyBiZSB1c2VkIHRvIHJlc3RvcmUgYQorICAgICAgICAgIC8vIGRlbGV0ZWQgY2hhbm5lbCBhbmQgdG8gdXBkYXRlIGFuIGV4aXN0aW5nIGNoYW5uZWwncyBuYW1lLCBkZXNjcmlwdGlvbiwgZ3JvdXAsIGFuZC9vcgorICAgICAgICAgIC8vIGltcG9ydGFuY2UuCisgICAgICAgICAgTm90aWZpY2F0aW9uVXRpbC5jcmVhdGVOb3RpZmljYXRpb25DaGFubmVsKGNvbnRleHQpOworCisgICAgICAgICAgLy8gT25seSBzdGFydCB0aGUgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlIHdoZW4gdGhlcmUgaXMgdGhlIGZpcnN0IGRvd25sb2FkIHJlcXVlc3QuCisgICAgICAgICAgaWYgKGtleVRvTGlzdGVuYWJsZUZ1dHVyZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIE5vdGlmaWNhdGlvblV0aWwuc3RhcnRGb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlKAorICAgICAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICAgICAgZm9yZWdyb3VuZERvd25sb2FkU2VydmljZUNsYXNzT3B0aW9uYWwuZ2V0KCksCisgICAgICAgICAgICAgICAgZG93bmxvYWRSZXF1ZXN0LmRlc3RpbmF0aW9uRmlsZVVyaSgpLnRvU3RyaW5nKCkpOworICAgICAgICAgIH0KKworICAgICAgICAgIERvd25sb2FkTGlzdGVuZXIgZG93bmxvYWRMaXN0ZW5lcldpdGhOb3RpZmljYXRpb24gPQorICAgICAgICAgICAgICBjcmVhdGVEb3dubG9hZExpc3RlbmVyV2l0aE5vdGlmaWNhdGlvbihkb3dubG9hZFJlcXVlc3QpOworCisgICAgICAgICAgLy8gVGhlIGRvd25sb2FkTW9uaXRvciB3aWxsIHRyaWdnZXIgdGhlIERvd25sb2FkTGlzdGVuZXIuCisgICAgICAgICAgZG93bmxvYWRNb25pdG9yT3B0aW9uYWwKKyAgICAgICAgICAgICAgLmdldCgpCisgICAgICAgICAgICAgIC5hZGREb3dubG9hZExpc3RlbmVyKAorICAgICAgICAgICAgICAgICAgZG93bmxvYWRSZXF1ZXN0LmRlc3RpbmF0aW9uRmlsZVVyaSgpLCBkb3dubG9hZExpc3RlbmVyV2l0aE5vdGlmaWNhdGlvbik7CisKKyAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0gc3RhcnREb3dubG9hZChkb3dubG9hZFJlcXVlc3QpOworCisgICAgICAgICAgRnV0dXJlcy5hZGRDYWxsYmFjaygKKyAgICAgICAgICAgICAgZG93bmxvYWRGdXR1cmUsCisgICAgICAgICAgICAgIG5ldyBGdXR1cmVDYWxsYmFjazxWb2lkPigpIHsKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoVm9pZCByZXN1bHQpIHsKKyAgICAgICAgICAgICAgICAgIC8vIEN1cnJlbnRseSB0aGUgTW9iU3RvcmUgbW9uaXRvciBkb2VzIG5vdCBzdXBwb3J0IG9uU3VjY2VzcyBzbyB3ZSBoYXZlIHRvIGFkZAorICAgICAgICAgICAgICAgICAgLy8gY2FsbGJhY2sgdG8gdGhlIGRvd25sb2FkIGZ1dHVyZSBoZXJlLgorCisgICAgICAgICAgICAgICAgICBGdXR1cmVzLmFkZENhbGxiYWNrKAorICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkTGlzdGVuZXJXaXRoTm90aWZpY2F0aW9uLm9uQ29tcGxldGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBuZXcgRnV0dXJlQ2FsbGJhY2s8Vm9pZD4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uU3VjY2VzcyhATnVsbGFibGVEZWNsIFZvaWQgcmVzdWx0KSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uRmFpbHVyZShUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUodCwgIiVzOiBGYWlsZWQgdG8gcnVuIGNsaWVudCBvbkNvbXBsZXRlIiwgVEFHKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IpOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uRmFpbHVyZShUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgICAgICAgLy8gQ3VycmVudGx5IHRoZSBNb2JTdG9yZSBtb25pdG9yIGRvZXMgbm90IHN1cHBvcnQgb25GYWlsdXJlIHNvIHdlIGhhdmUgdG8gYWRkCisgICAgICAgICAgICAgICAgICAvLyBjYWxsYmFjayB0byB0aGUgZG93bmxvYWQgZnV0dXJlIGhlcmUuCisgICAgICAgICAgICAgICAgICBMb2dVdGlsLmUodCwgIiVzOiBEb3dubG9hZCBGdXR1cmUgZmFpbGVkIiwgVEFHKTsKKyAgICAgICAgICAgICAgICAgIGRvd25sb2FkTGlzdGVuZXJXaXRoTm90aWZpY2F0aW9uLm9uRmFpbHVyZSh0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3IoKSk7CisKKyAgICAgICAgICBrZXlUb0xpc3RlbmFibGVGdXR1cmUucHV0KAorICAgICAgICAgICAgICBkb3dubG9hZFJlcXVlc3QuZGVzdGluYXRpb25GaWxlVXJpKCkudG9TdHJpbmcoKSwgZG93bmxvYWRGdXR1cmUpOworICAgICAgICAgIHJldHVybiBkb3dubG9hZEZ1dHVyZTsKKyAgICAgICAgfSwKKyAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgIH0KKworICAvLyBBc3NlcnRpb246IGZvcmVncm91bmREb3dubG9hZFNlcnZpY2UgYW5kIGRvd25sb2FkTW9uaXRvciBhcmUgcHJlc2VudAorICBwcml2YXRlIERvd25sb2FkTGlzdGVuZXIgY3JlYXRlRG93bmxvYWRMaXN0ZW5lcldpdGhOb3RpZmljYXRpb24oRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCkgeworICAgIE5vdGlmaWNhdGlvbk1hbmFnZXJDb21wYXQgbm90aWZpY2F0aW9uTWFuYWdlciA9IE5vdGlmaWNhdGlvbk1hbmFnZXJDb21wYXQuZnJvbShjb250ZXh0KTsKKyAgICBOb3RpZmljYXRpb25Db21wYXQuQnVpbGRlciBub3RpZmljYXRpb24gPQorICAgICAgICBOb3RpZmljYXRpb25VdGlsLmNyZWF0ZU5vdGlmaWNhdGlvbkJ1aWxkZXIoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgZG93bmxvYWRSZXF1ZXN0LmZpbGVTaXplQnl0ZXMoKSwKKyAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5ub3RpZmljYXRpb25Db250ZW50VGl0bGUoKSwKKyAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5ub3RpZmljYXRpb25Db250ZW50VGV4dE9wdGlvbmFsKCkub3IoZG93bmxvYWRSZXF1ZXN0LnVybFRvRG93bmxvYWQoKSkpOworCisgICAgaW50IG5vdGlmaWNhdGlvbktleSA9CisgICAgICAgIE5vdGlmaWNhdGlvblV0aWwubm90aWZpY2F0aW9uS2V5Rm9yS2V5KGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKTsKKworICAgIC8vIEF0dGFjaCB0aGUgQ2FuY2VsIGFjdGlvbiB0byB0aGUgbm90aWZpY2F0aW9uLgorICAgIE5vdGlmaWNhdGlvblV0aWwuY3JlYXRlQ2FuY2VsQWN0aW9uKAorICAgICAgICBjb250ZXh0LAorICAgICAgICBmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbC5nZXQoKSwKKyAgICAgICAgZG93bmxvYWRSZXF1ZXN0LmRlc3RpbmF0aW9uRmlsZVVyaSgpLnRvU3RyaW5nKCksCisgICAgICAgIG5vdGlmaWNhdGlvbiwKKyAgICAgICAgbm90aWZpY2F0aW9uS2V5KTsKKyAgICBub3RpZmljYXRpb25NYW5hZ2VyLm5vdGlmeShub3RpZmljYXRpb25LZXksIG5vdGlmaWNhdGlvbi5idWlsZCgpKTsKKworICAgIHJldHVybiBuZXcgRG93bmxvYWRMaXN0ZW5lcigpIHsKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKSB7CisgICAgICAgIHNlcXVlbnRpYWxDb250cm9sRXhlY3V0b3IuZXhlY3V0ZSgKKyAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgLy8gVGhlcmUgY2FuIGJlIGEgcmFjZSBjb25kaXRpb24sIHdoZXJlIG9uUGF1c2VkRm9yQ29ubmVjdGl2aXR5IGNhbiBiZSBjYWxsZWQKKyAgICAgICAgICAgICAgLy8gYWZ0ZXIgb25Db21wbGV0ZSBvciBvbkZhaWx1cmUgd2hpY2ggcmVtb3ZlcyB0aGUgZnV0dXJlIGFuZCB0aGUgbm90aWZpY2F0aW9uLgorICAgICAgICAgICAgICBpZiAoa2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmNvbnRhaW5zS2V5KAorICAgICAgICAgICAgICAgICAgZG93bmxvYWRSZXF1ZXN0LmRlc3RpbmF0aW9uRmlsZVVyaSgpLnRvU3RyaW5nKCkpKSB7CisgICAgICAgICAgICAgICAgbm90aWZpY2F0aW9uCisgICAgICAgICAgICAgICAgICAgIC5zZXRDYXRlZ29yeShOb3RpZmljYXRpb25Db21wYXQuQ0FURUdPUllfUFJPR1JFU1MpCisgICAgICAgICAgICAgICAgICAgIC5zZXRTbWFsbEljb24oYW5kcm9pZC5SLmRyYXdhYmxlLnN0YXRfc3lzX2Rvd25sb2FkKQorICAgICAgICAgICAgICAgICAgICAuc2V0UHJvZ3Jlc3MoCisgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZFJlcXVlc3QuZmlsZVNpemVCeXRlcygpLAorICAgICAgICAgICAgICAgICAgICAgICAgKGludCkgY3VycmVudFNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmRldGVybWluYXRlID0gKi8gZG93bmxvYWRSZXF1ZXN0LmZpbGVTaXplQnl0ZXMoKSA8PSAwKTsKKyAgICAgICAgICAgICAgICBub3RpZmljYXRpb25NYW5hZ2VyLm5vdGlmeShub3RpZmljYXRpb25LZXksIG5vdGlmaWNhdGlvbi5idWlsZCgpKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBpZiAoZG93bmxvYWRSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkub25Qcm9ncmVzcyhjdXJyZW50U2l6ZSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIG9uUGF1c2VkRm9yQ29ubmVjdGl2aXR5KCkgeworICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLmV4ZWN1dGUoCisgICAgICAgICAgICAoKSAtPiB7CisgICAgICAgICAgICAgIC8vIFRoZXJlIGNhbiBiZSBhIHJhY2UgY29uZGl0aW9uLCB3aGVyZSBvblBhdXNlZEZvckNvbm5lY3Rpdml0eSBjYW4gYmUgY2FsbGVkCisgICAgICAgICAgICAgIC8vIGFmdGVyIG9uQ29tcGxldGUgb3Igb25GYWlsdXJlIHdoaWNoIHJlbW92ZXMgdGhlIGZ1dHVyZSBhbmQgdGhlIG5vdGlmaWNhdGlvbi4KKyAgICAgICAgICAgICAgaWYgKGtleVRvTGlzdGVuYWJsZUZ1dHVyZS5jb250YWluc0tleSgKKyAgICAgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKSkgeworICAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbgorICAgICAgICAgICAgICAgICAgICAuc2V0Q2F0ZWdvcnkoTm90aWZpY2F0aW9uQ29tcGF0LkNBVEVHT1JZX1NUQVRVUykKKyAgICAgICAgICAgICAgICAgICAgLnNldENvbnRlbnRUZXh0KE5vdGlmaWNhdGlvblV0aWwuZ2V0RG93bmxvYWRQYXVzZWRNZXNzYWdlKGNvbnRleHQpKQorICAgICAgICAgICAgICAgICAgICAuc2V0U21hbGxJY29uKGFuZHJvaWQuUi5kcmF3YWJsZS5zdGF0X3N5c19kb3dubG9hZCkKKyAgICAgICAgICAgICAgICAgICAgLnNldE9uZ29pbmcodHJ1ZSkKKyAgICAgICAgICAgICAgICAgICAgLy8gaGlkZSBwcm9ncmVzcyBiYXIuCisgICAgICAgICAgICAgICAgICAgIC5zZXRQcm9ncmVzcygwLCAwLCBmYWxzZSk7CisgICAgICAgICAgICAgICAgbm90aWZpY2F0aW9uTWFuYWdlci5ub3RpZnkobm90aWZpY2F0aW9uS2V5LCBub3RpZmljYXRpb24uYnVpbGQoKSk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICBpZiAoZG93bmxvYWRSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkub25QYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSk7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gb25Db21wbGV0ZSgpIHsKKyAgICAgICAgLy8gV2Ugd2FudCB0byBrZWVwIHRoZSBGb3JlZ3JvdW5kIERvd25sb2FkIFNlcnZpY2UgYWxpdmUgdW50aWwgY2xpZW50J3Mgb25Db21wbGV0ZSBmaW5pc2hlcy4KKyAgICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjbGllbnRPbkNvbXBsZXRlRnV0dXJlID0KKyAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuaXNQcmVzZW50KCkKKyAgICAgICAgICAgICAgICA/IGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkub25Db21wbGV0ZSgpCisgICAgICAgICAgICAgICAgOiBGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKworICAgICAgICAvLyBMb2dpYyB0byBzaHV0ZG93biBGb3JlZ3JvdW5kIERvd25sb2FkIFNlcnZpY2UgYWZ0ZXIgdGhlIGNsaWVudCdzIHByb3ZpZGVkIG9uQ29tcGxldGUKKyAgICAgICAgLy8gZmluaXNoZWQKKyAgICAgICAgY2xpZW50T25Db21wbGV0ZUZ1dHVyZS5hZGRMaXN0ZW5lcigKKyAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIG5vdGlmaWNhdGlvbiBhY3Rpb24uCisgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbi5tQWN0aW9ucy5jbGVhcigpOworCisgICAgICAgICAgICAgIGlmIChkb3dubG9hZFJlcXVlc3Quc2hvd0Rvd25sb2FkZWROb3RpZmljYXRpb24oKSkgeworICAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbgorICAgICAgICAgICAgICAgICAgICAuc2V0Q2F0ZWdvcnkoTm90aWZpY2F0aW9uQ29tcGF0LkNBVEVHT1JZX1NUQVRVUykKKyAgICAgICAgICAgICAgICAgICAgLnNldENvbnRlbnRUZXh0KE5vdGlmaWNhdGlvblV0aWwuZ2V0RG93bmxvYWRTdWNjZXNzTWVzc2FnZShjb250ZXh0KSkKKyAgICAgICAgICAgICAgICAgICAgLnNldE9uZ29pbmcoZmFsc2UpCisgICAgICAgICAgICAgICAgICAgIC5zZXRTbWFsbEljb24oYW5kcm9pZC5SLmRyYXdhYmxlLnN0YXRfc3lzX2Rvd25sb2FkX2RvbmUpCisgICAgICAgICAgICAgICAgICAgIC8vIGhpZGUgcHJvZ3Jlc3MgYmFyLgorICAgICAgICAgICAgICAgICAgICAuc2V0UHJvZ3Jlc3MoMCwgMCwgZmFsc2UpOworCisgICAgICAgICAgICAgICAgbm90aWZpY2F0aW9uTWFuYWdlci5ub3RpZnkobm90aWZpY2F0aW9uS2V5LCBub3RpZmljYXRpb24uYnVpbGQoKSk7CisgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgTm90aWZpY2F0aW9uVXRpbC5jYW5jZWxOb3RpZmljYXRpb25Gb3JLZXkoCisgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIGtleVRvTGlzdGVuYWJsZUZ1dHVyZS5yZW1vdmUoZG93bmxvYWRSZXF1ZXN0LmRlc3RpbmF0aW9uRmlsZVVyaSgpLnRvU3RyaW5nKCkpOworICAgICAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBvdGhlciBvbi1nb2luZyBmb3JlZ3JvdW5kIGRvd25sb2FkLCBzaHV0ZG93biB0aGUKKyAgICAgICAgICAgICAgLy8gRm9yZWdyb3VuZERvd25sb2FkU2VydmljZQorICAgICAgICAgICAgICBpZiAoa2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIE5vdGlmaWNhdGlvblV0aWwuc3RvcEZvcmVncm91bmREb3dubG9hZFNlcnZpY2UoCisgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsLmdldCgpKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsCisgICAgICAgICAgICAgICAgICAuZ2V0KCkKKyAgICAgICAgICAgICAgICAgIC5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKSk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvcik7CisgICAgICAgIHJldHVybiBjbGllbnRPbkNvbXBsZXRlRnV0dXJlOworICAgICAgfQorCisgICAgICBAT3ZlcnJpZGUKKyAgICAgIHB1YmxpYyB2b2lkIG9uRmFpbHVyZShUaHJvd2FibGUgdCkgeworICAgICAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLmV4ZWN1dGUoCisgICAgICAgICAgICAoKSAtPiB7CisgICAgICAgICAgICAgIC8vIENsZWFyIHRoZSBub3RpZmljYXRpb24gYWN0aW9uLgorICAgICAgICAgICAgICBub3RpZmljYXRpb24ubUFjdGlvbnMuY2xlYXIoKTsKKworICAgICAgICAgICAgICAvLyBTaG93IGRvd25sb2FkIGZhaWxlZCBpbiBub3RpZmljYXRpb24uCisgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbgorICAgICAgICAgICAgICAgICAgLnNldENhdGVnb3J5KE5vdGlmaWNhdGlvbkNvbXBhdC5DQVRFR09SWV9TVEFUVVMpCisgICAgICAgICAgICAgICAgICAuc2V0Q29udGVudFRleHQoTm90aWZpY2F0aW9uVXRpbC5nZXREb3dubG9hZEZhaWxlZE1lc3NhZ2UoY29udGV4dCkpCisgICAgICAgICAgICAgICAgICAuc2V0T25nb2luZyhmYWxzZSkKKyAgICAgICAgICAgICAgICAgIC5zZXRTbWFsbEljb24oYW5kcm9pZC5SLmRyYXdhYmxlLnN0YXRfc3lzX3dhcm5pbmcpCisgICAgICAgICAgICAgICAgICAvLyBoaWRlIHByb2dyZXNzIGJhci4KKyAgICAgICAgICAgICAgICAgIC5zZXRQcm9ncmVzcygwLCAwLCBmYWxzZSk7CisKKyAgICAgICAgICAgICAgbm90aWZpY2F0aW9uTWFuYWdlci5ub3RpZnkobm90aWZpY2F0aW9uS2V5LCBub3RpZmljYXRpb24uYnVpbGQoKSk7CisKKyAgICAgICAgICAgICAga2V5VG9MaXN0ZW5hYmxlRnV0dXJlLnJlbW92ZShkb3dubG9hZFJlcXVlc3QuZGVzdGluYXRpb25GaWxlVXJpKCkudG9TdHJpbmcoKSk7CisKKyAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gb3RoZXIgb24tZ29pbmcgZm9yZWdyb3VuZCBkb3dubG9hZCwgc2h1dGRvd24gdGhlCisgICAgICAgICAgICAgIC8vIEZvcmVncm91bmREb3dubG9hZFNlcnZpY2UKKyAgICAgICAgICAgICAgaWYgKGtleVRvTGlzdGVuYWJsZUZ1dHVyZS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgICAgICBOb3RpZmljYXRpb25VdGlsLnN0b3BGb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlKAorICAgICAgICAgICAgICAgICAgICBjb250ZXh0LCBmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbC5nZXQoKSk7CisgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICBpZiAoZG93bmxvYWRSZXF1ZXN0Lmxpc3RlbmVyT3B0aW9uYWwoKS5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgICAgIGRvd25sb2FkUmVxdWVzdC5saXN0ZW5lck9wdGlvbmFsKCkuZ2V0KCkub25GYWlsdXJlKHQpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsCisgICAgICAgICAgICAgICAgICAuZ2V0KCkKKyAgICAgICAgICAgICAgICAgIC5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKSk7CisgICAgICAgICAgICB9KTsKKyAgICAgIH0KKyAgICB9OworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIGNhbmNlbEZvcmVncm91bmREb3dubG9hZChTdHJpbmcgZGVzdGluYXRpb25GaWxlVXJpKSB7CisgICAgTG9nVXRpbC5kKCIlczogQ2FuY2VsRm9yZWdyb3VuZERvd25sb2FkIGZvciBVcmkgPSAlcyIsIFRBRywgZGVzdGluYXRpb25GaWxlVXJpKTsKKyAgICBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yLmV4ZWN1dGUoCisgICAgICAgICgpIC0+IHsKKyAgICAgICAgICBpZiAoa2V5VG9MaXN0ZW5hYmxlRnV0dXJlLmNvbnRhaW5zS2V5KGRlc3RpbmF0aW9uRmlsZVVyaSkpIHsKKyAgICAgICAgICAgIGtleVRvTGlzdGVuYWJsZUZ1dHVyZS5nZXQoZGVzdGluYXRpb25GaWxlVXJpKS5jYW5jZWwodHJ1ZSk7CisgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL1NpbmdsZUZpbGVEb3dubG9hZFByb2dyZXNzTW9uaXRvci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL1NpbmdsZUZpbGVEb3dubG9hZFByb2dyZXNzTW9uaXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEwZTZjOGMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvU2luZ2xlRmlsZURvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmphdmEKQEAgLTAsMCArMSw0MCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubGl0ZTsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKKworLyoqIEludGVyZmFjZSBmb3IgTW9uaXRvcmluZyBTaW5nbGUgRmlsZSBEb3dubG9hZHMgZm9yIE1ERCBMaXRlLiAqLworcHVibGljIGludGVyZmFjZSBTaW5nbGVGaWxlRG93bmxvYWRQcm9ncmVzc01vbml0b3IgeworCisgIC8qKgorICAgKiBBZGQgYSBEb3dubG9hZExpc3RlbmVyIHRoYXQgY2xpZW50IGNhbiB1c2UgdG8gcmVjZWl2ZSBkb3dubG9hZCBwcm9ncmVzcyB1cGRhdGUuIEN1cnJlbnRseSB3ZQorICAgKiBvbmx5IHN1cHBvcnQgMSBsaXN0ZW5lciBwZXIgZmlsZSB1cmkuIENhbGxpbmcgYWRkRG93bmxvYWRMaXN0ZW5lciB0byBhZGQgYW5vdGhlciBsaXN0ZW5lciB3b3VsZAorICAgKiBiZSBuby1vcC4KKyAgICoKKyAgICogQHBhcmFtIHVyaSBUaGUgZGVzdGluYXRpb24gZmlsZSB1cmkgdGhhdCB0aGUgRG93bmxvYWRMaXN0ZW5lciB3aWxsIHJlY2VpdmUgZG93bmxvYWQgcHJvZ3Jlc3MKKyAgICogICAgIHVwZGF0ZS4KKyAgICogQHBhcmFtIGRvd25sb2FkTGlzdGVuZXIgdGhlIERvd25sb2FkTGlzdGVuZXIgdG8gYWRkLgorICAgKi8KKyAgcHVibGljIHZvaWQgYWRkRG93bmxvYWRMaXN0ZW5lcihVcmkgdXJpLCBEb3dubG9hZExpc3RlbmVyIGRvd25sb2FkTGlzdGVuZXIpOworCisgIC8qKgorICAgKiBSZW1vdmUgYSBEb3dubG9hZExpc3RlbmVyLgorICAgKgorICAgKiBAcGFyYW0gdXJpIFRoZSB1cmkgdGhhdCB0aGUgRG93bmxvYWRMaXN0ZW5lciByZWNlaXZlIGRvd25sb2FkIHByb2dyZXNzIHVwZGF0ZS4KKyAgICovCisgIHB1YmxpYyB2b2lkIHJlbW92ZURvd25sb2FkTGlzdGVuZXIoVXJpIHVyaSk7Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvYW5ub3RhdGlvbnMvQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvYW5ub3RhdGlvbnMvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmQwMGIzYgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9hbm5vdGF0aW9ucy9CVUlMRApAQCAtMCwwICsxLDI3IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9saWJyYXJ5IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbCisgICAgICAgICIvL3Zpc2liaWxpdHk6cHVibGljIiwKKyAgICBdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiYW5ub3RhdGlvbnMiLAorICAgIHNyY3MgPSBnbG9iKFsiKi5qYXZhIl0pLAorICAgIGRlcHMgPSBbIkBqYXZheF9pbmplY3QiXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9hbm5vdGF0aW9ucy9NZGRMaXRlLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvYW5ub3RhdGlvbnMvTWRkTGl0ZS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU1YzU4NmEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvYW5ub3RhdGlvbnMvTWRkTGl0ZS5qYXZhCkBAIC0wLDAgKzEsMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmxpdGUuYW5ub3RhdGlvbnM7CisKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5FbGVtZW50VHlwZTsKK2ltcG9ydCBqYXZhLmxhbmcuYW5ub3RhdGlvbi5UYXJnZXQ7CitpbXBvcnQgamF2YXguaW5qZWN0LlF1YWxpZmllcjsKKworLyoqIFF1YWxpZmllciBmb3IgTURETGl0ZS4gKi8KK0BUYXJnZXQoe0VsZW1lbnRUeXBlLlBBUkFNRVRFUiwgRWxlbWVudFR5cGUuTUVUSE9ELCBFbGVtZW50VHlwZS5GSUVMRH0pCitAUXVhbGlmaWVyCitwdWJsaWMgQGludGVyZmFjZSBNZGRMaXRlIHt9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvYW5ub3RhdGlvbnMvTWRkTGl0ZUNvbnRyb2xFeGVjdXRvci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL2Fubm90YXRpb25zL01kZExpdGVDb250cm9sRXhlY3V0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Y2ZmYTM4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL2Fubm90YXRpb25zL01kZExpdGVDb250cm9sRXhlY3V0b3IuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlLmFubm90YXRpb25zOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworaW1wb3J0IGphdmF4LmluamVjdC5RdWFsaWZpZXI7CisKKy8qKiBBbiBleGVjdXRvciBvbiB3aGljaCBNRERMaXRlIHJ1bnMgY29udHJvbCBleGVjdXRpb24gZmxvdyB3aGljaCB3aWxsIHRvdWNoIEkvTy4gKi8KK0BUYXJnZXQoe0VsZW1lbnRUeXBlLlBBUkFNRVRFUiwgRWxlbWVudFR5cGUuTUVUSE9ELCBFbGVtZW50VHlwZS5GSUVMRH0pCitAUXVhbGlmaWVyCitwdWJsaWMgQGludGVyZmFjZSBNZGRMaXRlQ29udHJvbEV4ZWN1dG9yIHt9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvYW5ub3RhdGlvbnMvTWRkTGl0ZURvd25sb2FkRXhlY3V0b3IuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9hbm5vdGF0aW9ucy9NZGRMaXRlRG93bmxvYWRFeGVjdXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY1M2FlYTQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvYW5ub3RhdGlvbnMvTWRkTGl0ZURvd25sb2FkRXhlY3V0b3IuamF2YQpAQCAtMCwwICsxLDI1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlLmFubm90YXRpb25zOworCitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uRWxlbWVudFR5cGU7CitpbXBvcnQgamF2YS5sYW5nLmFubm90YXRpb24uVGFyZ2V0OworaW1wb3J0IGphdmF4LmluamVjdC5RdWFsaWZpZXI7CisKKy8qKiBBbiBleGVjdXRvciBvbiB3aGljaCBNRERMaXRlIHJ1bnMgZG93bmxvYWRpbmcgdGFza3Mgd2hpY2ggd2lsbCB0b3VjaCBJL08uICovCitAVGFyZ2V0KHtFbGVtZW50VHlwZS5QQVJBTUVURVIsIEVsZW1lbnRUeXBlLk1FVEhPRCwgRWxlbWVudFR5cGUuRklFTER9KQorQFF1YWxpZmllcgorcHVibGljIEBpbnRlcmZhY2UgTWRkTGl0ZURvd25sb2FkRXhlY3V0b3Ige30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbG9nZ2VyL0JVSUxEIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9sb2dnZXIvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDhhMzU2MAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbG9nZ2VyL0JVSUxECkBAIC0wLDAgKzEsMzEgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsKKyAgICAgICAgIi8vdmlzaWJpbGl0eTpwdWJsaWMiLAorICAgIF0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJGaWxlR3JvdXBQb3B1bGF0b3JMb2dnZXIiLAorICAgIHNyY3MgPSBbIkZpbGVHcm91cFBvcHVsYXRvckxvZ2dlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6TG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ1V0aWwiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xvZ2dlci9GaWxlR3JvdXBQb3B1bGF0b3JMb2dnZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbG9nZ2VyL0ZpbGVHcm91cFBvcHVsYXRvckxvZ2dlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzNWYzYjMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xvZ2dlci9GaWxlR3JvdXBQb3B1bGF0b3JMb2dnZXIuamF2YQpAQCAtMCwwICsxLDUyIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5sb2dnZXI7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GbGFnczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Mb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dVdGlsOworCisvKiogVGhlIGV2ZW50IGxvZ2dlciBmb3Ige0Bjb2RlIEZpbGVHcm91cFBvcHVsYXRvcn0ncy4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBGaWxlR3JvdXBQb3B1bGF0b3JMb2dnZXIgeworCisgIHByaXZhdGUgZmluYWwgTG9nZ2VyIGxvZ2dlcjsKKyAgcHJpdmF0ZSBmaW5hbCBGbGFncyBmbGFnczsKKworICBwdWJsaWMgRmlsZUdyb3VwUG9wdWxhdG9yTG9nZ2VyKExvZ2dlciBsb2dnZXIsIEZsYWdzIGZsYWdzKSB7CisgICAgdGhpcy5sb2dnZXIgPSBsb2dnZXI7CisgICAgdGhpcy5mbGFncyA9IGZsYWdzOworICB9CisKKyAgLyoqIExvZ3MgdGhlIHJlZnJlc2ggcmVzdWx0IG9mIHtAY29kZSBNYW5pZmVzdEZpbGVHcm91cFBvcHVsYXRvcn0uICovCisgIHB1YmxpYyB2b2lkIGxvZ01hbmlmZXN0RmlsZUdyb3VwUG9wdWxhdG9yUmVmcmVzaFJlc3VsdCgKKyAgICAgIGludCBjb2RlLCBTdHJpbmcgbWFuaWZlc3RJZCwgU3RyaW5nIG93bmVyUGFja2FnZU5hbWUsIFN0cmluZyBtYW5pZmVzdEZpbGVVcmwpIHsKKyAgICBpbnQgc2FtcGxlSW50ZXJ2YWwgPSBmbGFncy5tZGREZWZhdWx0U2FtcGxlSW50ZXJ2YWwoKTsKKyAgICBpZiAoIUxvZ1V0aWwuc2hvdWxkU2FtcGxlSW50ZXJ2YWwoc2FtcGxlSW50ZXJ2YWwpKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIFZvaWQgbG9nRGF0YSA9IG51bGw7CisgIH0KKworICAvKiogTG9ncyB0aGUgcmVmcmVzaCByZXN1bHQgb2Yge0Bjb2RlIEdlbGxlckZpbGVHcm91cFBvcHVsYXRvcn0uICovCisgIHB1YmxpYyB2b2lkIGxvZ0dkZEZpbGVHcm91cFBvcHVsYXRvclJlZnJlc2hSZXN1bHQoCisgICAgICBpbnQgY29kZSwgU3RyaW5nIGNvbmZpZ3VyYXRpb25JZCwgU3RyaW5nIG93bmVyUGFja2FnZU5hbWUsIFN0cmluZyBjb3JwdXMpIHsKKyAgICBpbnQgc2FtcGxlSW50ZXJ2YWwgPSBmbGFncy5tZGREZWZhdWx0U2FtcGxlSW50ZXJ2YWwoKTsKKyAgICBpZiAoIUxvZ1V0aWwuc2hvdWxkU2FtcGxlSW50ZXJ2YWwoc2FtcGxlSW50ZXJ2YWwpKSB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIFZvaWQgbG9nRGF0YSA9IG51bGw7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvci9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvci9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jYWVhYTNjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yL0JVSUxECkBAIC0wLDAgKzEsNTUgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsKKyAgICAgICAgIi8vdmlzaWJpbGl0eTpwdWJsaWMiLAorICAgIF0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJOZXR3b3JrVXNhZ2VNb25pdG9yIiwKKyAgICBzcmNzID0gWyJOZXR3b3JrVXNhZ2VNb25pdG9yLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOlRpbWVTb3VyY2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvbW9uaXRvcnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ1V0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nZ2luZ1N0YXRlU3RvcmUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZyIsCisgICAgICAgICJAYW5kcm9pZHhfYW5ub3RhdGlvbl9hbm5vdGF0aW9uIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgc3JjcyA9IFsiRG93bmxvYWRQcm9ncmVzc01vbml0b3IuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRMaXN0ZW5lciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6VGltZVNvdXJjZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9tb25pdG9ycyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZTpEb3dubG9hZExpc3RlbmVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlOkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3IvRG93bmxvYWRQcm9ncmVzc01vbml0b3IuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvci9Eb3dubG9hZFByb2dyZXNzTW9uaXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkY2JmNmEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3IvRG93bmxvYWRQcm9ncmVzc01vbml0b3IuamF2YQpAQCAtMCwwICsxLDI1NyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubW9uaXRvcjsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkeC5hbm5vdGF0aW9uLlZpc2libGVGb3JUZXN0aW5nOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkTGlzdGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGltZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm1vbml0b3JzLkJ5dGVDb3VudGluZ091dHB1dE1vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubGl0ZS5TaW5nbGVGaWxlRG93bmxvYWRQcm9ncmVzc01vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0xvbmc7CitpbXBvcnQgamF2YXguYW5ub3RhdGlvbi5OdWxsYWJsZTsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLmNvbmN1cnJlbnQuR3VhcmRlZEJ5OworaW1wb3J0IGphdmF4LmFubm90YXRpb24uY29uY3VycmVudC5UaHJlYWRTYWZlOworCisvKioKKyAqIEEgRG93bmxvYWQgUHJvZ3Jlc3MgTW9uaXRvciB0byBzdXBwb3J0IHtAbGluayBEb3dubG9hZExpc3RlbmVyfS4KKyAqCisgKiA8cD5CZWZvcmUgbW9uaXRvcmluZyBhbiBVcmksIG9uZSBuZWVkcyB0byBjYWxsIG1vbml0b3JVcmkgdG8gcmVjb3JkIHRoZSBmaWxlIGdyb3VwIHRoYXQgVXJpCisgKiBiZWxvbmdzIHRvIGF0IHRoZSBkb3dubG9hZGluZyB0aW1lLgorICoKKyAqIDxwPkN1cnJlbnRseSB3ZSBvbmx5IHN1cHBvcnQgMSBEb3dubG9hZExpc3RlbmVyIHBlciBGaWxlIEdyb3VwLgorICovCitAVGhyZWFkU2FmZQorcHVibGljIGNsYXNzIERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIGltcGxlbWVudHMgTW9uaXRvciwgU2luZ2xlRmlsZURvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIjsKKworICBwcml2YXRlIGZpbmFsIFRpbWVTb3VyY2UgdGltZVNvdXJjZTsKKyAgcHJpdmF0ZSBmaW5hbCBFeGVjdXRvciBzZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yOworICBwcml2YXRlIGZpbmFsIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmxpdGUuRG93bmxvYWRQcm9ncmVzc01vbml0b3IKKyAgICAgIGxpdGVEb3dubG9hZFByb2dyZXNzTW9uaXRvcjsKKworICBwdWJsaWMgRG93bmxvYWRQcm9ncmVzc01vbml0b3IoVGltZVNvdXJjZSB0aW1lU291cmNlLCBFeGVjdXRvciBjb250cm9sRXhlY3V0b3IpIHsKKyAgICB0aGlzLnRpbWVTb3VyY2UgPSB0aW1lU291cmNlOworCisgICAgLy8gV2Ugd2FudCBvblByb2dyZXNzIHRvIGJlIGV4ZWN1dGVkIGluIG9yZGVyIG90aGVyd2lzZSBjbGllbnRzIHdpbGwgb2JzZXJ2ZSBvdXQgb2Ygb3JkZXIKKyAgICAvLyB1cGRhdGVzIChiaWdnZXIgY3VycmVudCBzaXplIHVwZGF0ZSBhcHBlYXJzIGJlZm9yZSBzbWFsbGVyIGN1cnJlbnQgc2l6ZSB1cGRhdGUpLgorICAgIC8vIFdlIHVzZSBTZXF1ZW50aWFsIEV4ZWN1dG9yIHRvIGVuc3VyZSB0aGUgb25Qcm9ncmVzcyB3aWxsIGJlIHByb2Nlc3NlZCBzZXF1ZW50aWFsbHkuCisgICAgdGhpcy5zZXF1ZW50aWFsQ29udHJvbEV4ZWN1dG9yID0gTW9yZUV4ZWN1dG9ycy5uZXdTZXF1ZW50aWFsRXhlY3V0b3IoY29udHJvbEV4ZWN1dG9yKTsKKworICAgIC8vIENvbnN0cnVjdCBpbnRlcm5hbCBpbnN0YW5jZSBvZiBNREQgTGl0ZSdzIERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLiBtZXRob2RzIG9mCisgICAgLy8gU2luZ2xlRmlsZURvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIHdpbGwgZGVsZWdhdGUgdG8gdGhpcyBpbnN0YW5jZS4KKyAgICB0aGlzLmxpdGVEb3dubG9hZFByb2dyZXNzTW9uaXRvciA9CisgICAgICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmxpdGUuRG93bmxvYWRQcm9ncmVzc01vbml0b3IuY3JlYXRlKAorICAgICAgICAgICAgdGhpcy50aW1lU291cmNlLCBjb250cm9sRXhlY3V0b3IpOworICB9CisKKyAgLy8gV2Ugd2lsbCBvbmx5IGJyb2FkY2FzdCBvbiBwcm9ncmVzcyBub3RpZmljYXRpb24gYXQgbW9zdCBvbmNlIGluIHRoaXMgdGltZSBmcmFtZS4KKyAgLy8gQ3VycmVudGx5IE1vYlN0b3JlIE1vbml0b3Igbm90aWZ5IGV2ZXJ5IDhLQiBvZiBkb3dubG9hZGVkIGJ5dGVzLiBUaGlzIG1heSBiZSB0b28gY2hhdHR5IG9uCisgIC8vIGZhc3QgbmV0d29yay4KKyAgLy8gMSBzZWNvbmQgd2FzIGNob3NlbiBhcmJpdHJhcmlseS4KKyAgQFZpc2libGVGb3JUZXN0aW5nIHN0YXRpYyBmaW5hbCBsb25nIExPR19GUkVRVUVOQ1kgPSAxMDAwTDsKKworICAvLyBNb2JTdG9yZSBNb25pdG9yIHdvcmtzIGF0IGZpbGUgbGV2ZWwuIFdlIHdhbnQgdG8gbW9uaXRvciBhdCBGaWxlR3JvdXAgbGV2ZWwuIFRoaXMgbWFwIHdpbGwKKyAgLy8gaGVscCB0byBtYXAgZnJvbSBhIGZpbGVVcmkgdG8gYSBmaWxlIGdyb3VwLgorICBAR3VhcmRlZEJ5KCJEb3dubG9hZFByb2dyZXNzTW9uaXRvci5jbGFzcyIpCisgIHByaXZhdGUgZmluYWwgSGFzaE1hcDxVcmksIFN0cmluZz4gdXJpVG9GaWxlR3JvdXAgPSBuZXcgSGFzaE1hcDw+KCk7CisKKyAgQEd1YXJkZWRCeSgiRG93bmxvYWRQcm9ncmVzc01vbml0b3IuY2xhc3MiKQorICBwcml2YXRlIGZpbmFsIEhhc2hNYXA8U3RyaW5nLCBCeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yPiBmaWxlR3JvdXBUb0J5dGVDb3VudGluZ091dHB1dE1vbml0b3IgPQorICAgICAgbmV3IEhhc2hNYXA8PigpOworCisgIEBPdmVycmlkZQorICBATnVsbGFibGUKKyAgcHVibGljIE1vbml0b3IuSW5wdXRNb25pdG9yIG1vbml0b3JSZWFkKFVyaSB1cmkpIHsKKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIEBPdmVycmlkZQorICBATnVsbGFibGUKKyAgcHVibGljIE1vbml0b3IuT3V0cHV0TW9uaXRvciBtb25pdG9yV3JpdGUoVXJpIHVyaSkgeworICAgIHN5bmNocm9uaXplZCAoRG93bmxvYWRQcm9ncmVzc01vbml0b3IuY2xhc3MpIHsKKyAgICAgIFN0cmluZyBncm91cE5hbWUgPSB1cmlUb0ZpbGVHcm91cC5nZXQodXJpKTsKKyAgICAgIGlmIChncm91cE5hbWUgPT0gbnVsbCkgeworICAgICAgICAvLyBNb2JTdG9yZSB3aWxsIGNhbGwgYWxsIG1vbml0b3JzIGZvciBhbGwgZmlsZXMgaXQgaGFuZGxlcy4KKyAgICAgICAgLy8gSW4gdGhpcyBjYXNlLCB3ZSByZWNlaXZlIGEgY2FsbCBmcm9tIE1vYlN0b3JlIGZvciBhbiBVcmkgdGhhdCB3ZSBkaWQgbm90IHJlZ2lzdGVyIGZvci4KKyAgICAgICAgLy8KKyAgICAgICAgLy8gVGhpcyBtYXkgYmUgZm9yIGEgc2luZ2xlIGZpbGUgZG93bmxvYWQsIHNvIGRlbGVnYXRlIHRvIGxpdGVEb3dubG9hZFByb2dyZXNzTW9uaXRvci4gVGhpcworICAgICAgICAvLyB3aWxsIGNoZWNrIGl0cyBpbnRlcm5hbCBtYXAgYW5kIHJldHVybiBudWxsIGlmIG5vdCBmb3VuZC4KKyAgICAgICAgcmV0dXJuIGxpdGVEb3dubG9hZFByb2dyZXNzTW9uaXRvci5tb25pdG9yV3JpdGUodXJpKTsKKyAgICAgIH0KKworICAgICAgaWYgKGZpbGVHcm91cFRvQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvci5nZXQoZ3JvdXBOYW1lKSA9PSBudWxsKSB7CisgICAgICAgIC8vIFRoaXMgaXMgYSByZWFsIGVycm9yLiBXZSByZWdpc3RlciBmb3IgdGhpcyBVcmkgYnV0IGRvZXMgb3QgaGF2ZSBhIGNvdW50ZXIgZm9yIGl0LgorICAgICAgICBMb2dVdGlsLmUoIiVzOiBDYW4ndCBmaW5kIGZpbGUgZ3JvdXAgZm9yIHVyaTogJXMiLCBUQUcsIHVyaSk7CisgICAgICAgIHJldHVybiBudWxsOworICAgICAgfQorICAgICAgcmV0dXJuIGZpbGVHcm91cFRvQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvci5nZXQoZ3JvdXBOYW1lKTsKKyAgICB9CisgIH0KKworICBAT3ZlcnJpZGUKKyAgQE51bGxhYmxlCisgIHB1YmxpYyBNb25pdG9yLk91dHB1dE1vbml0b3IgbW9uaXRvckFwcGVuZChVcmkgdXJpKSB7CisgICAgcmV0dXJuIG1vbml0b3JXcml0ZSh1cmkpOworICB9CisKKyAgcHVibGljIHZvaWQgcGF1c2VkRm9yQ29ubmVjdGl2aXR5KCkgeworICAgIHN5bmNocm9uaXplZCAoRG93bmxvYWRQcm9ncmVzc01vbml0b3IuY2xhc3MpIHsKKyAgICAgIGZvciAoQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvciBieXRlQ291bnRpbmdPdXRwdXRNb25pdG9yIDoKKyAgICAgICAgICBmaWxlR3JvdXBUb0J5dGVDb3VudGluZ091dHB1dE1vbml0b3IudmFsdWVzKCkpIHsKKyAgICAgICAgRG93bmxvYWRlZEJ5dGVzQ291bnRlciBjb3VudGVyID0KKyAgICAgICAgICAgIChEb3dubG9hZGVkQnl0ZXNDb3VudGVyKSBieXRlQ291bnRpbmdPdXRwdXRNb25pdG9yLmdldENvdW50ZXIoKTsKKyAgICAgICAgY291bnRlci5wYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKyAgICAgIH0KKworICAgICAgLy8gRGVsZWdhdGUgdG8gbGl0ZURvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIGFzIHdlbGwgc28gc2luZ2xlIGZpbGUgZG93bmxvYWRzIGNhbiBiZSB1cGRhdGVkCisgICAgICBsaXRlRG93bmxvYWRQcm9ncmVzc01vbml0b3IucGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEFkZCBhIEZpbGUgR3JvdXAgRG93bmxvYWRMaXN0ZW5lciB0aGF0IGNsaWVudCBjYW4gdXNlIHRvIHJlY2VpdmUgZG93bmxvYWQgcHJvZ3Jlc3MgdXBkYXRlLgorICAgKgorICAgKiA8cD5DdXJyZW50bHkgd2Ugb25seSBzdXBwb3J0IDEgbGlzdGVuZXIgcGVyIGZpbGUgZ3JvdXAuIENhbGxpbmcgYWRkRG93bmxvYWRMaXN0ZW5lciB0byBhZGQKKyAgICogYW5vdGhlciBsaXN0ZW5lciB3b3VsZCBiZSBuby1vcC4KKyAgICoKKyAgICogQHBhcmFtIGdyb3VwTmFtZSBUaGUgZ3JvdXBOYW1lIHRoYXQgdGhlIERvd25sb2FkTGlzdGVuZXIgd2lsbCByZWNlaXZlIGRvd25sb2FkIHByb2dyZXNzIHVwZGF0ZS4KKyAgICogQHBhcmFtIGRvd25sb2FkTGlzdGVuZXIgdGhlIERvd25sb2FkTGlzdGVuZXIgdG8gYWRkLgorICAgKi8KKyAgcHVibGljIHZvaWQgYWRkRG93bmxvYWRMaXN0ZW5lcihTdHJpbmcgZ3JvdXBOYW1lLCBEb3dubG9hZExpc3RlbmVyIGRvd25sb2FkTGlzdGVuZXIpIHsKKyAgICBzeW5jaHJvbml6ZWQgKERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmNsYXNzKSB7CisgICAgICBpZiAoIWZpbGVHcm91cFRvQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvci5jb250YWluc0tleShncm91cE5hbWUpKSB7CisgICAgICAgIGZpbGVHcm91cFRvQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvci5wdXQoCisgICAgICAgICAgICBncm91cE5hbWUsCisgICAgICAgICAgICBuZXcgQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvcigKKyAgICAgICAgICAgICAgICBuZXcgRG93bmxvYWRlZEJ5dGVzQ291bnRlcihncm91cE5hbWUsIGRvd25sb2FkTGlzdGVuZXIpLAorICAgICAgICAgICAgICAgIHRpbWVTb3VyY2U6OmN1cnJlbnRUaW1lTWlsbGlzLAorICAgICAgICAgICAgICAgIExPR19GUkVRVUVOQ1ksCisgICAgICAgICAgICAgICAgVGltZVVuaXQuTUlMTElTRUNPTkRTKSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEFkZCBhIFNpbmdsZSBGaWxlIERvd25sb2FkTGlzdGVuZXIuCisgICAqCisgICAqIDxwPlRoaXMgbGlzdGVuZXIgYWxsb3dzIGNsaWVudHMgdG8gcmVjZWl2ZSBvbiBwcm9ncmVzcyB1cGRhdGVzIGZvciBzaW5nbGUgZmlsZSBkb3dubG9hZHMuCisgICAqCisgICAqIEBwYXJhbSB1cmkgdGhlIHVyaSBmb3Igd2hpY2ggdGhlIERvd25sb2FkTGlzdGVuZXIgc2hvdWxkIHJlY2VpdmUgdXBkYXRlcworICAgKiBAcGFyYW0gZG93bmxvYWRMaXN0ZW5lciB0aGUgTUREIExpdGUgRG93bmxvYWRMaXN0ZW5lciB0byBhZGQKKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBhZGREb3dubG9hZExpc3RlbmVyKAorICAgICAgVXJpIHVyaSwKKyAgICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmxpdGUuRG93bmxvYWRMaXN0ZW5lciBkb3dubG9hZExpc3RlbmVyKSB7CisgICAgbGl0ZURvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmFkZERvd25sb2FkTGlzdGVuZXIodXJpLCBkb3dubG9hZExpc3RlbmVyKTsKKyAgfQorCisgIC8qKgorICAgKiBSZW1vdmUgYSBGaWxlIEdyb3VwIERvd25sb2FkTGlzdGVuZXIuCisgICAqCisgICAqIEBwYXJhbSBncm91cE5hbWUgVGhlIGdyb3VwTmFtZSB0aGF0IHRoZSBEb3dubG9hZExpc3RlbmVyIHJlY2VpdmUgZG93bmxvYWQgcHJvZ3Jlc3MgdXBkYXRlLgorICAgKi8KKyAgcHVibGljIHZvaWQgcmVtb3ZlRG93bmxvYWRMaXN0ZW5lcihTdHJpbmcgZ3JvdXBOYW1lKSB7CisgICAgc3luY2hyb25pemVkIChEb3dubG9hZFByb2dyZXNzTW9uaXRvci5jbGFzcykgeworICAgICAgZmlsZUdyb3VwVG9CeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yLnJlbW92ZShncm91cE5hbWUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBSZW1vdmUgYSBTaW5nbGUgRmlsZSBEb3dubG9hZExpc3RlbmVyLgorICAgKgorICAgKiBAcGFyYW0gdXJpIHRoZSB1cmkgd2hpY2ggc2hvdWxkIGJlIGNsZWFyZWQgb2YgYW55IHJlZ2lzdGVyZWQgRG93bmxvYWRMaXN0ZW5lcgorICAgKi8KKyAgQE92ZXJyaWRlCisgIHB1YmxpYyB2b2lkIHJlbW92ZURvd25sb2FkTGlzdGVuZXIoVXJpIHVyaSkgeworICAgIGxpdGVEb3dubG9hZFByb2dyZXNzTW9uaXRvci5yZW1vdmVEb3dubG9hZExpc3RlbmVyKHVyaSk7CisgIH0KKworICAvKioKKyAgICogUmVjb3JkIHRoYXQgdGhlIFVyaSBiZWxvbmcgdG8gdGhlIEZpbGVHcm91cCByZXByZXNlbnRlZCBieSBncm91cE5hbWUuIFdlIG5lZWQgdG8gcmVjb3JkIHRoaXMgYXQKKyAgICogZG93bmxvYWRpbmcgdGltZSBzaW5jZSB0aGUgZmlsZXMgaW4gRmlsZUdyb3VwIGNvdWxkIGNoYW5nZSBkdWUgdG8gY29uZmlnIGNoYW5nZS4gbW9uaXRvclVyaQorICAgKiBzaG91bGQgb25seSBiZSBjYWxsZWQgZm9yIGZpbGVzIHRoYXQgaGF2ZSBub3QgYmVlbiBkb3dubG9hZGVkLgorICAgKgorICAgKiBAcGFyYW0gdXJpIHRoZSBGaWxlVXJpIHRvIGJlIG1vbml0b3JlZC4KKyAgICogQHBhcmFtIGdyb3VwTmFtZSB0aGUgZ3JvdXAgbmFtZSB0byBiZSBtb25pdG9yZWQuCisgICAqLworICBwdWJsaWMgdm9pZCBtb25pdG9yVXJpKFVyaSB1cmksIFN0cmluZyBncm91cE5hbWUpIHsKKyAgICBzeW5jaHJvbml6ZWQgKERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLmNsYXNzKSB7CisgICAgICB1cmlUb0ZpbGVHcm91cC5wdXQodXJpLCBncm91cE5hbWUpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBBZGQgdGhlIGN1cnJlbnQgc2l6ZSBvZiBhIGRvd25sb2FkZWQgb3IgcGFydGlhbGx5IGRvd25sb2FkZWQgZmlsZSB0byBhIGZpbGUgZ3JvdXAgY291bnRlci4KKyAgICoKKyAgICogQHBhcmFtIGdyb3VwTmFtZSB0aGUgZ3JvdXAgbmFtZSB0byBhZGQgdGhlIGN1cnJlbnQgc2l6ZS4KKyAgICogQHBhcmFtIGN1cnJlbnRTaXplIHRoZSBjdXJyZW50IHNpemUgb2YgdGhlIGZpbGUuCisgICAqLworICBwdWJsaWMgdm9pZCBub3RpZnlDdXJyZW50RmlsZVNpemUoU3RyaW5nIGdyb3VwTmFtZSwgbG9uZyBjdXJyZW50U2l6ZSkgeworICAgIHN5bmNocm9uaXplZCAoRG93bmxvYWRQcm9ncmVzc01vbml0b3IuY2xhc3MpIHsKKyAgICAgIC8vIFVwZGF0ZSB0aGUgY291bnRlciB3aXRoIHRoZSBjdXJyZW50IHNpemUuCisgICAgICBpZiAoZmlsZUdyb3VwVG9CeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yLmNvbnRhaW5zS2V5KGdyb3VwTmFtZSkpIHsKKyAgICAgICAgZmlsZUdyb3VwVG9CeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yCisgICAgICAgICAgICAuZ2V0KGdyb3VwTmFtZSkKKyAgICAgICAgICAgIC5nZXRDb3VudGVyKCkKKyAgICAgICAgICAgIC5idWZmZXJDb3VudGVyKChpbnQpIGN1cnJlbnRTaXplKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBBIGNvdW50ZXIgZm9yIGJ5dGVzIGRvd25sb2FkZWQuCisgIHByaXZhdGUgZmluYWwgY2xhc3MgRG93bmxvYWRlZEJ5dGVzQ291bnRlciBpbXBsZW1lbnRzIEJ5dGVDb3VudGluZ091dHB1dE1vbml0b3IuQ291bnRlciB7CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgZ3JvdXBOYW1lOworICAgIHByaXZhdGUgZmluYWwgRG93bmxvYWRMaXN0ZW5lciBkb3dubG9hZExpc3RlbmVyOworCisgICAgcHJpdmF0ZSBmaW5hbCBBdG9taWNMb25nIGJ5dGVDb3VudGVyID0gbmV3IEF0b21pY0xvbmcoKTsKKworICAgIERvd25sb2FkZWRCeXRlc0NvdW50ZXIoU3RyaW5nIGdyb3VwTmFtZSwgRG93bmxvYWRMaXN0ZW5lciBkb3dubG9hZExpc3RlbmVyKSB7CisgICAgICB0aGlzLmdyb3VwTmFtZSA9IGdyb3VwTmFtZTsKKyAgICAgIHRoaXMuZG93bmxvYWRMaXN0ZW5lciA9IGRvd25sb2FkTGlzdGVuZXI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYnVmZmVyQ291bnRlcihpbnQgbGVuKSB7CisgICAgICBieXRlQ291bnRlci5nZXRBbmRBZGQobGVuKTsKKyAgICAgIExvZ1V0aWwudigKKyAgICAgICAgICAiJXM6IFJlY2VpdmVkIGRhdGEgZm9yIGdyb3VwTmFtZSA9ICVzLCBsZW4gPSAlZCwgQ291bnRlciA9ICVkIiwKKyAgICAgICAgICBUQUcsIGdyb3VwTmFtZSwgbGVuLCBieXRlQ291bnRlci5nZXQoKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2hDb3VudGVyKCkgeworICAgICAgLy8gQ2hlY2sgaWYgdGhlIERvd25sb2FkTGlzdGVuZXIgaXMgc3RpbGwgYmVpbmcgdXNlZCBiZWZvcmUgY2FsbGluZyBpdHMgb25Qcm9ncmVzcy4KKyAgICAgIHN5bmNocm9uaXplZCAoRG93bmxvYWRQcm9ncmVzc01vbml0b3IuY2xhc3MpIHsKKyAgICAgICAgaWYgKGZpbGVHcm91cFRvQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvci5jb250YWluc0tleShncm91cE5hbWUpKSB7CisgICAgICAgICAgc2VxdWVudGlhbENvbnRyb2xFeGVjdXRvci5leGVjdXRlKCgpIC0+IGRvd25sb2FkTGlzdGVuZXIub25Qcm9ncmVzcyhieXRlQ291bnRlci5nZXQoKSkpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorCisgICAgcHVibGljIHZvaWQgcGF1c2VkRm9yQ29ubmVjdGl2aXR5KCkgeworICAgICAgZG93bmxvYWRMaXN0ZW5lci5wYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvci9OZXR3b3JrVXNhZ2VNb25pdG9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3IvTmV0d29ya1VzYWdlTW9uaXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQxM2EyZDEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3IvTmV0d29ya1VzYWdlTW9uaXRvci5qYXZhCkBAIC0wLDAgKzEsMjU2IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRyYWNpbmcuVHJhY2VQcm9wYWdhdGlvbi5wcm9wYWdhdGVGdXR1cmVDYWxsYmFjazsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3I7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0LlNFQ09ORFM7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Db25uZWN0aXZpdHlNYW5hZ2VyOworaW1wb3J0IGFuZHJvaWQubmV0Lk5ldHdvcmtJbmZvOworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkOworaW1wb3J0IGFuZHJvaWR4LmFubm90YXRpb24uR3VhcmRlZEJ5OworaW1wb3J0IGFuZHJvaWR4LmFubm90YXRpb24uVmlzaWJsZUZvclRlc3Rpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGltZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm1vbml0b3JzLkJ5dGVDb3VudGluZ091dHB1dE1vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dnaW5nU3RhdGVTdG9yZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlQ2FsbGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5GaWxlR3JvdXBMb2dnaW5nU3RhdGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleTsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljTG9uZzsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworCisvKioKKyAqIEEgbmV0d29yayB1c2FnZSBtb25pdG9yIHRoYXQgY291bnRzIGJ5dGVzIGRvd25sb2FkZWQgZm9yIGVhY2ggRmlsZUdyb3VwLiBCZWZvcmUgbW9uaXRvcmluZyBhbgorICogVXJpLCBvbmUgbmVlZHMgdG8gY2FsbCBtb25pdG9yVXJpIHRvIHJlY29yZCB0aGUgZmlsZSBncm91cCB0aGF0IFVyaSBiZWxvbmdzIHRvIGF0IHRoZSBkb3dubG9hZGluZworICogdGltZS4gRmFpbGluZyB0byBkbyBzbyB3aWxsIHJlc3VsdCBpbiBubyBuZXR3b3JrIHVzYWdlIGJlaW5nIGNvdW50ZWQuCisgKi8KK3B1YmxpYyBjbGFzcyBOZXR3b3JrVXNhZ2VNb25pdG9yIGltcGxlbWVudHMgTW9uaXRvciB7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiTmV0d29ya1VzYWdlTW9uaXRvciI7CisKKyAgLy8gV2Ugd2lsbCBvbmx5IGZsdXNoIGNvdW50ZXJzIHRvIFNoYXJlZFByZWZlcmVuY2UgYXQgbW9zdCBvbmNlIGluIHRoaXMgdGltZSBmcmFtZS4KKyAgLy8gMTAgc2Vjb25kcyB3ZXJlIGNob3NlbiBhcmJpdHJhcmlseS4KKyAgQFZpc2libGVGb3JUZXN0aW5nIHN0YXRpYyBmaW5hbCBsb25nIExPR19GUkVRVUVOQ1lfU0VDT05EUyA9IDEwTDsKKworICBwcml2YXRlIGZpbmFsIFRpbWVTb3VyY2UgdGltZVNvdXJjZTsKKyAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisKKyAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgbG9jayA9IG5ldyBPYmplY3QoKTsKKworICAvLyBLZXkgaXMgRmlsZUdyb3VwTG9nZ2luZ1N0YXRlIHdpdGggR3JvdXBLZXksIGJ1aWxkIGlkLCB2ZXJzaW9uIG51bWJlciBwb3B1bGF0ZWQuCisgIEBHdWFyZGVkQnkoImxvY2siKQorICBwcml2YXRlIGZpbmFsIEhhc2hNYXA8RmlsZUdyb3VwTG9nZ2luZ1N0YXRlLCBCeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yPgorICAgICAgZmlsZUdyb3VwTG9nZ2luZ1N0YXRlVG9PdXRwdXRNb25pdG9yID0gbmV3IEhhc2hNYXA8PigpOworCisgIEBHdWFyZGVkQnkoImxvY2siKQorICBwcml2YXRlIGZpbmFsIEhhc2hNYXA8VXJpLCBCeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yPiB1cmlUb091dHB1dE1vbml0b3IgPSBuZXcgSGFzaE1hcDw+KCk7CisKKyAgcHVibGljIE5ldHdvcmtVc2FnZU1vbml0b3IoQ29udGV4dCBjb250ZXh0LCBUaW1lU291cmNlIHRpbWVTb3VyY2UpIHsKKyAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OworICAgIHRoaXMudGltZVNvdXJjZSA9IHRpbWVTb3VyY2U7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgQE51bGxhYmxlCisgIHB1YmxpYyBNb25pdG9yLklucHV0TW9uaXRvciBtb25pdG9yUmVhZChVcmkgdXJpKSB7CisgICAgcmV0dXJuIG51bGw7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgQE51bGxhYmxlCisgIHB1YmxpYyBNb25pdG9yLk91dHB1dE1vbml0b3IgbW9uaXRvcldyaXRlKFVyaSB1cmkpIHsKKyAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgIHJldHVybiB1cmlUb091dHB1dE1vbml0b3IuZ2V0KHVyaSk7CisgICAgfQorICB9CisKKyAgQE92ZXJyaWRlCisgIEBOdWxsYWJsZQorICBwdWJsaWMgTW9uaXRvci5PdXRwdXRNb25pdG9yIG1vbml0b3JBcHBlbmQoVXJpIHVyaSkgeworICAgIHJldHVybiBtb25pdG9yV3JpdGUodXJpKTsKKyAgfQorCisgIC8qKgorICAgKiBSZWNvcmQgdGhhdCB0aGUgVXJpIGJlbG9uZyB0byB0aGUgRmlsZUdyb3VwIHJlcHJlc2VudGVkIGJ5IG93bmVyUGFja2FnZSBhbmQgZ3JvdXBOYW1lLiBXZSBuZWVkCisgICAqIHRvIHJlY29yZCB0aGlzIGF0IGRvd25sb2FkaW5nIHRpbWUgc2luY2UgdGhlIGZpbGVzIGluIEZpbGVHcm91cCBjb3VsZCBjaGFuZ2UgZHVlIHRvIGNvbmZpZworICAgKiBjaGFuZ2UuCisgICAqCisgICAqIEBwYXJhbSB1cmkgVGhlIFVyaSBvZiB0aGUgZGF0YSBmaWxlLgorICAgKiBAcGFyYW0gZ3JvdXBLZXkgVGhlIGdyb3VwS2V5IHBhcnQgb2YgdGhlIGZpbGUgZ3JvdXAuCisgICAqIEBwYXJhbSBidWlsZElkIFRoZSBidWlsZCBpZCBvZiB0aGUgZmlsZSBncm91cC4KKyAgICogQHBhcmFtIHZlcnNpb25OdW1iZXIgVGhlIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBmaWxlIGdyb3VwLgorICAgKiBAcGFyYW0gbG9nZ2luZ1N0YXRlU3RvcmUgVGhlIHN0b3JhZ2UgZm9yIHRoZSBuZXR3b3JrIHVzYWdlIGxvZ3MKKyAgICovCisgIHB1YmxpYyB2b2lkIG1vbml0b3JVcmkoCisgICAgICBVcmkgdXJpLAorICAgICAgR3JvdXBLZXkgZ3JvdXBLZXksCisgICAgICBsb25nIGJ1aWxkSWQsCisgICAgICBpbnQgdmVyc2lvbk51bWJlciwKKyAgICAgIExvZ2dpbmdTdGF0ZVN0b3JlIGxvZ2dpbmdTdGF0ZVN0b3JlKSB7CisgICAgRmlsZUdyb3VwTG9nZ2luZ1N0YXRlIGZpbGVHcm91cExvZ2dpbmdTdGF0ZUtleSA9CisgICAgICAgIEZpbGVHcm91cExvZ2dpbmdTdGF0ZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cEtleShncm91cEtleSkKKyAgICAgICAgICAgIC5zZXRCdWlsZElkKGJ1aWxkSWQpCisgICAgICAgICAgICAuc2V0RmlsZUdyb3VwVmVyc2lvbk51bWJlcih2ZXJzaW9uTnVtYmVyKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBJZiB3ZSBoYXZlbid0IHNlZW4gdGhpcyBmaWxlIGdyb3VwLCBjcmVhdGUgYSBvdXRwdXQgbW9uaXRvciBmb3IgaXQgYW5kIHJlZ2lzdGVyIGl0IHRvIHRoaXMKKyAgICAvLyBmaWxlIGdyb3VwIGtleS4KKyAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgIGlmICghZmlsZUdyb3VwTG9nZ2luZ1N0YXRlVG9PdXRwdXRNb25pdG9yLmNvbnRhaW5zS2V5KGZpbGVHcm91cExvZ2dpbmdTdGF0ZUtleSkpIHsKKyAgICAgICAgZmlsZUdyb3VwTG9nZ2luZ1N0YXRlVG9PdXRwdXRNb25pdG9yLnB1dCgKKyAgICAgICAgICAgIGZpbGVHcm91cExvZ2dpbmdTdGF0ZUtleSwKKyAgICAgICAgICAgIG5ldyBCeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yKAorICAgICAgICAgICAgICAgIG5ldyBEb3dubG9hZGVkQnl0ZXNDb3VudGVyKGNvbnRleHQsIGxvZ2dpbmdTdGF0ZVN0b3JlLCBmaWxlR3JvdXBMb2dnaW5nU3RhdGVLZXkpLAorICAgICAgICAgICAgICAgIHRpbWVTb3VyY2U6OmN1cnJlbnRUaW1lTWlsbGlzLAorICAgICAgICAgICAgICAgIExPR19GUkVRVUVOQ1lfU0VDT05EUywKKyAgICAgICAgICAgICAgICBTRUNPTkRTKSk7CisgICAgICB9CisKKyAgICAgIC8vIFJlZ2lzdGVyIHRoZSBtYXBwaW5nIGZyb20gdGhpcyB1cmkgdG8gdGhlIG91dHB1dCBtb25pdG9yIHdlIGNyZWF0ZWQuCisgICAgICAvLyBOT1RFOiBJdCdzIHBvc3NpYmxlIHRoZSBVUkkgaXMgYXNzb2NpYXRlZCB3aXRoIGFub3RoZXIgbW9uaXRvciBoZXJlIChlLmcuIGlmIGEKKyAgICAgIC8vIHVyaSBpcyBzaGFyZWQgYnkgZmlsZSBncm91cHMpLCBidXQgd2UgZG9uJ3QgaGF2ZSBhIHdheSB0byBkZWR1cGUgdGhhdCBhdCB0aGUgbW9tZW50LCBzbyB3ZQorICAgICAgLy8ganVzdCBvdmVyd3JpdGUgaXQuCisgICAgICB1cmlUb091dHB1dE1vbml0b3IucHV0KAorICAgICAgICAgIHVyaSwgZmlsZUdyb3VwTG9nZ2luZ1N0YXRlVG9PdXRwdXRNb25pdG9yLmdldChmaWxlR3JvdXBMb2dnaW5nU3RhdGVLZXkpKTsKKyAgICB9CisgIH0KKworICAvLyBBIGNvdW50ZXIgZm9yIGJ5dGVzIGRvd25sb2FkZWQgb24gd2lmaSBhbmQgY2VsbHVsYXIuCisgIC8vIEl0IHdpbGwga2VlcCBpbi1tZW1vcnkgY291bnRlcnMgdG8gcmVkdWNlIHRoZSB3cml0ZSB0byBTaGFyZWRQcmVmZXJlbmNlLgorICAvLyBXaGVuIHVwZGF0aW5nIHRoZSBpbi1tZW1vcnkgY291bnRlcnMsIGl0IHdpbGwgb25seSBzYXZlIGFuZCByZXNldCB0aGVtIGlmIHRoZSB0aW1lIHNpbmNlIHRoZQorICAvLyBsYXN0IHNhdmUgaXMgYXQgbGVhc3QgTE9HX0ZSRVFVRU5DWS4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRG93bmxvYWRlZEJ5dGVzQ291bnRlciBpbXBsZW1lbnRzIEJ5dGVDb3VudGluZ091dHB1dE1vbml0b3IuQ291bnRlciB7CisgICAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisgICAgcHJpdmF0ZSBmaW5hbCBMb2dnaW5nU3RhdGVTdG9yZSBsb2dnaW5nU3RhdGVTdG9yZTsKKyAgICBwcml2YXRlIGZpbmFsIEZpbGVHcm91cExvZ2dpbmdTdGF0ZSBmaWxlR3JvdXBMb2dnaW5nU3RhdGVLZXk7CisKKyAgICAvLyBJbi1tZW1vcnkgY291bnRlcnMgYmVmb3JlIHNhdmluZyB0byBTaGFyZWRQcmVmZXJlbmNlLgorICAgIHByaXZhdGUgZmluYWwgQXRvbWljTG9uZyB3aWZpQ291bnRlciA9IG5ldyBBdG9taWNMb25nKCk7CisgICAgcHJpdmF0ZSBmaW5hbCBBdG9taWNMb25nIGNlbGx1bGFyQ291bnRlciA9IG5ldyBBdG9taWNMb25nKCk7CisKKyAgICBEb3dubG9hZGVkQnl0ZXNDb3VudGVyKAorICAgICAgICBDb250ZXh0IGNvbnRleHQsCisgICAgICAgIExvZ2dpbmdTdGF0ZVN0b3JlIGxvZ2dpbmdTdGF0ZVN0b3JlLAorICAgICAgICBGaWxlR3JvdXBMb2dnaW5nU3RhdGUgZmlsZUdyb3VwTG9nZ2luZ1N0YXRlS2V5KSB7CisgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OworICAgICAgdGhpcy5sb2dnaW5nU3RhdGVTdG9yZSA9IGxvZ2dpbmdTdGF0ZVN0b3JlOworICAgICAgdGhpcy5maWxlR3JvdXBMb2dnaW5nU3RhdGVLZXkgPSBmaWxlR3JvdXBMb2dnaW5nU3RhdGVLZXk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYnVmZmVyQ291bnRlcihpbnQgbGVuKSB7CisKKyAgICAgIGJvb2xlYW4gaXNDZWxsdWxhciA9IGlzQ2VsbHVsYXIoY29udGV4dCk7CisKKyAgICAgIGlmIChpc0NlbGx1bGFyKSB7CisgICAgICAgIGNlbGx1bGFyQ291bnRlci5nZXRBbmRBZGQobGVuKTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIHdpZmlDb3VudGVyLmdldEFuZEFkZChsZW4pOworICAgICAgfQorCisgICAgICBMb2dVdGlsLnYoCisgICAgICAgICAgIiVzOiBSZWNlaXZlZCBkYXRhICglcykgZm9yIGZpbGVHcm91cCA9ICVzLCBsZW4gPSAlZCwgd2lmaUNvdW50ZXIgPSAlZCwiCisgICAgICAgICAgICAgICsgIiBjZWxsdWxhckNvdW50ZXIgPSAlZCIsCisgICAgICAgICAgVEFHLAorICAgICAgICAgIGlzQ2VsbHVsYXIgPyAiY2VsbHVsYXIiIDogIndpZmkiLAorICAgICAgICAgIGZpbGVHcm91cExvZ2dpbmdTdGF0ZUtleS5nZXRHcm91cEtleSgpLmdldEdyb3VwTmFtZSgpLAorICAgICAgICAgIGxlbiwKKyAgICAgICAgICB3aWZpQ291bnRlci5nZXQoKSwKKyAgICAgICAgICBjZWxsdWxhckNvdW50ZXIuZ2V0KCkpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGZsdXNoQ291bnRlcigpIHsKKyAgICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gaW5jcmVtZW50RGF0YVVzYWdlID0KKyAgICAgICAgICBsb2dnaW5nU3RhdGVTdG9yZS5pbmNyZW1lbnREYXRhVXNhZ2UoCisgICAgICAgICAgICAgIGZpbGVHcm91cExvZ2dpbmdTdGF0ZUtleS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgLnNldENlbGx1bGFyVXNhZ2UoY2VsbHVsYXJDb3VudGVyLmdldEFuZFNldCgwKSkKKyAgICAgICAgICAgICAgICAgIC5zZXRXaWZpVXNhZ2Uod2lmaUNvdW50ZXIuZ2V0QW5kU2V0KDApKQorICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworCisgICAgICBGdXR1cmVzLmFkZENhbGxiYWNrKAorICAgICAgICAgIGluY3JlbWVudERhdGFVc2FnZSwKKyAgICAgICAgICBwcm9wYWdhdGVGdXR1cmVDYWxsYmFjaygKKyAgICAgICAgICAgICAgbmV3IEZ1dHVyZUNhbGxiYWNrPFZvaWQ+KCkgeworICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uU3VjY2VzcyhWb2lkIHVudXNlZCkgeworICAgICAgICAgICAgICAgICAgTG9nVXRpbC5kKAorICAgICAgICAgICAgICAgICAgICAgICIlczogU3VjY2Vzc2Z1bGx5IGluY3JlbWVudGVkIExvZ2dpbmdTdGF0ZVN0b3JlIG5ldHdvcmsgdXNhZ2UgZm9yICVzIiwKKyAgICAgICAgICAgICAgICAgICAgICBUQUcsIGZpbGVHcm91cExvZ2dpbmdTdGF0ZUtleS5nZXRHcm91cEtleSgpLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkZhaWx1cmUoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZSgKKyAgICAgICAgICAgICAgICAgICAgICB0LAorICAgICAgICAgICAgICAgICAgICAgICIlczogVW5hYmxlIHRvIGluY3JlbWVudCBMb2dnaW5nU3RhdGVTdG9yZSBuZXR3b3JrIHVzYWdlIGZvciAlcyIsCisgICAgICAgICAgICAgICAgICAgICAgVEFHLAorICAgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cExvZ2dpbmdTdGF0ZUtleS5nZXRHcm91cEtleSgpLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIH0pLAorICAgICAgICAgIGRpcmVjdEV4ZWN1dG9yKCkpOworICAgIH0KKyAgfQorCisgIEBOdWxsYWJsZQorICBwdWJsaWMgc3RhdGljIENvbm5lY3Rpdml0eU1hbmFnZXIgZ2V0Q29ubmVjdGl2aXR5TWFuYWdlcihDb250ZXh0IGNvbnRleHQpIHsKKyAgICB0cnkgeworICAgICAgcmV0dXJuIChDb25uZWN0aXZpdHlNYW5hZ2VyKSBjb250ZXh0LmdldFN5c3RlbVNlcnZpY2UoQ29udGV4dC5DT05ORUNUSVZJVFlfU0VSVklDRSk7CisgICAgfSBjYXRjaCAoU2VjdXJpdHlFeGNlcHRpb24gZSkgeworICAgICAgTG9nVXRpbC5lKCIlczogQ291bGRuJ3QgcmV0cmlldmUgQ29ubmVjdGl2aXR5TWFuYWdlci4iLCBUQUcpOworICAgIH0KKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIEBOdWxsYWJsZQorICBwdWJsaWMgc3RhdGljIE5ldHdvcmtJbmZvIGdldEFjdGl2ZU5ldHdvcmtJbmZvKENvbnRleHQgY29udGV4dCkgeworICAgIENvbm5lY3Rpdml0eU1hbmFnZXIgY20gPSBnZXRDb25uZWN0aXZpdHlNYW5hZ2VyKGNvbnRleHQpOworICAgIHJldHVybiAoY20gPT0gbnVsbCkgPyBudWxsIDogY20uZ2V0QWN0aXZlTmV0d29ya0luZm8oKTsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnJlbnQgbmV0d29yayBjb25uZWN0aXZpdHkgdHlwZSBpcyBjZWxsdWxhci4gSWYgdGhlIG5ldHdvcmsgY29ubmVjdGl2aXR5CisgICAqIHR5cGUgaXMgbm90IGNlbGx1bGFyIG9yIGlmIHRoZXJlIGlzIGFuIGVycm9yIGluIGdldHRpbmcgTmV0d29ya0luZm8gcmV0dXJuIGZhbHNlLgorICAgKgorICAgKiA8cD5UaGUgbG9naWMgaGVyZSBpcyBzaW1pbGFyIHRvIE9mZnJvYWREb3dubG9hZGVyLgorICAgKi8KKyAgQFZpc2libGVGb3JUZXN0aW5nCisgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0NlbGx1bGFyKENvbnRleHQgY29udGV4dCkgeworICAgIE5ldHdvcmtJbmZvIG5ldHdvcmtJbmZvID0gZ2V0QWN0aXZlTmV0d29ya0luZm8oY29udGV4dCk7CisgICAgaWYgKG5ldHdvcmtJbmZvID09IG51bGwpIHsKKyAgICAgIExvZ1V0aWwuZSgiJXM6IEZhaWwgdG8gZ2V0IG5ldHdvcmsgdHlwZSAiLCBUQUcpOworICAgICAgLy8gV2UgcmV0dXJuIGZhbHNlIHdoZW4gd2UgZmFpbCB0byBnZXQgTmV0d29ya0luZm8uCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgaWYgKChuZXR3b3JrSW5mby5nZXRUeXBlKCkgPT0gQ29ubmVjdGl2aXR5TWFuYWdlci5UWVBFX1dJRkkKKyAgICAgICAgfHwgbmV0d29ya0luZm8uZ2V0VHlwZSgpID09IENvbm5lY3Rpdml0eU1hbmFnZXIuVFlQRV9FVEhFUk5FVAorICAgICAgICB8fCAoQnVpbGQuVkVSU0lPTi5TREtfSU5UID49IEJ1aWxkLlZFUlNJT05fQ09ERVMuTE9MTElQT1AKKyAgICAgICAgICAgICYmIG5ldHdvcmtJbmZvLmdldFR5cGUoKSA9PSBDb25uZWN0aXZpdHlNYW5hZ2VyLlRZUEVfVlBOKSkpIHsKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9IGVsc2UgeworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQyZjdlNzMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9CVUlMRApAQCAtMCwwICsxLDE4OSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWworICAgICAgICAiLy92aXNpYmlsaXR5OnB1YmxpYyIsCisgICAgXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkRhdGFGaWxlR3JvdXBPdmVycmlkZXIiLAorICAgIHNyY3MgPSBbIkRhdGFGaWxlR3JvdXBPdmVycmlkZXIuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL3Byb3RvOmRvd25sb2FkX2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIlNpbmdsZURhdGFGaWxlR3JvdXBQb3B1bGF0b3IiLAorICAgIHNyY3MgPSBbIlNpbmdsZURhdGFGaWxlR3JvdXBQb3B1bGF0b3IuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6RGF0YUZpbGVHcm91cE92ZXJyaWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICIvL3Byb3RvOmRvd25sb2FkX2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk1pZ3JhdGlvblByb3h5UG9wdWxhdG9yIiwKKyAgICBzcmNzID0gWyJNaWdyYXRpb25Qcm94eVBvcHVsYXRvci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiTG9jYXRpb25Qcm92aWRlciIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkxvY2F0aW9uUHJvdmlkZXIuamF2YSIsCisgICAgICAgICJMb2NhdGlvblByb3ZpZGVySW1wbC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6TG9jYXRpb25Qcm92aWRlck92ZXJyaWRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hbm5vdGF0aW9ucyIsCisgICAgICAgICJAYW5kcm9pZHhfYXBwY29tcGF0X2FwcGNvbXBhdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9kYWdnZXIiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkxvY2F0aW9uUHJvdmlkZXJPdmVycmlkZSIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkxvY2F0aW9uUHJvdmlkZXJPdmVycmlkZS5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICJAamF2YXhfaW5qZWN0IiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJNYW5pZmVzdENvbmZpZ0hlbHBlciIsCisgICAgc3JjcyA9IFsiTWFuaWZlc3RDb25maWdIZWxwZXIuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6TWFuaWZlc3RDb25maWdPdmVycmlkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nOmNvbmN1cnJlbnQiLAorICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk1hbmlmZXN0Q29uZmlnT3ZlcnJpZGVyIiwKKyAgICBzcmNzID0gWyJNYW5pZmVzdENvbmZpZ092ZXJyaWRlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vcHJvdG86ZG93bmxvYWRfY29uZmlnX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiTWFuaWZlc3RDb25maWdGbGFnUG9wdWxhdG9yIiwKKyAgICBzcmNzID0gWyJNYW5pZmVzdENvbmZpZ0ZsYWdQb3B1bGF0b3IuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6TWFuaWZlc3RDb25maWdIZWxwZXIiLAorICAgICAgICAiOk1hbmlmZXN0Q29uZmlnT3ZlcnJpZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIi8vcHJvdG86ZG93bmxvYWRfY29uZmlnX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiTWFuaWZlc3RGaWxlR3JvdXBQb3B1bGF0b3IiLAorICAgIHNyY3MgPSBbIk1hbmlmZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOk1hbmlmZXN0Q29uZmlnSGVscGVyIiwKKyAgICAgICAgIjpNYW5pZmVzdENvbmZpZ092ZXJyaWRlciIsCisgICAgICAgICI6TWFuaWZlc3RGaWxlTWV0YWRhdGFTdG9yZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkFnZ3JlZ2F0ZUV4Y2VwdGlvbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXI6RmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpEaXJlY3RvcnlVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9sb2dnZXI6RmlsZUdyb3VwUG9wdWxhdG9yTG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nOmNvbmN1cnJlbnQiLAorICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkeF9hbm5vdGF0aW9uX2Fubm90YXRpb24iLAorICAgICAgICAiQGNvbV9nb29nbGVfY29kZV9maW5kYnVnc19qc3IzMDUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGphdmF4X2luamVjdCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiTWFuaWZlc3RGaWxlTWV0YWRhdGFTdG9yZSIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIk1hbmlmZXN0RmlsZU1ldGFkYXRhU3RvcmUuamF2YSIsCisgICAgXSwKKyAgICAjIERPIE5PVCBBREQgVklTSUJJTElUWTogdGhpcyBpc24ndCBhbiBvcGVuIGludGVyZmFjZSBmb3IgY2xpZW50cyB0byBpbXBsZW1lbnQuCisgICAgdmlzaWJpbGl0eSA9IFsiLy92aXNpYmlsaXR5OnByaXZhdGUiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIlNoYXJlZFByZWZlcmVuY2VzTWFuaWZlc3RGaWxlTWV0YWRhdGEiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJTaGFyZWRQcmVmZXJlbmNlc01hbmlmZXN0RmlsZU1ldGFkYXRhLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpNYW5pZmVzdEZpbGVNZXRhZGF0YVN0b3JlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOlNoYXJlZFByZWZlcmVuY2VzVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZzpjb25jdXJyZW50IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJMb2NhbGVPdmVycmlkZXIiLAorICAgIHNyY3MgPSBbIkxvY2FsZU92ZXJyaWRlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpNYW5pZmVzdENvbmZpZ092ZXJyaWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nOmNvbmN1cnJlbnQiLAorICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJNaWdyYXRpb25Qcm94eUxvY2FsZU92ZXJyaWRlciIsCisgICAgc3JjcyA9IFsiTWlncmF0aW9uUHJveHlMb2NhbGVPdmVycmlkZXIuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6TG9jYWxlT3ZlcnJpZGVyIiwKKyAgICAgICAgIjpNYW5pZmVzdENvbmZpZ092ZXJyaWRlciIsCisgICAgICAgICIvL3Byb3RvOmRvd25sb2FkX2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9EYXRhRmlsZUdyb3VwT3ZlcnJpZGVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9EYXRhRmlsZUdyb3VwT3ZlcnJpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWE1NDhlZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0RhdGFGaWxlR3JvdXBPdmVycmlkZXIuamF2YQpAQCAtMCwwICsxLDMyIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5wb3B1bGF0b3I7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKKworLyoqCisgKiBDbGllbnQgcHJvdmlkZWQgb3ZlcnJpZGVyIHdoaWNoIG9wdGlvbmFsbHkgb3ZlcnJpZGVzIGEge0BsaW5rIERhdGFGaWxlR3JvdXB9LgorICoKKyAqIDxwPlRoaXMgY291bGQgYmUgdXNlZCB0byBhbHRlciB0aGUgaW5wdXQgZGF0YUZpbGVHcm91cCBvciBkcm9wIHRoZSBkYXRhRmlsZUdyb3VwIGFsdG9nZXRoZXIuCisgKiBEcm9wcGluZyBoZXJlIGNvdWxkIGJlIHVzZWQgZm9yIG9uIGRldmljZSB0YXJnZXRpbmcuCisgKi8KK3B1YmxpYyBpbnRlcmZhY2UgRGF0YUZpbGVHcm91cE92ZXJyaWRlciB7CisKKyAgLyoqIE92ZXJyaWRlcyB0aGUgaW5wdXQge0BsaW5rIERhdGFGaWxlR3JvdXB9LiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPE9wdGlvbmFsPERhdGFGaWxlR3JvdXA+PiBvdmVycmlkZShEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXApOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTG9jYWxlT3ZlcnJpZGVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9Mb2NhbGVPdmVycmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOTg1Y2FhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTG9jYWxlT3ZlcnJpZGVyLmphdmEKQEAgLTAsMCArMSwyMTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnBvcHVsYXRvcjsKKworaW1wb3J0IHN0YXRpYyBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnMuZ3JvdXBpbmdCeTsKK2ltcG9ydCBzdGF0aWMgamF2YS51dGlsLnN0cmVhbS5Db2xsZWN0b3JzLm1hcHBpbmc7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5zdHJlYW0uQ29sbGVjdG9ycy50b0NvbGxlY3Rpb247CisKK2ltcG9ydCBhbmRyb2lkLmFubm90YXRpb24uVGFyZ2V0QXBpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlByb3BhZ2F0ZWRGdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5QcmVjb25kaXRpb25zOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuU3VwcGxpZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZUdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uTWFuaWZlc3RDb25maWc7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLlNldDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuZnVuY3Rpb24uQmlGdW5jdGlvbjsKKworLyoqCisgKiBBbiBPdmVycmlkZXIgdGhhdCBmaW5kcyBtYXRjaGluZyB7QGxpbmsgRGF0YUZpbGVHcm91cH0gd2l0aGluIHtAbGluayBNYW5pZmVzdENvbmZpZ30gYmFzZWQgb24KKyAqIHN1cHBsaWVkIGxvY2FsZS4KKyAqCisgKiA8cD5XZSB3aWxsIGZpcnN0IGdyb3VwIHRoZSB7QGxpbmsgRGF0YUZpbGVHcm91cH0gYnkge0Bjb2RlIGdyb3VwX25hbWV9LCB0aGVuIGFwcGx5IHtAY29kZQorICogbWF0Y2hTdHJhdGVneX0gdG8gZ2V0IDAgb3IgMSB7QGxpbmsgRGF0YUZpbGVHcm91cH0gZm9yIGVhY2ggb2YgdGhlIGdyb3VwLCB0aGVuIGNvbWJpbmUgdGhlbSBhbmQKKyAqIHJldHVybnMgYSBsaXN0LgorICoKKyAqIDxwPntAY29kZSBsb2NhbGVTdXBwbGllcn0gc3VwcGxpZXMgdGhlIGxvY2FsZSB0byBnZXQgbWF0Y2hlcworICoKKyAqIDxwPk5PVEU6IEJ5IGRlZmF1bHQgd2UgdXNlIHtAbGluayBMT0NBTEVfTUFUQ0hFUl9TVFJBVEVHWX0sIHdoaWNoIGNvdWxkIGZhbGxiYWNrIHRvIGEgZGlmZmVyZW50CisgKiBsb2NhbGUgdG8gc3VwcGxpZWQgb25lLgorICoKKyAqIDxwPldBUk5JTkc6IEl0J3MgVU5ERUZJTkVEIGJlaGF2aW9yIGlmIG1vcmUgdGhhbiBvbmUge2xvY2FsZSwgZ3JvdXBfbmFtZX0gcGFpciBleGlzdHMuCisgKi8KK0BUYXJnZXRBcGkoMjQpCitAU3VwcHJlc3NXYXJuaW5ncygiQW5kcm9pZEpka0xpYnNDaGVja2VyIikKK3B1YmxpYyBmaW5hbCBjbGFzcyBMb2NhbGVPdmVycmlkZXIgaW1wbGVtZW50cyBNYW5pZmVzdENvbmZpZ092ZXJyaWRlciB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJMb2NhbGVPdmVycmlkZXIiOworCisgIC8qKiBCdWlsZGVyIGZvciB7QGxpbmsgRmlsdGVyaW5nUG9wdWxhdG9yfS4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIHsKKworICAgIHByaXZhdGUgU3VwcGxpZXI8TGlzdGVuYWJsZUZ1dHVyZTxMb2NhbGU+PiBsb2NhbGVTdXBwbGllcjsKKyAgICBwcml2YXRlIEJpRnVuY3Rpb248TG9jYWxlLCBTZXQ8TG9jYWxlPiwgT3B0aW9uYWw8TG9jYWxlPj4gbWF0Y2hTdHJhdGVneTsKKyAgICBwcml2YXRlIEV4ZWN1dG9yIGxpZ2h0d2VpZ2h0RXhlY3V0b3I7CisKKyAgICAvKiogb25seSBvbmUgb2Ygc2V0TG9jYWxlU3VwcGxpZXIgb3Igc2V0TG9jYWxlRnV0dXJlU3VwcGxpZXIgaXMgcmVxdWlyZWQgKi8KKyAgICBwdWJsaWMgQnVpbGRlciBzZXRMb2NhbGVTdXBwbGllcihTdXBwbGllcjxMb2NhbGU+IGxvY2FsZVN1cHBsaWVyKSB7CisgICAgICB0aGlzLmxvY2FsZVN1cHBsaWVyID0gKCkgLT4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobG9jYWxlU3VwcGxpZXIuZ2V0KCkpOworICAgICAgdGhpcy5saWdodHdlaWdodEV4ZWN1dG9yID0KKyAgICAgICAgICBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCk7IC8vIHVzZSBkaXJlY3RFeGVjdXRvciBpZiBsb2NhbGUgaXMgcHJvdmlkZWQgc3luYy4KKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyIHNldExvY2FsZUZ1dHVyZVN1cHBsaWVyKAorICAgICAgICBTdXBwbGllcjxMaXN0ZW5hYmxlRnV0dXJlPExvY2FsZT4+IGxvY2FsZVN1cHBsaWVyLCBFeGVjdXRvciBsaWdodHdlaWdodEV4ZWN1dG9yKSB7CisgICAgICB0aGlzLmxvY2FsZVN1cHBsaWVyID0gbG9jYWxlU3VwcGxpZXI7CisgICAgICB0aGlzLmxpZ2h0d2VpZ2h0RXhlY3V0b3IgPSBsaWdodHdlaWdodEV4ZWN1dG9yOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQSBmdW5jdGlvbiB0aGF0IGRlY2lkZXMgYSBtYXRjaCBiYXNlZCBvbiBwcm92aWRlZCBMb2NhbGUgYW5kIGEgc2V0IG9mIGF2YWlsYWJsZSBMb2NhbGVzIGluCisgICAgICogdGhlIGNvbmZpZy4gVGhlIHNldCBvZiBMb2NhbGUgc2hvdWxkIGJlIHJlbGF0ZWQgdG8gT05FIHtAY29kZSBncm91cF9uYW1lfSBvZiB7QGxpbmsKKyAgICAgKiBEYXRhRmlsZWdyb3VwfS4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVpbGRlciBzZXRNYXRjaFN0cmF0ZWd5KAorICAgICAgICBCaUZ1bmN0aW9uPExvY2FsZSwgU2V0PExvY2FsZT4sIE9wdGlvbmFsPExvY2FsZT4+IG1hdGNoU3RyYXRlZ3kpIHsKKyAgICAgIHRoaXMubWF0Y2hTdHJhdGVneSA9IG1hdGNoU3RyYXRlZ3k7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgTG9jYWxlT3ZlcnJpZGVyIGJ1aWxkKCkgeworICAgICAgUHJlY29uZGl0aW9ucy5jaGVja1N0YXRlKAorICAgICAgICAgIGxvY2FsZVN1cHBsaWVyICE9IG51bGwsCisgICAgICAgICAgIk11c3QgY2FsbCBzZXRMb2NhbGVTdXBwbGllcigpIG9yIHNldExvY2FsZUZ1dHVyZVN1cHBsaWVyKCkgYmVmb3JlIGJ1aWxkKCkuIik7CisgICAgICBpZiAobWF0Y2hTdHJhdGVneSA9PSBudWxsKSB7CisgICAgICAgIExvZ1V0aWwuZCgiJXM6IEFwcGx5aW5nIExBTkdfRkFMTEJBQ0tfU1RSQVRFR1kiLCBUQUcpOworICAgICAgICBtYXRjaFN0cmF0ZWd5ID0gTEFOR19GQUxMQkFDS19TVFJBVEVHWTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIG5ldyBMb2NhbGVPdmVycmlkZXIodGhpcyk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBmaW5hbCBTdXBwbGllcjxMaXN0ZW5hYmxlRnV0dXJlPExvY2FsZT4+IGxvY2FsZVN1cHBsaWVyOworICBwcml2YXRlIGZpbmFsIEJpRnVuY3Rpb248TG9jYWxlLCBTZXQ8TG9jYWxlPiwgT3B0aW9uYWw8TG9jYWxlPj4gbWF0Y2hTdHJhdGVneTsKKyAgcHJpdmF0ZSBmaW5hbCBFeGVjdXRvciBsaWdodHdlaWdodEV4ZWN1dG9yOworCisgIC8qKiBSZXR1cm5zIGEgQnVpbGRlciBmb3Ige0BsaW5rIExvY2FsZU92ZXJyaWRlcn0uICovCisgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBidWlsZGVyKCkgeworICAgIHJldHVybiBuZXcgQnVpbGRlcigpOworICB9CisKKyAgcHJpdmF0ZSBMb2NhbGVPdmVycmlkZXIoQnVpbGRlciBidWlsZGVyKSB7CisgICAgdGhpcy5sb2NhbGVTdXBwbGllciA9IGJ1aWxkZXIubG9jYWxlU3VwcGxpZXI7CisgICAgdGhpcy5tYXRjaFN0cmF0ZWd5ID0gYnVpbGRlci5tYXRjaFN0cmF0ZWd5OworICAgIHRoaXMubGlnaHR3ZWlnaHRFeGVjdXRvciA9IGJ1aWxkZXIubGlnaHR3ZWlnaHRFeGVjdXRvcjsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgTG9jYWxlfSBpZiBpdCdzIHByZXNlbnQgaW4ge0BsaW5rIFNldDxMb2NhbGU+fSwgb3Ige0BsaW5rIE9wdGlvbmFsI2Fic2VudH0KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgZmluYWwgQmlGdW5jdGlvbjxMb2NhbGUsIFNldDxMb2NhbGU+LCBPcHRpb25hbDxMb2NhbGU+PiBFUVVBTF9TVFJBVEVHWSA9CisgICAgICAobG9jYWxlLCBsb2NhbGVTZXQpIC0+IGxvY2FsZVNldC5jb250YWlucyhsb2NhbGUpID8gT3B0aW9uYWwub2YobG9jYWxlKSA6IE9wdGlvbmFsLmFic2VudCgpOworCisgIC8qKgorICAgKiBSZXR1cm5zIGFuIGV4YWN0IG1hdGNoaW5nIHtAbGluayBMb2NhbGV9LCBvciBmYWxsYmFjayB0byBvbmx5IG1hdGNoaW5nIGxhbmcgd2hlbiBub3QgYXZhaWxhYmxlLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBCaUZ1bmN0aW9uPExvY2FsZSwgU2V0PExvY2FsZT4sIE9wdGlvbmFsPExvY2FsZT4+IExBTkdfRkFMTEJBQ0tfU1RSQVRFR1kgPQorICAgICAgKGxvY2FsZSwgbG9jYWxlU2V0KSAtPiB7CisgICAgICAgIE9wdGlvbmFsPExvY2FsZT4gZXhhY3RNYXRjaCA9IEVRVUFMX1NUUkFURUdZLmFwcGx5KGxvY2FsZSwgbG9jYWxlU2V0KTsKKyAgICAgICAgaWYgKGV4YWN0TWF0Y2guaXNQcmVzZW50KCkpIHsKKyAgICAgICAgICByZXR1cm4gZXhhY3RNYXRjaDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAvLyBNYXRjaCBvbiBsYW5nIHBhcnQuCisgICAgICAgICAgcmV0dXJuIEVRVUFMX1NUUkFURUdZLmFwcGx5KG5ldyBMb2NhbGUobG9jYWxlLmdldExhbmd1YWdlKCkpLCBsb2NhbGVTZXQpOworICAgICAgICB9CisgICAgICB9OworCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxMaXN0PERhdGFGaWxlR3JvdXA+PiBvdmVycmlkZShNYW5pZmVzdENvbmZpZyBtYW5pZmVzdENvbmZpZykgeworICAgIC8vIEdyb3VwcyBFbnRyaWVzIGJ5IEdyb3VwTmFtZS4KKyAgICBNYXA8U3RyaW5nLCBMaXN0PE1hbmlmZXN0Q29uZmlnLkVudHJ5Pj4gZ3JvdXBUb0VudHJpZXMgPQorICAgICAgICBtYW5pZmVzdENvbmZpZy5nZXRFbnRyeUxpc3QoKS5zdHJlYW0oKQorICAgICAgICAgICAgLmNvbGxlY3QoCisgICAgICAgICAgICAgICAgZ3JvdXBpbmdCeSgKKyAgICAgICAgICAgICAgICAgICAgZW50cnkgLT4gZW50cnkuZ2V0RGF0YUZpbGVHcm91cCgpLmdldEdyb3VwTmFtZSgpLAorICAgICAgICAgICAgICAgICAgICBIYXNoTWFwPFN0cmluZywgTGlzdDxNYW5pZmVzdENvbmZpZy5FbnRyeT4+OjpuZXcsCisgICAgICAgICAgICAgICAgICAgIG1hcHBpbmcoZW50cnkgLT4gZW50cnksIHRvQ29sbGVjdGlvbihBcnJheUxpc3Q8TWFuaWZlc3RDb25maWcuRW50cnk+OjpuZXcpKSkpOworCisgICAgLy8gRmluZHMgYSBEYXRhRmlsZUdyb3VwIGZvciBldmVyeSBHcm91cE5hbWUuCisgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPE9wdGlvbmFsPERhdGFGaWxlR3JvdXA+Pj4gbWF0Y2hlZEZpbGVHcm91cHNGdXR1cmUgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBmb3IgKExpc3Q8TWFuaWZlc3RDb25maWcuRW50cnk+IGVudHJpZXMgOiBncm91cFRvRW50cmllcy52YWx1ZXMoKSkgeworICAgICAgbWF0Y2hlZEZpbGVHcm91cHNGdXR1cmUuYWRkKGdldEZpbGVHcm91cFdpdGhNYXRjaFN0cmF0ZWd5KGVudHJpZXMpKTsKKyAgICB9CisKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtKAorICAgICAgICBGdXR1cmVzLnN1Y2Nlc3NmdWxBc0xpc3QobWF0Y2hlZEZpbGVHcm91cHNGdXR1cmUpLAorICAgICAgICBmaWxlR3JvdXBzIC0+IHsKKyAgICAgICAgICBMaXN0PERhdGFGaWxlR3JvdXA+IG1hdGNoZWRGaWxlR3JvdXBzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgICAgICAgZm9yIChPcHRpb25hbDxEYXRhRmlsZUdyb3VwPiBmaWxlR3JvdXAgOiBmaWxlR3JvdXBzKSB7CisgICAgICAgICAgICBpZiAoZmlsZUdyb3VwICE9IG51bGwgJiYgZmlsZUdyb3VwLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICAgIG1hdGNoZWRGaWxlR3JvdXBzLmFkZChmaWxlR3JvdXAuZ2V0KCkpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gbWF0Y2hlZEZpbGVHcm91cHM7CisgICAgICAgIH0sCisgICAgICAgIGxpZ2h0d2VpZ2h0RXhlY3V0b3IpOworICB9CisKKyAgLyoqIFJldHVybnMgYW4gb3B0aW9uYWwge0BsaW5rIERhdGFGaWxlR3JvdXB9IGJ5IGFwcGx5aW5nIHtAY29kZSBtYXRjaFN0cmF0ZWd5fS4gKi8KKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPE9wdGlvbmFsPERhdGFGaWxlR3JvdXA+PiBnZXRGaWxlR3JvdXBXaXRoTWF0Y2hTdHJhdGVneSgKKyAgICAgIExpc3Q8TWFuaWZlc3RDb25maWcuRW50cnk+IGVudHJpZXMpIHsKKyAgICBNYXA8TG9jYWxlLCBEYXRhRmlsZUdyb3VwPiBsb2NhbGVUb0ZpbGVHcm91cCA9IG5ldyBIYXNoTWFwPD4oKTsKKworICAgIGZvciAoTWFuaWZlc3RDb25maWcuRW50cnkgZW50cnkgOiBlbnRyaWVzKSB7CisgICAgICBmb3IgKFN0cmluZyBsb2NhbGVTdHJpbmcgOiBlbnRyeS5nZXRNb2RpZmllcigpLmdldExvY2FsZUxpc3QoKSkgeworICAgICAgICBEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXA7CisgICAgICAgIGlmIChlbnRyeS5nZXREYXRhRmlsZUdyb3VwKCkuZ2V0TG9jYWxlTGlzdCgpLmNvbnRhaW5zKGxvY2FsZVN0cmluZykpIHsKKyAgICAgICAgICBkYXRhRmlsZUdyb3VwID0gZW50cnkuZ2V0RGF0YUZpbGVHcm91cCgpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGRhdGFGaWxlR3JvdXAgPSBlbnRyeS5nZXREYXRhRmlsZUdyb3VwKCkudG9CdWlsZGVyKCkuYWRkTG9jYWxlKGxvY2FsZVN0cmluZykuYnVpbGQoKTsKKyAgICAgICAgfQorICAgICAgICBsb2NhbGVUb0ZpbGVHcm91cC5wdXQoTG9jYWxlLmZvckxhbmd1YWdlVGFnKGxvY2FsZVN0cmluZyksIGRhdGFGaWxlR3JvdXApOworICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm0oCisgICAgICAgIGxvY2FsZVN1cHBsaWVyLmdldCgpLAorICAgICAgICBsb2NhbGUgLT4geworICAgICAgICAgIE9wdGlvbmFsPExvY2FsZT4gY2hvc2VuTG9jYWxlT3B0aW9uYWwgPQorICAgICAgICAgICAgICBtYXRjaFN0cmF0ZWd5LmFwcGx5KGxvY2FsZSwgbG9jYWxlVG9GaWxlR3JvdXAua2V5U2V0KCkpOworICAgICAgICAgIGlmIChjaG9zZW5Mb2NhbGVPcHRpb25hbC5pc1ByZXNlbnQoKSkgeworICAgICAgICAgICAgTG9jYWxlIGNob3NlbkxvY2FsZSA9IGNob3NlbkxvY2FsZU9wdGlvbmFsLmdldCgpOworICAgICAgICAgICAgTG9nVXRpbC5kKCIlczogY2hvc2VuTG9jYWxlOiAlcyIsIFRBRywgY2hvc2VuTG9jYWxlKTsKKyAgICAgICAgICAgIGlmIChsb2NhbGVUb0ZpbGVHcm91cC5jb250YWluc0tleShjaG9zZW5Mb2NhbGUpKSB7CisgICAgICAgICAgICAgIExvZ1V0aWwudigiJXM6IG1hdGNoZWQgZ3JvdXBzICVzIiwgVEFHLCBsb2NhbGVUb0ZpbGVHcm91cC5nZXQoY2hvc2VuTG9jYWxlKSk7CisgICAgICAgICAgICAgIHJldHVybiBPcHRpb25hbC5vZihsb2NhbGVUb0ZpbGVHcm91cC5nZXQoY2hvc2VuTG9jYWxlKSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBMb2dVdGlsLmUoIiVzOiBTdHJhdGVneSBhcHBsaWVkIHJldHVyZWQgaW52YWxpZCBsb2NhbGU6IDogJXMiLCBUQUcsIGNob3NlbkxvY2FsZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBPcHRpb25hbC5hYnNlbnQoKTsKKyAgICAgICAgfSwKKyAgICAgICAgbGlnaHR3ZWlnaHRFeGVjdXRvcik7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0xvY2F0aW9uUHJvdmlkZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0xvY2F0aW9uUHJvdmlkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNTFjN2JjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTG9jYXRpb25Qcm92aWRlci5qYXZhCkBAIC0wLDAgKzEsMjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnBvcHVsYXRvcjsKKworaW1wb3J0IGFuZHJvaWQubG9jYXRpb24uTG9jYXRpb247CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyOworCisvKiogQW4gaW50ZXJmYWNlIHRvIHByb3ZpZGUgdGhlIGRldmljZSBsb2NhdGlvbiB0byB0aGUgV2VicmVmIHBvcHVsYXRvci4gKi8KK3B1YmxpYyBpbnRlcmZhY2UgTG9jYXRpb25Qcm92aWRlciBleHRlbmRzIFN1cHBsaWVyPE9wdGlvbmFsPExvY2F0aW9uPj4ge30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0xvY2F0aW9uUHJvdmlkZXJJbXBsLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9Mb2NhdGlvblByb3ZpZGVySW1wbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc0NjM1ODUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9Mb2NhdGlvblByb3ZpZGVySW1wbC5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnBvcHVsYXRvcjsKKworaW1wb3J0IGFuZHJvaWQuTWFuaWZlc3QucGVybWlzc2lvbjsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQucG0uUGFja2FnZU1hbmFnZXI7CitpbXBvcnQgYW5kcm9pZC5sb2NhdGlvbi5Mb2NhdGlvbjsKK2ltcG9ydCBhbmRyb2lkLmxvY2F0aW9uLkxvY2F0aW9uTWFuYWdlcjsKK2ltcG9ydCBhbmRyb2lkeC5jb3JlLmNvbnRlbnQuQ29udGV4dENvbXBhdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworCisvKioKKyAqIFRoaXMgY29tbW9uIGNsYXNzIGRlZmluZXMgYSBmdW5jdGlvbiB0aGF0IHByb3ZpZGVzIHRoZSBkZXZpY2UgbG9jYXRpb24gdG8gdGhlIFdlYnJlZiBwb3B1bGF0b3IuCisgKi8KK2ZpbmFsIGNsYXNzIExvY2F0aW9uUHJvdmlkZXJJbXBsIGltcGxlbWVudHMgTG9jYXRpb25Qcm92aWRlciB7CisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIGZpbmFsIExvY2F0aW9uTWFuYWdlciBsb2NhdGlvbk1hbmFnZXI7CisKKyAgTG9jYXRpb25Qcm92aWRlckltcGwoQ29udGV4dCBjb250ZXh0LCBMb2NhdGlvbk1hbmFnZXIgbG9jYXRpb25NYW5hZ2VyKSB7CisgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsKKyAgICB0aGlzLmxvY2F0aW9uTWFuYWdlciA9IGxvY2F0aW9uTWFuYWdlcjsKKyAgfQorCisgIC8qKgorICAgKiBSZXR1cm5zIHRoZSBsb2NhdGlvbiBhY2NvcmRpbmcgdG8gbmV0d29yayBvciBHUFMgcHJvdmlkZXIgb3IgcmV0dXJucyBhYnNlbnQgaWYgYXBwIGRvZXNuJ3QgaGF2ZQorICAgKiB0aGUgcGVybWlzc2lvbiB0byByZXF1ZXN0IHRoZSBsb2NhdGlvbi4KKyAgICovCisgIEBPdmVycmlkZQorICBwdWJsaWMgT3B0aW9uYWw8TG9jYXRpb24+IGdldCgpIHsKKyAgICBpZiAoQ29udGV4dENvbXBhdC5jaGVja1NlbGZQZXJtaXNzaW9uKGNvbnRleHQsIHBlcm1pc3Npb24uQUNDRVNTX0ZJTkVfTE9DQVRJT04pCisgICAgICAgICAgICA9PSBQYWNrYWdlTWFuYWdlci5QRVJNSVNTSU9OX0RFTklFRAorICAgICAgICAmJiBDb250ZXh0Q29tcGF0LmNoZWNrU2VsZlBlcm1pc3Npb24oY29udGV4dCwgcGVybWlzc2lvbi5BQ0NFU1NfQ09BUlNFX0xPQ0FUSU9OKQorICAgICAgICAgICAgPT0gUGFja2FnZU1hbmFnZXIuUEVSTUlTU0lPTl9ERU5JRUQpIHsKKyAgICAgIHJldHVybiBPcHRpb25hbC5hYnNlbnQoKTsKKyAgICB9CisKKyAgICBMb2NhdGlvbiBuZXR3b3JrUHJvdmlkZXJMb2NhdGlvbiA9CisgICAgICAgIGxvY2F0aW9uTWFuYWdlci5nZXRMYXN0S25vd25Mb2NhdGlvbihMb2NhdGlvbk1hbmFnZXIuTkVUV09SS19QUk9WSURFUik7CisgICAgaWYgKG5ldHdvcmtQcm92aWRlckxvY2F0aW9uICE9IG51bGwgJiYgbmV0d29ya1Byb3ZpZGVyTG9jYXRpb24uaGFzQWNjdXJhY3koKSkgeworICAgICAgcmV0dXJuIE9wdGlvbmFsLm9mKG5ldHdvcmtQcm92aWRlckxvY2F0aW9uKTsKKyAgICB9CisgICAgTG9jYXRpb24gZ3BzUHJvdmlkZXJMb2NhdGlvbiA9CisgICAgICAgIGxvY2F0aW9uTWFuYWdlci5nZXRMYXN0S25vd25Mb2NhdGlvbihMb2NhdGlvbk1hbmFnZXIuR1BTX1BST1ZJREVSKTsKKyAgICBpZiAoZ3BzUHJvdmlkZXJMb2NhdGlvbiAhPSBudWxsICYmIGdwc1Byb3ZpZGVyTG9jYXRpb24uaGFzQWNjdXJhY3koKSkgeworICAgICAgcmV0dXJuIE9wdGlvbmFsLm9mKGdwc1Byb3ZpZGVyTG9jYXRpb24pOworICAgIH0KKyAgICByZXR1cm4gT3B0aW9uYWwuYWJzZW50KCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0xvY2F0aW9uUHJvdmlkZXJPdmVycmlkZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTG9jYXRpb25Qcm92aWRlck92ZXJyaWRlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWI1NzQ0ZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0xvY2F0aW9uUHJvdmlkZXJPdmVycmlkZS5qYXZhCkBAIC0wLDAgKzEsMjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnBvcHVsYXRvcjsKKworaW1wb3J0IGphdmF4LmluamVjdC5RdWFsaWZpZXI7CisKKy8qKiBBbGxvd3Mgb3ZlcnJpZGluZyB0aGUgZGVmYXVsdCBiaW5kaW5nIGZvciB7QGxpbmsgTG9jYXRpb25Qcm92aWRlcn0uICovCitAUXVhbGlmaWVyCitwdWJsaWMgQGludGVyZmFjZSBMb2NhdGlvblByb3ZpZGVyT3ZlcnJpZGUge30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTWFuaWZlc3RDb25maWdGbGFnUG9wdWxhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzdmZmJjNwotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvci5qYXZhCkBAIC0wLDAgKzEsMTA5IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5wb3B1bGF0b3I7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24uYmFzZS5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQ7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GaWxlR3JvdXBQb3B1bGF0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuTW9iaWxlRGF0YURvd25sb2FkOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLkpvaW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuU3VwcGxpZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5MaXN0czsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlR3JvdXA7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5NYW5pZmVzdENvbmZpZzsKKworLyoqCisgKiBGaWxlR3JvdXBQb3B1bGF0b3IgdGhhdCBjYW4gcHJvY2VzcyB0aGUgTWFuaWZlc3RDb25maWcgRmxhZyBmcm9tIHBoZW5vdHlwZS4KKyAqCisgKiA8cD5UaGUge0BsaW5rIE1hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvciNtYW5pZmVzdENvbmZpZ0ZsYWdOYW1lfSBzaG91bGQgcG9pbnQgdG8gYSBQSCBmbGFnIG9mCisgKiB0eXBlIHtAbGluayBNYW5pZmVzdENvbmZpZ30uCisgKgorICogPHA+Q2xpZW50IGNhbiBzZXQgYW4gb3B0aW9uYWwgTWFuaWZlc3RDb25maWdPdmVycmlkZXIgdG8gcmV0dXJuIGEgbGlzdCBvZiB7QGxpbmsgRGF0YUZpbGVHcm91cH0KKyAqIHdoaWNoIHdpbGwgYmUgYWRkZWQgdG8gTURELiBUaGUgT3ZlcnJpZGVyIHdpbGwgZW5hYmxlIHRoZSBvbiBkZXZpY2UgdGFyZ2V0aW5nLgorICoKKyAqIDxwPk5PVEU6IGlmIGFuIGFwcCB1c2VzIEZsYWcgTmFtZSBPYmZ1c2NhdGlvbiwgdGhlbiB0aGUgcGFzc2VkIGluIGZsYWcgbmFtZSBtdXN0IGJlIGFuIG9iZnVzY2F0ZWQKKyAqIG5hbWUuIEZvciBtb3JlIGluZm8sIHNlZSA8aW50ZXJuYWw+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNYW5pZmVzdENvbmZpZ0ZsYWdQb3B1bGF0b3IgaW1wbGVtZW50cyBGaWxlR3JvdXBQb3B1bGF0b3IgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiTWFuaWZlc3RDb25maWdGbGFnUG9wdWxhdG9yIjsKKworICAvKioKKyAgICogQnVpbGRlciBmb3Ige0BsaW5rIE1hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvcn0uCisgICAqCisgICAqIDxwPkVpdGhlciB7QGNvZGUgbWFuaWZlc3RDb25maWdTdXBwbGllcn0gb3IgYm90aCB7QGNvZGUgcGhQYWNrYWdlTmFtZX0gYW5kIHtAY29kZQorICAgKiBtYW5pZmVzdENvbmZpZ0ZsYWdOYW1lfSBzaG91bGQgYmUgc2V0LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIHsKKyAgICBwcml2YXRlIFN1cHBsaWVyPE1hbmlmZXN0Q29uZmlnPiBtYW5pZmVzdENvbmZpZ1N1cHBsaWVyOworCisgICAgcHJpdmF0ZSBPcHRpb25hbDxNYW5pZmVzdENvbmZpZ092ZXJyaWRlcj4gb3ZlcnJpZGVyT3B0aW9uYWwgPSBPcHRpb25hbC5hYnNlbnQoKTsKKworICAgIC8qKiBTZXQgdGhlIE1hbmlmZXN0Q29uZmlnIHN1cHBsaWVyLiAqLworICAgIHB1YmxpYyBCdWlsZGVyIHNldE1hbmlmZXN0Q29uZmlnU3VwcGxpZXIoU3VwcGxpZXI8TWFuaWZlc3RDb25maWc+IG1hbmlmZXN0Q29uZmlnU3VwcGxpZXIpIHsKKyAgICAgIHRoaXMubWFuaWZlc3RDb25maWdTdXBwbGllciA9IG1hbmlmZXN0Q29uZmlnU3VwcGxpZXI7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBTZXRzIHRoZSBvcHRpb25hbCBPdmVycmlkZXIgdGhhdCB0YWtlcyBhIHtAbGluayBNYW5pZmVzdENvbmZpZ30gYW5kIHJldHVybnMgYSBsaXN0IG9mIHtAbGluaworICAgICAqIERhdGFGaWxlR3JvdXB9IHdoaWNoIHdpbGwgYmUgYWRkZWQgdG8gTURELiBUaGUgT3ZlcnJpZGVyIHdpbGwgZW5hYmxlIHRoZSBvbiBkZXZpY2UgdGFyZ2V0aW5nLgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIHNldE92ZXJyaWRlck9wdGlvbmFsKE9wdGlvbmFsPE1hbmlmZXN0Q29uZmlnT3ZlcnJpZGVyPiBvdmVycmlkZXJPcHRpb25hbCkgeworICAgICAgdGhpcy5vdmVycmlkZXJPcHRpb25hbCA9IG92ZXJyaWRlck9wdGlvbmFsOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIE1hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvciBidWlsZCgpIHsKKyAgICAgIGNoZWNrQXJndW1lbnQobWFuaWZlc3RDb25maWdTdXBwbGllciAhPSBudWxsLCAiU3VwcGxpZXIgc2hvdWxkIGJlIHByb3ZpZGVkLiIpOworICAgICAgcmV0dXJuIG5ldyBNYW5pZmVzdENvbmZpZ0ZsYWdQb3B1bGF0b3IobWFuaWZlc3RDb25maWdTdXBwbGllciwgb3ZlcnJpZGVyT3B0aW9uYWwpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgZmluYWwgU3VwcGxpZXI8TWFuaWZlc3RDb25maWc+IG1hbmlmZXN0Q29uZmlnU3VwcGxpZXI7CisgIHByaXZhdGUgZmluYWwgT3B0aW9uYWw8TWFuaWZlc3RDb25maWdPdmVycmlkZXI+IG92ZXJyaWRlck9wdGlvbmFsOworCisgIC8qKiBSZXR1cm5zIGEgQnVpbGRlciBmb3IgTWFuaWZlc3RDb25maWdGbGFnUG9wdWxhdG9yLiAqLworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgYnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEJ1aWxkZXIoKTsKKyAgfQorCisgIHByaXZhdGUgTWFuaWZlc3RDb25maWdGbGFnUG9wdWxhdG9yKAorICAgICAgU3VwcGxpZXI8TWFuaWZlc3RDb25maWc+IG1hbmlmZXN0Q29uZmlnU3VwcGxpZXIsCisgICAgICBPcHRpb25hbDxNYW5pZmVzdENvbmZpZ092ZXJyaWRlcj4gb3ZlcnJpZGVyT3B0aW9uYWwpIHsKKyAgICB0aGlzLm1hbmlmZXN0Q29uZmlnU3VwcGxpZXIgPSBtYW5pZmVzdENvbmZpZ1N1cHBsaWVyOworICAgIHRoaXMub3ZlcnJpZGVyT3B0aW9uYWwgPSBvdmVycmlkZXJPcHRpb25hbDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiByZWZyZXNoRmlsZUdyb3VwcyhNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkKSB7CisgICAgTWFuaWZlc3RDb25maWcgbWFuaWZlc3RDb25maWcgPSBtYW5pZmVzdENvbmZpZ1N1cHBsaWVyLmdldCgpOworCisgICAgU3RyaW5nIGdyb3VwcyA9CisgICAgICAgIEpvaW5lci5vbigiLCIpCisgICAgICAgICAgICAuam9pbigKKyAgICAgICAgICAgICAgICBMaXN0cy50cmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgIG1hbmlmZXN0Q29uZmlnLmdldEVudHJ5TGlzdCgpLAorICAgICAgICAgICAgICAgICAgICBlbnRyeSAtPiBlbnRyeS5nZXREYXRhRmlsZUdyb3VwKCkuZ2V0R3JvdXBOYW1lKCkpKTsKKyAgICBMb2dVdGlsLmQoIiVzOiBBZGQgZ3JvdXBzIFslc10gZnJvbSBNYW5pZmVzdENvbmZpZyB0byBNREQuIiwgVEFHLCBncm91cHMpOworCisgICAgcmV0dXJuIE1hbmlmZXN0Q29uZmlnSGVscGVyLnJlZnJlc2hGcm9tTWFuaWZlc3RDb25maWcoCisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZCwgbWFuaWZlc3RDb25maWdTdXBwbGllci5nZXQoKSwgb3ZlcnJpZGVyT3B0aW9uYWwpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9NYW5pZmVzdENvbmZpZ0hlbHBlci5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTWFuaWZlc3RDb25maWdIZWxwZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMmM4NzIyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTWFuaWZlc3RDb25maWdIZWxwZXIuamF2YQpAQCAtMCwwICsxLDE4OCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQucG9wdWxhdG9yOworCitpbXBvcnQgYW5kcm9pZC51dGlsLkxvZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5BZGRGaWxlR3JvdXBSZXF1ZXN0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLk1vYmlsZURhdGFEb3dubG9hZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlByb3BhZ2F0ZWRGbHVlbnRGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5Qcm9wYWdhdGVkRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVDYWxsYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRlbHRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLk1hbmlmZXN0Q29uZmlnOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKKy8qKiBTaGFyZWQgZnVuY3Rpb25zIGZvciBNYW5pZmVzdENvbmZpZy4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNYW5pZmVzdENvbmZpZ0hlbHBlciB7CisgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFVSTF9URU1QTEFURV9DSEVDS1NVTV9QTEFDRUhPTERFUiA9ICJ7Y2hlY2tzdW19IjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIk1hbmlmZXN0Q29uZmlnSGVscGVyIjsKKworICBwcml2YXRlIGZpbmFsIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQ7CisgIHByaXZhdGUgZmluYWwgT3B0aW9uYWw8TWFuaWZlc3RDb25maWdPdmVycmlkZXI+IG92ZXJyaWRlck9wdGlvbmFsOworCisgIC8qKiBDcmVhdGVzIGEgbmV3IGhlbHBlciBmb3IgY29udmVydGluZyBtYW5pZmVzdCBjb25maWdzIGludG8gZGF0YSBmaWxlIGdyb3Vwcy4gKi8KKyAgTWFuaWZlc3RDb25maWdIZWxwZXIoCisgICAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkLCBPcHRpb25hbDxNYW5pZmVzdENvbmZpZ092ZXJyaWRlcj4gb3ZlcnJpZGVyT3B0aW9uYWwpIHsKKyAgICB0aGlzLm1vYmlsZURhdGFEb3dubG9hZCA9IG1vYmlsZURhdGFEb3dubG9hZDsKKyAgICB0aGlzLm92ZXJyaWRlck9wdGlvbmFsID0gb3ZlcnJpZGVyT3B0aW9uYWw7CisgIH0KKworICAvKioKKyAgICogUmVhZHMgZmlsZSBncm91cHMgZnJvbSB7QGxpbmsgTWFuaWZlc3RDb25maWd9IGFuZCBhZGRzIHRvIE1ERCBhZnRlciBhcHBseWluZyB0aGUge0BsaW5rCisgICAqIE1hbmlmZXN0Q29uZmlnT3ZlcnJpZGVyfSBpZiBpdCdzIHByZXNlbnQuIFRoaXMgc3RhdGljIG1ldGhvZCBpcyBzaGFyZWQgd2l0aCB7QGxpbmsKKyAgICogTWFuaWZlc3RGaWxlR3JvdXBQb3B1bGF0b3J9LgorICAgKgorICAgKiBAcGFyYW0gbW9iaWxlRGF0YURvd25sb2FkIFRoZSBNREQgaW5zdGFuY2UuCisgICAqIEBwYXJhbSBtYW5pZmVzdENvbmZpZyBUaGUgcHJvdG8gdGhhdCBjb250YWlucyBjb25maWdzIGZvciBmaWxlIGdyb3VwcyBhbmQgbW9kaWZpZXJzLgorICAgKiBAcGFyYW0gb3ZlcnJpZGVyT3B0aW9uYWwgQW4gb3B0aW9uYWwgb3ZlcnJpZGVyIHRoYXQgdGFrZXMgbWFuaWZlc3QgY29uZmlnIGFuZCByZXR1cm5zIGEgbGlzdCBvZgorICAgKiAgICAgZmlsZSBncm91cHMgdG8gYmUgYWRkZWQgdG8gTURELgorICAgKi8KKyAgc3RhdGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVmcmVzaEZyb21NYW5pZmVzdENvbmZpZygKKyAgICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQsCisgICAgICBNYW5pZmVzdENvbmZpZyBtYW5pZmVzdENvbmZpZywKKyAgICAgIE9wdGlvbmFsPE1hbmlmZXN0Q29uZmlnT3ZlcnJpZGVyPiBvdmVycmlkZXJPcHRpb25hbCkgeworICAgIE1hbmlmZXN0Q29uZmlnSGVscGVyIGhlbHBlciA9IG5ldyBNYW5pZmVzdENvbmZpZ0hlbHBlcihtb2JpbGVEYXRhRG93bmxvYWQsIG92ZXJyaWRlck9wdGlvbmFsKTsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKGhlbHBlci5hcHBseU92ZXJyaWRlcihtYW5pZmVzdENvbmZpZykpCisgICAgICAgIC50cmFuc2Zvcm1Bc3luYyhoZWxwZXI6OmFkZEFsbEZpbGVHcm91cHMsIE1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3IoKSk7CisgIH0KKworICAvKiogQWRkcyB0aGUgc3BlY2lmaWVkIGxpc3Qgb2YgZmlsZSBncm91cHMgdG8gTURELiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGFkZEFsbEZpbGVHcm91cHMoTGlzdDxEYXRhRmlsZUdyb3VwPiBmaWxlR3JvdXBzKSB7CisgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+PiBhZGRGaWxlR3JvdXBGdXR1cmVzID0gbmV3IEFycmF5TGlzdDw+KCk7CisKKyAgICBmb3IgKERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cCA6IGZpbGVHcm91cHMpIHsKKyAgICAgIGlmIChkYXRhRmlsZUdyb3VwID09IG51bGwgfHwgZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKS5pc0VtcHR5KCkpIHsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisKKyAgICAgIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gYWRkRmlsZUdyb3VwRnV0dXJlID0KKyAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuYWRkRmlsZUdyb3VwKAorICAgICAgICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXREYXRhRmlsZUdyb3VwKGRhdGFGaWxlR3JvdXApLmJ1aWxkKCkpOworCisgICAgICBQcm9wYWdhdGVkRnV0dXJlcy5hZGRDYWxsYmFjaygKKyAgICAgICAgICBhZGRGaWxlR3JvdXBGdXR1cmUsCisgICAgICAgICAgbmV3IEZ1dHVyZUNhbGxiYWNrPEJvb2xlYW4+KCkgeworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoQm9vbGVhbiByZXN1bHQpIHsKKyAgICAgICAgICAgICAgU3RyaW5nIGdyb3VwTmFtZSA9IGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCk7CisgICAgICAgICAgICAgIGlmIChyZXN1bHQuYm9vbGVhblZhbHVlKCkpIHsKKyAgICAgICAgICAgICAgICBMb2cuZChUQUcsICJBZGRlZCBmaWxlIGdyb3VwcyAiICsgZ3JvdXBOYW1lKTsKKyAgICAgICAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgICAgICBMb2cuZChUQUcsICJGYWlsZWQgdG8gYWRkIGZpbGUgZ3JvdXAgIiArIGdyb3VwTmFtZSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkZhaWx1cmUoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgTG9nLmUoVEFHLCAiRmFpbGVkIHRvIGFkZCBmaWxlIGdyb3VwIiwgdCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfSwKKyAgICAgICAgICBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCkpOworICAgICAgYWRkRmlsZUdyb3VwRnV0dXJlcy5hZGQoYWRkRmlsZUdyb3VwRnV0dXJlKTsKKyAgICB9CisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLndoZW5BbGxDb21wbGV0ZShhZGRGaWxlR3JvdXBGdXR1cmVzKQorICAgICAgICAuY2FsbCgoKSAtPiBudWxsLCBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCkpOworICB9CisKKyAgLyoqIEFwcGxpZXMgdGhlIG92ZXJyaWRlciB0byB0aGUgbWFuaWZlc3QgY29uZmlnIHRvIGdlbmVyYXRlIGEgbGlzdCBvZiBmaWxlIGdyb3VwcyBmb3IgYWRkaW5nLiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPExpc3Q8RGF0YUZpbGVHcm91cD4+IGFwcGx5T3ZlcnJpZGVyKE1hbmlmZXN0Q29uZmlnIG1hbmlmZXN0Q29uZmlnKSB7CisgICAgaWYgKG92ZXJyaWRlck9wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICByZXR1cm4gb3ZlcnJpZGVyT3B0aW9uYWwuZ2V0KCkub3ZlcnJpZGUobWF5YmVBcHBseUZpbGVVcmxUZW1wbGF0ZShtYW5pZmVzdENvbmZpZykpOworICAgIH0KKyAgICBMaXN0PERhdGFGaWxlR3JvdXA+IHJlc3VsdHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBmb3IgKE1hbmlmZXN0Q29uZmlnLkVudHJ5IGVudHJ5IDogbWF5YmVBcHBseUZpbGVVcmxUZW1wbGF0ZShtYW5pZmVzdENvbmZpZykuZ2V0RW50cnlMaXN0KCkpIHsKKyAgICAgIHJlc3VsdHMuYWRkKGVudHJ5LmdldERhdGFGaWxlR3JvdXAoKSk7CisgICAgfQorICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShyZXN1bHRzKTsKKyAgfQorCisgIC8qKgorICAgKiBJZiBmaWxlX3VybF90ZW1wbGF0ZSBpcyBwb3B1bGF0ZWQgYW5kIGZpbGUgdXJsX3RvX2Rvd25sb2FkIGZpZWxkIGlzIGVtcHR5IGluIHRoZSB7QGNvZGUKKyAgICogTWFuaWZlc3RDb25maWd9IG1hbmlmZXN0Q29uZmlnIHRoZW4gY29uc3RydWN0IHRoZSB1cmxfdG9fZG93bmxvYWQgZmllbGQgdXNpbmcgdGhlIHRlbXBsYXRlLgorICAgKgorICAgKiA8cD5OT1RFOiBJZiBmaWxlX3VybF90ZW1wbGF0ZSBpcyBlbXB0eSB0aGVuIHRoZSBmaWxlcyBhcmUgZXhwZWN0ZWQgdG8gaGF2ZSB0aGUgY29tcGxldGUKKyAgICogZG93bmxvYWQgVVJMLCB2YWxpZGF0ZSBhbmQgdGhyb3cgYW4ge0BsaW5rIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbn0gaWYgdXJsX3RvX2Rvd25sb2FkIGlzIG5vdAorICAgKiBwb3B1bGF0ZWQuCisgICAqLworICBwdWJsaWMgc3RhdGljIE1hbmlmZXN0Q29uZmlnIG1heWJlQXBwbHlGaWxlVXJsVGVtcGxhdGUoTWFuaWZlc3RDb25maWcgbWFuaWZlc3RDb25maWcpIHsKKyAgICBpZiAoIW1hbmlmZXN0Q29uZmlnLmhhc1VybFRlbXBsYXRlKCkKKyAgICAgICAgfHwgbWFuaWZlc3RDb25maWcuZ2V0VXJsVGVtcGxhdGUoKS5nZXRGaWxlVXJsVGVtcGxhdGUoKS5pc0VtcHR5KCkpIHsKKyAgICAgIHJldHVybiB2YWxpZGF0ZU1hbmlmZXN0Q29uZmlnRmlsZVVybHMobWFuaWZlc3RDb25maWcpOworICAgIH0KKyAgICBTdHJpbmcgZmlsZURvd25sb2FkVXJsVGVtcGxhdGUgPSBtYW5pZmVzdENvbmZpZy5nZXRVcmxUZW1wbGF0ZSgpLmdldEZpbGVVcmxUZW1wbGF0ZSgpOworICAgIE1hbmlmZXN0Q29uZmlnLkJ1aWxkZXIgdXBkYXRlZE1hbmlmZXN0Q29uZmlnQnVpbGRlciA9IG1hbmlmZXN0Q29uZmlnLnRvQnVpbGRlcigpLmNsZWFyRW50cnkoKTsKKworICAgIGZvciAoTWFuaWZlc3RDb25maWcuRW50cnkgZW50cnkgOiBtYW5pZmVzdENvbmZpZy5nZXRFbnRyeUxpc3QoKSkgeworICAgICAgRGF0YUZpbGVHcm91cC5CdWlsZGVyIGRhdGFGaWxlR3JvdXBCdWlsZGVyID0gZW50cnkuZ2V0RGF0YUZpbGVHcm91cCgpLnRvQnVpbGRlcigpLmNsZWFyRmlsZSgpOworICAgICAgZm9yIChEYXRhRmlsZSBkYXRhRmlsZSA6IGVudHJ5LmdldERhdGFGaWxlR3JvdXAoKS5nZXRGaWxlTGlzdCgpKSB7CisgICAgICAgIERhdGFGaWxlLkJ1aWxkZXIgZGF0YUZpbGVCdWlsZGVyID0gZGF0YUZpbGUudG9CdWlsZGVyKCkuY2xlYXJEZWx0YUZpbGUoKTsKKworICAgICAgICBpZiAoZGF0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpLmlzRW1wdHkoKSkgeworICAgICAgICAgIGRhdGFGaWxlQnVpbGRlci5zZXRVcmxUb0Rvd25sb2FkKAorICAgICAgICAgICAgICBmaWxlRG93bmxvYWRVcmxUZW1wbGF0ZS5yZXBsYWNlKAorICAgICAgICAgICAgICAgICAgVVJMX1RFTVBMQVRFX0NIRUNLU1VNX1BMQUNFSE9MREVSLCBkYXRhRmlsZS5nZXRDaGVja3N1bSgpKSk7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKERlbHRhRmlsZSBkZWx0YUZpbGUgOiBkYXRhRmlsZS5nZXREZWx0YUZpbGVMaXN0KCkpIHsKKyAgICAgICAgICBkYXRhRmlsZUJ1aWxkZXIuYWRkRGVsdGFGaWxlKAorICAgICAgICAgICAgICBkZWx0YUZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpLmlzRW1wdHkoKQorICAgICAgICAgICAgICAgICAgPyBkZWx0YUZpbGUudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZURvd25sb2FkVXJsVGVtcGxhdGUucmVwbGFjZSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVSTF9URU1QTEFURV9DSEVDS1NVTV9QTEFDRUhPTERFUiwgZGVsdGFGaWxlLmdldENoZWNrc3VtKCkpKQorICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpCisgICAgICAgICAgICAgICAgICA6IGRlbHRhRmlsZSk7CisgICAgICAgIH0KKworICAgICAgICBkYXRhRmlsZUdyb3VwQnVpbGRlci5hZGRGaWxlKGRhdGFGaWxlQnVpbGRlcik7CisgICAgICB9CisgICAgICB1cGRhdGVkTWFuaWZlc3RDb25maWdCdWlsZGVyLmFkZEVudHJ5KAorICAgICAgICAgIGVudHJ5LnRvQnVpbGRlcigpLnNldERhdGFGaWxlR3JvdXAoZGF0YUZpbGVHcm91cEJ1aWxkZXIpKTsKKyAgICB9CisgICAgcmV0dXJuIHVwZGF0ZWRNYW5pZmVzdENvbmZpZ0J1aWxkZXIuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBWYWxpZGF0ZXMgdGhhdCBhbGwgdGhlIGZpbGVzIGluIHtAY29kZSBNYW5pZmVzdENvbmZpZ30gbWFuaWZlc3RDb25maWcgaGF2ZSB0aGUgdXJsX3RvX2Rvd25sb2FkCisgICAqIHBvcHVsYXRlZC4KKyAgICovCisgIHByaXZhdGUgc3RhdGljIE1hbmlmZXN0Q29uZmlnIHZhbGlkYXRlTWFuaWZlc3RDb25maWdGaWxlVXJscyhNYW5pZmVzdENvbmZpZyBtYW5pZmVzdENvbmZpZykgeworICAgIGZvciAoTWFuaWZlc3RDb25maWcuRW50cnkgZW50cnkgOiBtYW5pZmVzdENvbmZpZy5nZXRFbnRyeUxpc3QoKSkgeworICAgICAgZm9yIChEYXRhRmlsZSBkYXRhRmlsZSA6IGVudHJ5LmdldERhdGFGaWxlR3JvdXAoKS5nZXRGaWxlTGlzdCgpKSB7CisgICAgICAgIGlmIChkYXRhRmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkuaXNFbXB0eSgpKSB7CisgICAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKKyAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdCgiRGF0YUZpbGUgJXMgdXJsX3RvX2Rvd25sb2FkIGlzIG1pc3NpbmcuIiwgZGF0YUZpbGUuZ2V0RmlsZUlkKCkpKTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKERlbHRhRmlsZSBkZWx0YUZpbGUgOiBkYXRhRmlsZS5nZXREZWx0YUZpbGVMaXN0KCkpIHsKKyAgICAgICAgICBpZiAoZGVsdGFGaWxlLmdldFVybFRvRG93bmxvYWQoKS5pc0VtcHR5KCkpIHsKKyAgICAgICAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCisgICAgICAgICAgICAgICAgU3RyaW5nLmZvcm1hdCgKKyAgICAgICAgICAgICAgICAgICAgIkRlbHRhRmlsZSBmb3IgZmlsZSAlcyB1cmxfdG9fZG93bmxvYWQgaXMgbWlzc2luZy4iLCBkYXRhRmlsZS5nZXRGaWxlSWQoKSkpOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbWFuaWZlc3RDb25maWc7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01hbmlmZXN0Q29uZmlnT3ZlcnJpZGVyLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9NYW5pZmVzdENvbmZpZ092ZXJyaWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhhMzFmNjAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9NYW5pZmVzdENvbmZpZ092ZXJyaWRlci5qYXZhCkBAIC0wLDAgKzEsMzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnBvcHVsYXRvcjsKKworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLk1hbmlmZXN0Q29uZmlnOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworCisvKioKKyAqIENsaWVudCBwcm92aWRlZCBPdmVycmlkZXIgd2hpY2ggb3B0aW9uYWxseSBvdmVycmlkZXMgYSB7QGxpbmsgTWFuaWZlc3RDb25maWd9LiBUaGlzIGNvdWxkIGJlIHVzZWQKKyAqIGZvciBvbiBkZXZpY2UgdGFyZ2V0aW5nIGJ5IGFsdGVyaW5nIG9yIGRyb3BwaW5nIHRoZSBpbnB1dCBNYW5pZmVzdENvbmZpZy5EYXRhRmlsZUdyb3VwLgorICovCitwdWJsaWMgaW50ZXJmYWNlIE1hbmlmZXN0Q29uZmlnT3ZlcnJpZGVyIHsKKworICAvKiogT3B0aW9uYWxseSBvdmVycmlkZSB0aGUgaW5wdXQgTWFuaWZlc3RDb25maWcuICovCisgIExpc3RlbmFibGVGdXR1cmU8TGlzdDxEYXRhRmlsZUdyb3VwPj4gb3ZlcnJpZGUoTWFuaWZlc3RDb25maWcgbWFuaWZlc3RDb25maWcpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTWFuaWZlc3RGaWxlR3JvdXBQb3B1bGF0b3IuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01hbmlmZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjZkMjZhYgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01hbmlmZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmphdmEKQEAgLTAsMCArMSw2ODAgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnBvcHVsYXRvcjsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlRyYWNlUHJvcGFnYXRpb24ucHJvcGFnYXRlQXN5bmNDYWxsYWJsZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWR4LmFubm90YXRpb24uVmlzaWJsZUZvclRlc3Rpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQucG9wdWxhdG9yLk1ldGFkYXRhUHJvdG8uTWFuaWZlc3RGaWxlQm9va2tlZXBpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQucG9wdWxhdG9yLk1ldGFkYXRhUHJvdG8uTWFuaWZlc3RGaWxlQm9va2tlZXBpbmcuU3RhdHVzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkFnZ3JlZ2F0ZUV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbi5Eb3dubG9hZFJlc3VsdENvZGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmlsZUdyb3VwUG9wdWxhdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkZsYWdzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkxvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Nb2JpbGVEYXRhRG93bmxvYWQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5DaGVja0NvbnRlbnRDaGFuZ2VSZXF1ZXN0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuQ2hlY2tDb250ZW50Q2hhbmdlUmVzcG9uc2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZENvbnN0cmFpbnRzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLkRpcmVjdG9yeVV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubG9nZ2VyLkZpbGVHcm91cFBvcHVsYXRvckxvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nLlByb3BhZ2F0ZWRGbHVlbnRGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5Qcm9wYWdhdGVkRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuUHJlY29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uU2VxdWVuY2VyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVDYWxsYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlR3JvdXA7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5NYW5pZmVzdENvbmZpZzsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLk1hbmlmZXN0RmlsZUZsYWc7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljUmVmZXJlbmNlOworaW1wb3J0IGphdmF4LmFubm90YXRpb24uTnVsbGFibGU7CitpbXBvcnQgamF2YXguaW5qZWN0LlNpbmdsZXRvbjsKKworLyoqCisgKiBGaWxlIGdyb3VwIHBvcHVsYXRvciB0aGF0IGdldHMge0BsaW5rIE1hbmlmZXN0RmlsZUZsYWd9IGZyb20gdGhlIGNhbGxlciwgZG93bmxvYWRzIHRoZQorICogY29ycmVzcG9uZGluZyBtYW5pZmVzdCBmaWxlLCBwYXJzZXMgdGhlIGZpbGUgaW50byB7QGxpbmsgTWFuaWZlc3RDb25maWd9LCBhbmQgcHJvY2Vzc2VzIHtAbGluaworICogTWFuaWZlc3RDb25maWd9LgorICoKKyAqIDxwPkNsaWVudCBjYW4gc2V0IGFuIG9wdGlvbmFsIHtAbGluayBNYW5pZmVzdENvbmZpZ092ZXJyaWRlcn0gdG8gcmV0dXJuIGEgbGlzdCBvZiB7QGxpbmsKKyAqIERhdGFGaWxlR3JvdXB9J3MgdG8gYmUgYWRkZWQgdG8gTURELiBUaGUgb3ZlcnJpZGVyIHdpbGwgZW5hYmxlIHRoZSBvbiBkZXZpY2UgdGFyZ2V0aW5nLgorICoKKyAqIDxwPkNsaWVudCBpcyByZXNwb25zaWJsZSBvZiByZWFkaW5nIHtAbGluayBNYW5pZmVzdEZpbGVGbGFnfSBmcm9tIFAvSCwgYW5kIHRoaXMgcG9wdWxhdG9yIHdvdWxkCisgKiBnZXQgdGhlIGZsYWcgdmlhIHtAbGluayBTdXBwbGllcjxNYW5pZmVzdEZpbGVGbGFnPn0uCisgKgorICogPHA+T24gY2FsbGluZyB7QGxpbmsgI3JlZnJlc2hGaWxlR3JvdXBzKE1vYmlsZURhdGFEb3dubG9hZCl9LCB0aGlzIHBvcHVsYXRvciB3b3VsZCBzeW5jIHVwIHdpdGgKKyAqIHNlcnZlciB0byB2ZXJpZnkgaWYgdGhlIG1hbmlmZXN0IGZpbGUgb24gc2VydmVyIGhhcyBjaGFuZ2VkIHNpbmNlIGxhc3QgZG93bmxvYWQuIEl0IHdvdWxkCisgKiByZS1kb3dubG9hZCB0aGUgZmlsZSBpZiBhIG5ld2VyIHZlcnNpb24gaXMgYXZhaWxhYmxlLiBNb3JlIHNwZWNpZmljYWxseSwgdGhlcmUgYXJlIDMgc2NlbmFyaW9zOgorICoKKyAqIDx1bD4KKyAqICAgPGxpPjEuIEN1cnJlbnQgZmlsZSB1cC10by1kYXRlLCBzdGF0dXMgUEVORElORy4gUmVzdW1lIGRvd25sb2FkLgorICogICA8bGk+Mi4gQ3VycmVudCBmaWxlIHVwLXRvLWRhdGUsIHN0YXR1cyAoRE9XTkxPQURFRCB8IENPTU1JVFRFRCkuIE5vIGRvd25sb2FkIHdpbGwgaGFwcGVuLgorICogICA8bGk+My4gQ3VycmVudCBmaWxlIG91dGRhdGVkLiBEZWxldGUgdGhlIG91dGRhdGVkIGZpbGUgYW5kIHJlLWRvd25sb2FkLgorICogPC91bD4KKyAqCisgKiA8cD5UbyBlbnN1cmUgdGhhdCBlYWNoIHRpbWUgd2UgZG93bmxvYWQgdGhlIG1vc3QgdXAtdG8tZGF0ZSBtYW5pZmVzdCBmaWxlIGNvcnJlY3RseSwgd2Ugd2lsbAorICogY2hlY2sgZm9yIHtAbGluayBGaWxlRG93bmxvYWRlciNpc0NvbnRlbnRDaGFuZ2VkKENoZWNrQ29udGVudENoYW5nZVJlcXVlc3QpfSB0d2ljZToKKyAqCisgKiA8dWw+CisgKiAgIDxsaT4xLiBCZWZvcmUgdGhlIGRvd25sb2FkIHRvIGNoZWNrIGlmIHRoZSBuZXcgZG93bmxvYWQgaXMgbmVjZXNzYXJ5LgorICogICA8bGk+Mi4gQWZ0ZXIgdGhlIGRvd25sb2FkIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBjb250ZW50IGlzIG5vdCBvdXQgb2YgZGF0ZS4KKyAqIDwvdWw+CisgKgorICogPHA+Tm90ZSB0aGF0IHRoZSBjdXJyZW50IHByZXJlcXVpc2l0ZSBvZiB1c2luZyB7QGxpbmsgTWFuaWZlc3RGaWxlR3JvdXBQb3B1bGF0b3J9IGlzIHRoYXQsIHRoZQorICogaG9zdGluZyBzZXJ2aWNlIG5lZWRzIHRvIHN1cHBvcnQgRVRhZyAoZS5nLiBMb3JyeSksIG90aGVyd2lzZSB0aGUgYmVoYXZpb3Igd2lsbCBiZSB1bmV4cGVjdGVkLgorICogVGFsayB0byA8aW50ZXJuYWw+QCBpZiB5b3UgYXJlIG5vdCBzdXJlIGlmIHRoZSBob3N0aW5nIHNlcnZpY2Ugc3VwcG9ydHMgRVRhZy4KKyAqCisgKiA8cD5Ob3RlIHRoYXQge0BsaW5rIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2V9IGFuZCB7QGxpbmsgUHJvdG9EYXRhU3RvcmVGYWN0b3J5fSBwYXNzZWQgdG8gYnVpbGRlcgorICogbXVzdCBiZSBAU2luZ2xldG9uLgorICoKKyAqIDxwPlRoaXMgY2xhc3MgaXMgQFNpbmdsZXRvbiwgYmVjYXVzZSBpdCBwcm92aWRlcyB0aGUgZ3VhcmFudGVlIHRoYXQgYWxsIHRoZSBvcGVyYXRpb25zIGFyZQorICogc2VyaWFsaXplZCBjb3JyZWN0bHkgYnkge0BsaW5rIEV4ZWN1dGlvblNlcXVlbmNlcn0uCisgKi8KK0BTaW5nbGV0b24KK3B1YmxpYyBmaW5hbCBjbGFzcyBNYW5pZmVzdEZpbGVHcm91cFBvcHVsYXRvciBpbXBsZW1lbnRzIEZpbGVHcm91cFBvcHVsYXRvciB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJNYW5pZmVzdEZpbGVHcm91cFBvcHVsYXRvciI7CisKKyAgLyoqIFRoZSBwYXJzZXIgb2YgdGhlIG1hbmlmZXN0IGZpbGUuICovCisgIHB1YmxpYyBpbnRlcmZhY2UgTWFuaWZlc3RDb25maWdQYXJzZXIgeworCisgICAgLyoqIFBhcnNlcyB0aGUgaW5wdXQgZmlsZSBhbmQgcmV0dXJucyB0aGUge0BsaW5rIE1hbmlmZXN0Q29uZmlnfS4gKi8KKyAgICBMaXN0ZW5hYmxlRnV0dXJlPE1hbmlmZXN0Q29uZmlnPiBwYXJzZShVcmkgZmlsZVVyaSk7CisgIH0KKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIE1hbmlmZXN0RmlsZUdyb3VwUG9wdWxhdG9yfS4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIHsKKyAgICBwcml2YXRlIGJvb2xlYW4gYWxsb3dzSW5zZWN1cmVIdHRwID0gZmFsc2U7CisgICAgcHJpdmF0ZSBib29sZWFuIGRlZHVwRG93bmxvYWRXaXRoRXRhZyA9IHRydWU7CisgICAgcHJpdmF0ZSBDb250ZXh0IGNvbnRleHQ7CisgICAgcHJpdmF0ZSBTdXBwbGllcjxNYW5pZmVzdEZpbGVGbGFnPiBtYW5pZmVzdEZpbGVGbGFnU3VwcGxpZXI7CisgICAgcHJpdmF0ZSBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXI7CisgICAgcHJpdmF0ZSBNYW5pZmVzdENvbmZpZ1BhcnNlciBtYW5pZmVzdENvbmZpZ1BhcnNlcjsKKyAgICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2U7CisgICAgcHJpdmF0ZSBFeGVjdXRvciBiYWNrZ3JvdW5kRXhlY3V0b3I7CisgICAgcHJpdmF0ZSBNYW5pZmVzdEZpbGVNZXRhZGF0YVN0b3JlIG1hbmlmZXN0RmlsZU1ldGFkYXRhU3RvcmU7CisgICAgcHJpdmF0ZSBMb2dnZXIgbG9nZ2VyOworICAgIHByaXZhdGUgT3B0aW9uYWw8TWFuaWZlc3RDb25maWdPdmVycmlkZXI+IG92ZXJyaWRlck9wdGlvbmFsID0gT3B0aW9uYWwuYWJzZW50KCk7CisgICAgcHJpdmF0ZSBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWRPcHRpb25hbCA9IE9wdGlvbmFsLmFic2VudCgpOworICAgIHByaXZhdGUgRmxhZ3MgZmxhZ3MgPSBuZXcgRmxhZ3MoKSB7fTsKKworICAgIC8qKgorICAgICAqIFNldHMgdGhlIGZsYWcgdGhhdCBhbGxvd3MgaW5zZWN1cmUgaHR0cC4KKyAgICAgKgorICAgICAqIDxwPkZvciB0ZXN0aW5nIG9ubHkuCisgICAgICovCisgICAgQFZpc2libGVGb3JUZXN0aW5nCisgICAgQnVpbGRlciBzZXRBbGxvd3NJbnNlY3VyZUh0dHAoYm9vbGVhbiBhbGxvd3NJbnNlY3VyZUh0dHApIHsKKyAgICAgIHRoaXMuYWxsb3dzSW5zZWN1cmVIdHRwID0gYWxsb3dzSW5zZWN1cmVIdHRwOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogQnkgZGVmYXVsdCwgYW4gSFRUUCBIRUFEIHJlcXVlc3QgaXMgbWFkZSB0byBhdm9pZCBkdXBsaWNhdGUgZG93bmxvYWRzIG9mIHRoZSBtYW5pZmVzdCBmaWxlLgorICAgICAqIFNldHRpbmcgdGhpcyB0byBmYWxzZSBkaXNhYmxlcyB0aGF0IGJlaGF2aW9yLgorICAgICAqLworICAgIHB1YmxpYyBCdWlsZGVyIHNldERlZHVwRG93bmxvYWRXaXRoRXRhZyhib29sZWFuIGRlZHVwKSB7CisgICAgICB0aGlzLmRlZHVwRG93bmxvYWRXaXRoRXRhZyA9IGRlZHVwOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqIFNldHMgdGhlIGNvbnRleHQuICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0Q29udGV4dChDb250ZXh0IGNvbnRleHQpIHsKKyAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKiogU2V0cyB0aGUgbWFuaWZlc3QgZmlsZSBmbGFnLiAqLworICAgIHB1YmxpYyBCdWlsZGVyIHNldE1hbmlmZXN0RmlsZUZsYWdTdXBwbGllcigKKyAgICAgICAgU3VwcGxpZXI8TWFuaWZlc3RGaWxlRmxhZz4gbWFuaWZlc3RGaWxlRmxhZ1N1cHBsaWVyKSB7CisgICAgICB0aGlzLm1hbmlmZXN0RmlsZUZsYWdTdXBwbGllciA9IG1hbmlmZXN0RmlsZUZsYWdTdXBwbGllcjsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKiBTZXRzIHRoZSBmaWxlIGRvd25sb2FkZXIuICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0RmlsZURvd25sb2FkZXIoU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGZpbGVEb3dubG9hZGVyKSB7CisgICAgICB0aGlzLmZpbGVEb3dubG9hZGVyID0gZmlsZURvd25sb2FkZXI7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKiogU2V0cyB0aGUgbWFuaWZlc3QgY29uZmlnIHBhcnNlciB0aGF0IHRha2VzIGZpbGUgdXJpIGFuZCByZXR1cm5zIHtAbGluayBNYW5pZmVzdENvbmZpZ30uICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0TWFuaWZlc3RDb25maWdQYXJzZXIoTWFuaWZlc3RDb25maWdQYXJzZXIgbWFuaWZlc3RDb25maWdQYXJzZXIpIHsKKyAgICAgIHRoaXMubWFuaWZlc3RDb25maWdQYXJzZXIgPSBtYW5pZmVzdENvbmZpZ1BhcnNlcjsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKiBTZXRzIHRoZSBtb2JzdG9yZSBmaWxlIHN0b3JhZ2UuIE1vYnN0b3JlIGZpbGUgc3RvcmFnZSBtdXN0IGJlIHNpbmdsZXRvbi4gKi8KKyAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWxlU3RvcmFnZShTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlKSB7CisgICAgICB0aGlzLmZpbGVTdG9yYWdlID0gZmlsZVN0b3JhZ2U7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKiogU2V0cyB0aGUgYmFja2dyb3VuZCBleGVjdXRvciB0aGF0IGV4ZWN1dGVzIHBvcHVsYXRvcidzIHRhc2tzIHNlcXVlbnRpYWxseS4gKi8KKyAgICBwdWJsaWMgQnVpbGRlciBzZXRCYWNrZ3JvdW5kRXhlY3V0b3IoRXhlY3V0b3IgYmFja2dyb3VuZEV4ZWN1dG9yKSB7CisgICAgICB0aGlzLmJhY2tncm91bmRFeGVjdXRvciA9IGJhY2tncm91bmRFeGVjdXRvcjsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIC8qKiBTZXRzIHRoZSBNYW5pZmVzdEZpbGVNZXRhZGF0YVN0b3JlLiAqLworICAgIHB1YmxpYyBCdWlsZGVyIHNldE1ldGFkYXRhU3RvcmUoTWFuaWZlc3RGaWxlTWV0YWRhdGFTdG9yZSBtYW5pZmVzdEZpbGVNZXRhZGF0YVN0b3JlKSB7CisgICAgICB0aGlzLm1hbmlmZXN0RmlsZU1ldGFkYXRhU3RvcmUgPSBtYW5pZmVzdEZpbGVNZXRhZGF0YVN0b3JlOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqIFNldHMgdGhlIE1ERCBsb2dnZXIuICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9nZ2VyKExvZ2dlciBsb2dnZXIpIHsKKyAgICAgIHRoaXMubG9nZ2VyID0gbG9nZ2VyOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqIFNldHMgdGhlIG9wdGlvbmFsIG1hbmlmZXN0IGNvbmZpZyBvdmVycmlkZXIuICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0T3ZlcnJpZGVyT3B0aW9uYWwoT3B0aW9uYWw8TWFuaWZlc3RDb25maWdPdmVycmlkZXI+IG92ZXJyaWRlck9wdGlvbmFsKSB7CisgICAgICB0aGlzLm92ZXJyaWRlck9wdGlvbmFsID0gb3ZlcnJpZGVyT3B0aW9uYWw7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICAvKiogU2V0cyB0aGUgb3B0aW9uYWwgaW5zdGFuY2UgSUQuICovCisgICAgcHVibGljIEJ1aWxkZXIgc2V0SW5zdGFuY2VJZE9wdGlvbmFsKE9wdGlvbmFsPFN0cmluZz4gaW5zdGFuY2VJZE9wdGlvbmFsKSB7CisgICAgICB0aGlzLmluc3RhbmNlSWRPcHRpb25hbCA9IGluc3RhbmNlSWRPcHRpb25hbDsKKyAgICAgIHJldHVybiB0aGlzOworICAgIH0KKworICAgIHB1YmxpYyBCdWlsZGVyIHNldEZsYWdzKEZsYWdzIGZsYWdzKSB7CisgICAgICB0aGlzLmZsYWdzID0gZmxhZ3M7CisgICAgICByZXR1cm4gdGhpczsKKyAgICB9CisKKyAgICBwdWJsaWMgTWFuaWZlc3RGaWxlR3JvdXBQb3B1bGF0b3IgYnVpbGQoKSB7CisgICAgICBQcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChjb250ZXh0LCAiTXVzdCBjYWxsIHNldENvbnRleHQoKSBiZWZvcmUgYnVpbGQoKS4iKTsKKyAgICAgIFByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKAorICAgICAgICAgIG1hbmlmZXN0RmlsZUZsYWdTdXBwbGllciwgIk11c3QgY2FsbCBzZXRNYW5pZmVzdEZpbGVGbGFnU3VwcGxpZXIoKSBiZWZvcmUgYnVpbGQoKS4iKTsKKyAgICAgIFByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKGZpbGVEb3dubG9hZGVyLCAiTXVzdCBjYWxsIHNldEZpbGVEb3dubG9hZGVyKCkgYmVmb3JlIGJ1aWxkKCkuIik7CisgICAgICBQcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbCgKKyAgICAgICAgICBtYW5pZmVzdENvbmZpZ1BhcnNlciwgIk11c3QgY2FsbCBzZXRNYW5pZmVzdENvbmZpZ1BhcnNlcigpIGJlZm9yZSBidWlsZCgpLiIpOworICAgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwoZmlsZVN0b3JhZ2UsICJNdXN0IGNhbGwgc2V0RmlsZVN0b3JhZ2UoKSBiZWZvcmUgYnVpbGQoKS4iKTsKKyAgICAgIFByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKAorICAgICAgICAgIGJhY2tncm91bmRFeGVjdXRvciwgIk11c3QgY2FsbCBzZXRCYWNrZ3JvdW5kRXhlY3V0b3IoKSBiZWZvcmUgYnVpbGQoKS4iKTsKKyAgICAgIFByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKAorICAgICAgICAgIG1hbmlmZXN0RmlsZU1ldGFkYXRhU3RvcmUsICJNdXN0IGNhbGwgbWFuaWZlc3RGaWxlTWV0YWRhdGFTdG9yZSgpIGJlZm9yZSBidWlsZCgpLiIpOworICAgICAgUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwobG9nZ2VyLCAiTXVzdCBjYWxsIHNldExvZ2dlcigpIGJlZm9yZSBidWlsZCgpLiIpOworICAgICAgcmV0dXJuIG5ldyBNYW5pZmVzdEZpbGVHcm91cFBvcHVsYXRvcih0aGlzKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gYWxsb3dzSW5zZWN1cmVIdHRwOworICBwcml2YXRlIGZpbmFsIGJvb2xlYW4gZGVkdXBEb3dubG9hZFdpdGhFdGFnOworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dDsKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgbWFuaWZlc3REaXJlY3RvcnlVcmk7CisgIHByaXZhdGUgZmluYWwgU3VwcGxpZXI8TWFuaWZlc3RGaWxlRmxhZz4gbWFuaWZlc3RGaWxlRmxhZ1N1cHBsaWVyOworICBwcml2YXRlIGZpbmFsIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlcjsKKyAgcHJpdmF0ZSBmaW5hbCBNYW5pZmVzdENvbmZpZ1BhcnNlciBtYW5pZmVzdENvbmZpZ1BhcnNlcjsKKyAgcHJpdmF0ZSBmaW5hbCBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIGZpbmFsIEV4ZWN1dG9yIGJhY2tncm91bmRFeGVjdXRvcjsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxNYW5pZmVzdENvbmZpZ092ZXJyaWRlcj4gb3ZlcnJpZGVyT3B0aW9uYWw7CisgIHByaXZhdGUgZmluYWwgTWFuaWZlc3RGaWxlTWV0YWRhdGFTdG9yZSBtYW5pZmVzdEZpbGVNZXRhZGF0YVN0b3JlOworICBwcml2YXRlIGZpbmFsIEZpbGVHcm91cFBvcHVsYXRvckxvZ2dlciBldmVudExvZ2dlcjsKKyAgLy8gV2UgdXNlIGZ1dHVyZVNlcmlhbGl6ZXIgZm9yIHN5bmNocm9uaXphdGlvbi4KKyAgcHJpdmF0ZSBmaW5hbCBFeGVjdXRpb25TZXF1ZW5jZXIgZnV0dXJlU2VyaWFsaXplciA9IEV4ZWN1dGlvblNlcXVlbmNlci5jcmVhdGUoKTsKKworICAvKiogUmV0dXJucyBhIEJ1aWxkZXIgZm9yIHtAbGluayBNYW5pZmVzdEZpbGVHcm91cFBvcHVsYXRvcn0uICovCisgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBidWlsZGVyKCkgeworICAgIHJldHVybiBuZXcgQnVpbGRlcigpOworICB9CisKKyAgcHJpdmF0ZSBNYW5pZmVzdEZpbGVHcm91cFBvcHVsYXRvcihCdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICB0aGlzLmFsbG93c0luc2VjdXJlSHR0cCA9IGJ1aWxkZXIuYWxsb3dzSW5zZWN1cmVIdHRwOworICAgIHRoaXMuZGVkdXBEb3dubG9hZFdpdGhFdGFnID0gYnVpbGRlci5kZWR1cERvd25sb2FkV2l0aEV0YWc7CisgICAgdGhpcy5jb250ZXh0ID0gYnVpbGRlci5jb250ZXh0OworICAgIHRoaXMubWFuaWZlc3REaXJlY3RvcnlVcmkgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE1hbmlmZXN0RGlyZWN0b3J5KGJ1aWxkZXIuY29udGV4dCwgYnVpbGRlci5pbnN0YW5jZUlkT3B0aW9uYWwpOworICAgIHRoaXMubWFuaWZlc3RGaWxlRmxhZ1N1cHBsaWVyID0gYnVpbGRlci5tYW5pZmVzdEZpbGVGbGFnU3VwcGxpZXI7CisgICAgdGhpcy5maWxlRG93bmxvYWRlciA9IGJ1aWxkZXIuZmlsZURvd25sb2FkZXI7CisgICAgdGhpcy5tYW5pZmVzdENvbmZpZ1BhcnNlciA9IGJ1aWxkZXIubWFuaWZlc3RDb25maWdQYXJzZXI7CisgICAgdGhpcy5maWxlU3RvcmFnZSA9IGJ1aWxkZXIuZmlsZVN0b3JhZ2U7CisgICAgdGhpcy5iYWNrZ3JvdW5kRXhlY3V0b3IgPSBidWlsZGVyLmJhY2tncm91bmRFeGVjdXRvcjsKKyAgICB0aGlzLm92ZXJyaWRlck9wdGlvbmFsID0gYnVpbGRlci5vdmVycmlkZXJPcHRpb25hbDsKKyAgICB0aGlzLmV2ZW50TG9nZ2VyID0gbmV3IEZpbGVHcm91cFBvcHVsYXRvckxvZ2dlcihidWlsZGVyLmxvZ2dlciwgYnVpbGRlci5mbGFncyk7CisgICAgdGhpcy5tYW5pZmVzdEZpbGVNZXRhZGF0YVN0b3JlID0gYnVpbGRlci5tYW5pZmVzdEZpbGVNZXRhZGF0YVN0b3JlOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlZnJlc2hGaWxlR3JvdXBzKE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQpIHsKKyAgICByZXR1cm4gZnV0dXJlU2VyaWFsaXplci5zdWJtaXRBc3luYygKKyAgICAgICAgcHJvcGFnYXRlQXN5bmNDYWxsYWJsZSgKKyAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgTG9nVXRpbC5kKCIlczogQWRkIGdyb3VwcyBmcm9tIE1hbmlmZXN0RmlsZUZsYWcgdG8gTURELiIsIFRBRyk7CisKKyAgICAgICAgICAgICAgLy8gV2Ugd2lsbCByZXR1cm4gaW1tZWRpYXRlbHkgaWYgdGhlIGZsYWcgaXMgbnVsbCBvciBlbXB0eS4gVGhpcyBjb3VsZCBoYXBwZW4gaWYgUC9ICisgICAgICAgICAgICAgIC8vIGhhcyBub3Qgc3luY2VkIHRoZSBmbGFnIG9yIHdlIGZhaWwgdG8gcGFyc2UgdGhlIGZsYWcuCisgICAgICAgICAgICAgIE1hbmlmZXN0RmlsZUZsYWcgbWFuaWZlc3RGaWxlRmxhZyA9IG1hbmlmZXN0RmlsZUZsYWdTdXBwbGllci5nZXQoKTsKKyAgICAgICAgICAgICAgaWYgKG1hbmlmZXN0RmlsZUZsYWcgPT0gbnVsbAorICAgICAgICAgICAgICAgICAgfHwgbWFuaWZlc3RGaWxlRmxhZy5lcXVhbHMoTWFuaWZlc3RGaWxlRmxhZy5nZXREZWZhdWx0SW5zdGFuY2UoKSkpIHsKKyAgICAgICAgICAgICAgICBMb2dVdGlsLncoIiVzOiBUaGUgTWFuaWZlc3RGaWxlRmxhZyBpcyBlbXB0eS4iLCBUQUcpOworICAgICAgICAgICAgICAgIGxvZ1JlZnJlc2hSZXN1bHQoMCwgTWFuaWZlc3RGaWxlRmxhZy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIHJldHVybiByZWZyZXNoRmlsZUdyb3Vwcyhtb2JpbGVEYXRhRG93bmxvYWQsIG1hbmlmZXN0RmlsZUZsYWcpOworICAgICAgICAgICAgfSksCisgICAgICAgIGJhY2tncm91bmRFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVmcmVzaEZpbGVHcm91cHMoCisgICAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkLCBNYW5pZmVzdEZpbGVGbGFnIG1hbmlmZXN0RmlsZUZsYWcpIHsKKworICAgIGlmICghdmFsaWRhdGUobWFuaWZlc3RGaWxlRmxhZykpIHsKKyAgICAgIGxvZ1JlZnJlc2hSZXN1bHQoMCwgbWFuaWZlc3RGaWxlRmxhZyk7CisgICAgICBMb2dVdGlsLmUoIiVzOiBJbnZhbGlkIG1hbmlmZXN0IGNvbmZpZyBmcm9tIG1hbmlmZXN0IGZsYWcuIiwgVEFHKTsKKyAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUobmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiSW52YWxpZCBtYW5pZmVzdCBmbGFnLiIpKTsKKyAgICB9CisKKyAgICBTdHJpbmcgbWFuaWZlc3RGaWxlVXJsID0gbWFuaWZlc3RGaWxlRmxhZy5nZXRNYW5pZmVzdEZpbGVVcmwoKTsKKworICAgIC8vIE1hbmlmZXN0IGZpbGVzIGFyZSBuYW1lZCBhbmQgaWRlbnRpZmllZCB3aXRoIHRoZWlyIG1hbmlmZXN0IElELgorICAgIFVyaSBtYW5pZmVzdEZpbGVVcmkgPQorICAgICAgICBtYW5pZmVzdERpcmVjdG9yeVVyaS5idWlsZFVwb24oKS5hcHBlbmRQYXRoKG1hbmlmZXN0RmlsZUZsYWcuZ2V0TWFuaWZlc3RJZCgpKS5idWlsZCgpOworCisgICAgLy8gUmVwcmVzZW50cyB0aGUgaW50ZXJuYWwgc3RhdGUgb2YgdGhlIG1ldGFkYXRhLiBVc2luZyBBdG9taWNSZWZlcmVuY2UgaGVyZSBiZWNhdXNlIHRoZQorICAgIC8vIHZhcmlhYmxlIGNhcHR1cmVkIGJ5IGxhbWJkYSBuZWVkcyB0byBiZSBmaW5hbC4KKyAgICBmaW5hbCBBdG9taWNSZWZlcmVuY2U8TWFuaWZlc3RGaWxlQm9va2tlZXBpbmc+IGJvb2trZWVwaW5nUmVmID0KKyAgICAgICAgbmV3IEF0b21pY1JlZmVyZW5jZTw+KGNyZWF0ZURlZmF1bHRNYW5pZmVzdEZpbGVCb29ra2VlcGluZyhtYW5pZmVzdEZpbGVVcmwpKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gY2hlY2tGdXR1cmUgPQorICAgICAgICBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlLmZyb20ocmVhZEJvb2tlZXBpbmcobWFuaWZlc3RGaWxlRmxhZy5nZXRNYW5pZmVzdElkKCkpKQorICAgICAgICAgICAgLnRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICAoZmluYWwgT3B0aW9uYWw8TWFuaWZlc3RGaWxlQm9va2tlZXBpbmc+IGJvb2trZWVwaW5nT3B0aW9uYWwpIC0+IHsKKyAgICAgICAgICAgICAgICAgIGlmIChib29ra2VlcGluZ09wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICAgICAgICAgIGJvb2trZWVwaW5nUmVmLnNldChib29ra2VlcGluZ09wdGlvbmFsLmdldCgpKTsKKyAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIHJldHVybiAoVm9pZCkgbnVsbDsKKyAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgIGJhY2tncm91bmRFeGVjdXRvcikKKyAgICAgICAgICAgIC50cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICAgICAgICB2b2lkQXJnIC0+CisgICAgICAgICAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gY2FsbCBjaGVja0ZvckNvbnRlbnRDaGFuZ2VCZWZvcmVEb3dubG9hZCB0byBzeW5jIGJhY2sgdGhlIGxhdGVzdAorICAgICAgICAgICAgICAgICAgICAvLyBFVGFnLCBldmVuIHdoZW4gdGhlcmUgaXMgbm8gZW50cnkgZm9yIGJvb2trZWVwaW5nLgorICAgICAgICAgICAgICAgICAgICBjaGVja0ZvckNvbnRlbnRDaGFuZ2VCZWZvcmVEb3dubG9hZCgKKyAgICAgICAgICAgICAgICAgICAgICAgIG1hbmlmZXN0RmlsZVVybCwgbWFuaWZlc3RGaWxlVXJpLCBib29ra2VlcGluZ1JlZiksCisgICAgICAgICAgICAgICAgYmFja2dyb3VuZEV4ZWN1dG9yKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8T3B0aW9uYWw8VGhyb3dhYmxlPj4gdHJhbnNmb3JtQ2hlY2tGdXR1cmUgPQorICAgICAgICBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlLmZyb20oY2hlY2tGdXR1cmUpCisgICAgICAgICAgICAudHJhbnNmb3JtKHZvaWRBcmcgLT4gT3B0aW9uYWwuPFRocm93YWJsZT5hYnNlbnQoKSwgYmFja2dyb3VuZEV4ZWN1dG9yKQorICAgICAgICAgICAgLmNhdGNoaW5nKFRocm93YWJsZS5jbGFzcywgT3B0aW9uYWw6Om9mLCBiYWNrZ3JvdW5kRXhlY3V0b3IpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBwcm9jZXNzRnV0dXJlID0KKyAgICAgICAgUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKHRyYW5zZm9ybUNoZWNrRnV0dXJlKQorICAgICAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICAgIChmaW5hbCBPcHRpb25hbDxUaHJvd2FibGU+IHRocm93YWJsZU9wdGlvbmFsKSAtPiB7CisgICAgICAgICAgICAgICAgICAvLyBXZSBkbyBub3Qgd2FudCB0byBwcm9jZWVkIGlmIHRyYW5zZm9ybUNoZWNrRnV0dXJlIGNvbnRhaW5zIGZhaWx1cmVzLCBzbyByZXR1cm4KKyAgICAgICAgICAgICAgICAgIC8vIGVhcmx5LgorICAgICAgICAgICAgICAgICAgaWYgKHRocm93YWJsZU9wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgIE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nIGJvb2trZWVwaW5nID0gYm9va2tlZXBpbmdSZWYuZ2V0KCk7CisKKyAgICAgICAgICAgICAgICAgIGlmIChib29ra2VlcGluZy5nZXRTdGF0dXMoKSA9PSBTdGF0dXMuQ09NTUlUVEVEKSB7CisgICAgICAgICAgICAgICAgICAgIExvZ1V0aWwuZCgiJXM6IE1hbmlmZXN0IGZpbGUgd2FzIGNvbW1pdHRlZC4iLCBUQUcpOworICAgICAgICAgICAgICAgICAgICBpZiAoIW92ZXJyaWRlck9wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gdGhlIG92ZXJyaWRlciBpcyBwcmVzZW50LCBpdCBtYXkgcHJvZHVjZSBkaWZmZXJlbnQgY29uZmlncyBlYWNoIHRpbWUgdGhlCisgICAgICAgICAgICAgICAgICAgIC8vIGNhbGxlciB0cmlnZ2VycyByZWZyZXNoLiBUaGVyZWZvcmUsIHdlIG5lZWQgdG8gcmVjb21taXQgdG8gTURELgorICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmQoIiVzOiBPdmVycmlkZXIgaXMgcHJlc2VudCwgY29tbWl0IGFnYWluLiIsIFRBRyk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUFuZENvbW1pdE1hbmlmZXN0RmlsZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZCwgbWFuaWZlc3RGaWxlVXJpLCBib29ra2VlcGluZ1JlZik7CisgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgIGlmIChib29ra2VlcGluZy5nZXRTdGF0dXMoKSA9PSBTdGF0dXMuRE9XTkxPQURFRCkgeworICAgICAgICAgICAgICAgICAgICBMb2dVdGlsLmQoIiVzOiBNYW5pZmVzdCBmaWxlIHdhcyBkb3dubG9hZGVkLiIsIFRBRyk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUFuZENvbW1pdE1hbmlmZXN0RmlsZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZCwgbWFuaWZlc3RGaWxlVXJpLCBib29ra2VlcGluZ1JlZik7CisgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlLmZyb20oCisgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkTWFuaWZlc3RGaWxlKG1hbmlmZXN0RmlsZVVybCwgbWFuaWZlc3RGaWxlVXJpKSkKKyAgICAgICAgICAgICAgICAgICAgICAudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWRBcmdJbm5lciAtPgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tGb3JDb250ZW50Q2hhbmdlQWZ0ZXJEb3dubG9hZCgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYW5pZmVzdEZpbGVVcmwsIG1hbmlmZXN0RmlsZVVyaSwgYm9va2tlZXBpbmdSZWYpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kRXhlY3V0b3IpCisgICAgICAgICAgICAgICAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkQXJnSW5uZXIgLT4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlQW5kQ29tbWl0TWFuaWZlc3RGaWxlKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZCwgbWFuaWZlc3RGaWxlVXJpLCBib29ra2VlcGluZ1JlZiksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRFeGVjdXRvcik7CisgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kRXhlY3V0b3IpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjYXRjaGluZ1Byb2Nlc3NGdXR1cmUgPQorICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy5jYXRjaGluZ0FzeW5jKAorICAgICAgICAgICAgcHJvY2Vzc0Z1dHVyZSwKKyAgICAgICAgICAgIFRocm93YWJsZS5jbGFzcywKKyAgICAgICAgICAgIChUaHJvd2FibGUgdW51c2VkKSAtPiB7CisgICAgICAgICAgICAgIE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nIGJvb2trZWVwaW5nID0gYm9va2tlZXBpbmdSZWYuZ2V0KCk7CisgICAgICAgICAgICAgIGJvb2trZWVwaW5nUmVmLnNldChib29ra2VlcGluZy50b0J1aWxkZXIoKS5zZXRTdGF0dXMoU3RhdHVzLlBFTkRJTkcpLmJ1aWxkKCkpOworICAgICAgICAgICAgICBkZWxldGVNYW5pZmVzdEZpbGVDaGVja2VkKG1hbmlmZXN0RmlsZVVyaSk7CisgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgYmFja2dyb3VuZEV4ZWN1dG9yKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gdXBkYXRlRnV0dXJlID0KKyAgICAgICAgUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICBjYXRjaGluZ1Byb2Nlc3NGdXR1cmUsCisgICAgICAgICAgICB2b2lkQXJnIC0+IHdyaXRlQm9va2tlZXBpbmcobWFuaWZlc3RGaWxlRmxhZy5nZXRNYW5pZmVzdElkKCksIGJvb2trZWVwaW5nUmVmLmdldCgpKSwKKyAgICAgICAgICAgIGJhY2tncm91bmRFeGVjdXRvcik7CisKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIHVwZGF0ZUZ1dHVyZSwKKyAgICAgICAgdm9pZEFyZyAtPiB7CisgICAgICAgICAgbG9nQW5kVGhyb3dJZkZhaWxlZCgKKyAgICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihjaGVja0Z1dHVyZSwgcHJvY2Vzc0Z1dHVyZSwgdXBkYXRlRnV0dXJlKSwKKyAgICAgICAgICAgICAgIkZhaWxlZCB0byByZWZyZXNoIGZpbGUgZ3JvdXBzIiwKKyAgICAgICAgICAgICAgbWFuaWZlc3RGaWxlRmxhZyk7CisgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgYW55IGZhaWx1cmUsIGl0IHNob3VsZCBoYXZlIGJlZW4gdGhyb3duIGFscmVhZHkuIFRoZXJlZm9yZSwgd2UgbG9nIHJlZnJlc2gKKyAgICAgICAgICAvLyBzdWNjZXNzIGhlcmUuCisgICAgICAgICAgbG9nUmVmcmVzaFJlc3VsdCgwLCBtYW5pZmVzdEZpbGVGbGFnKTsKKyAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICB9LAorICAgICAgICBiYWNrZ3JvdW5kRXhlY3V0b3IpOworICB9CisKKyAgcHJpdmF0ZSBib29sZWFuIHZhbGlkYXRlKEBOdWxsYWJsZSBNYW5pZmVzdEZpbGVGbGFnIG1hbmlmZXN0RmlsZUZsYWcpIHsKKyAgICBpZiAobWFuaWZlc3RGaWxlRmxhZyA9PSBudWxsKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmICghbWFuaWZlc3RGaWxlRmxhZy5oYXNNYW5pZmVzdElkKCkgfHwgbWFuaWZlc3RGaWxlRmxhZy5nZXRNYW5pZmVzdElkKCkuaXNFbXB0eSgpKSB7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorICAgIGlmICghbWFuaWZlc3RGaWxlRmxhZy5oYXNNYW5pZmVzdEZpbGVVcmwoKQorICAgICAgICB8fCAoIWFsbG93c0luc2VjdXJlSHR0cCAmJiAhbWFuaWZlc3RGaWxlRmxhZy5nZXRNYW5pZmVzdEZpbGVVcmwoKS5zdGFydHNXaXRoKCJodHRwcyIpKSkgeworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBwYXJzZUFuZENvbW1pdE1hbmlmZXN0RmlsZSgKKyAgICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQsCisgICAgICBVcmkgbWFuaWZlc3RGaWxlVXJpLAorICAgICAgQXRvbWljUmVmZXJlbmNlPE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nPiBib29ra2VlcGluZ1JlZikgeworICAgIHJldHVybiBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlLmZyb20ocGFyc2VNYW5pZmVzdEZpbGUobWFuaWZlc3RGaWxlVXJpKSkKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgKGZpbmFsIE1hbmlmZXN0Q29uZmlnIG1hbmlmZXN0Q29uZmlnKSAtPgorICAgICAgICAgICAgICAgIE1hbmlmZXN0Q29uZmlnSGVscGVyLnJlZnJlc2hGcm9tTWFuaWZlc3RDb25maWcoCisgICAgICAgICAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZCwgbWFuaWZlc3RDb25maWcsIG92ZXJyaWRlck9wdGlvbmFsKSwKKyAgICAgICAgICAgIGJhY2tncm91bmRFeGVjdXRvcikKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgdm9pZEFyZyAtPiB7CisgICAgICAgICAgICAgIE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nIGJvb2trZWVwaW5nID0gYm9va2tlZXBpbmdSZWYuZ2V0KCk7CisgICAgICAgICAgICAgIGJvb2trZWVwaW5nUmVmLnNldChib29ra2VlcGluZy50b0J1aWxkZXIoKS5zZXRTdGF0dXMoU3RhdHVzLkNPTU1JVFRFRCkuYnVpbGQoKSk7CisgICAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICB9LAorICAgICAgICAgICAgYmFja2dyb3VuZEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZE1hbmlmZXN0RmlsZShTdHJpbmcgdXJsVG9Eb3dubG9hZCwgVXJpIGRlc3RpbmF0aW9uVXJpKSB7CisgICAgTG9nVXRpbC5kKAorICAgICAgICAiJXM6IFN0YXJ0IGRvd25sb2FkaW5nIHRoZSBtYW5pZmVzdCBmaWxlIGZyb20gJXMgdG8gJXMuIiwKKyAgICAgICAgVEFHLCB1cmxUb0Rvd25sb2FkLCBkZXN0aW5hdGlvblVyaS50b1N0cmluZygpKTsKKworICAgIC8vIFdlIG5vdyBkb3dubG9hZCBtYW5pZmVzdCBmaWxlIG9uIGFueSBuZXR3b3JrIChzaW1pbGFyIHRvIFAvSCkuIEluIHRoZSBmdXR1cmUsIHdlIG1heSB3YW50IHRvCisgICAgLy8gcmVzdHJpY3QgdGhlIGRvd25sb2FkIG9ubHkgb24gV2lGaSwgYW5kIG5lZWQgdG8gaW50cm9kdWNlIG5ldHdvcmsgcG9saWN5LiAoSG93ZXZlciwgc29tZQorICAgIC8vIHVzZXJzIGFyZSBuZXZlciBvbiBXaUZpKQorICAgIC8vCisgICAgLy8gTm90ZTogUmlnaHQgbm93LCBpZiB0aGUgZG93bmxvYWQgb2YgbWFuaWZlc3QgY29uZmlnIGZpbGUgaXMgc2V0IHRvIFdpRmkgb25seSBidXQgdGhpcworICAgIC8vIHBvcHVsYXRvciBpcyB0cmlnZ2VyZWQgaW4gQ0VMTFVMQVJfQ0hBUkdJTkcgdGFzaywgdGhlbiB0aGUgZG93bmxvYWRpbmcgd2lsbCBiZSBibG9ja2VkLgorICAgIERvd25sb2FkQ29uc3RyYWludHMgZG93bmxvYWRDb25zdHJhaW50cyA9IERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQ7CisKKyAgICByZXR1cm4gZmlsZURvd25sb2FkZXIKKyAgICAgICAgLmdldCgpCisgICAgICAgIC5zdGFydERvd25sb2FkaW5nKAorICAgICAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKHVybFRvRG93bmxvYWQpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmkoZGVzdGluYXRpb25VcmkpCisgICAgICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoZG93bmxvYWRDb25zdHJhaW50cykKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8TWFuaWZlc3RDb25maWc+IHBhcnNlTWFuaWZlc3RGaWxlKFVyaSBtYW5pZmVzdEZpbGVVcmkpIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBQYXJzZSB0aGUgbWFuaWZlc3QgZmlsZSBhdCAlcy4iLCBUQUcsIG1hbmlmZXN0RmlsZVVyaSk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPE1hbmlmZXN0Q29uZmlnPiBwYXJzZUZ1dHVyZSA9IG1hbmlmZXN0Q29uZmlnUGFyc2VyLnBhcnNlKG1hbmlmZXN0RmlsZVVyaSk7CisgICAgcmV0dXJuIERvd25sb2FkRXhjZXB0aW9uLndyYXBJZkZhaWxlZCgKKyAgICAgICAgcGFyc2VGdXR1cmUsCisgICAgICAgIERvd25sb2FkUmVzdWx0Q29kZS5NQU5JRkVTVF9GSUxFX0dST1VQX1BPUFVMQVRPUl9QQVJTRV9NQU5JRkVTVF9GSUxFX0VSUk9SLAorICAgICAgICAiRmFpbGVkIHRvIHBhcnNlIHRoZSBtYW5pZmVzdCBmaWxlLiIpOworICB9CisKKyAgcHJpdmF0ZSBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGNoZWNrRm9yQ29udGVudENoYW5nZUJlZm9yZURvd25sb2FkKAorICAgICAgU3RyaW5nIHVybFRvRG93bmxvYWQsCisgICAgICBVcmkgbWFuaWZlc3RGaWxlVXJpLAorICAgICAgQXRvbWljUmVmZXJlbmNlPE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nPiBib29ra2VlcGluZ1JlZikgeworICAgIExvZ1V0aWwuZCgiJXM6IFByZXBhcmUgZm9yIGRvd25sb2FkaW5nIG1hbmlmZXN0IGZpbGUuIiwgVEFHKTsKKworICAgIGlmICghZGVkdXBEb3dubG9hZFdpdGhFdGFnKSB7CisgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgIH0KKworICAgIE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nIGJvb2trZWVwaW5nID0gYm9va2tlZXBpbmdSZWYuZ2V0KCk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPENoZWNrQ29udGVudENoYW5nZVJlc3BvbnNlPiBpc0NvbnRlbnRDaGFuZ2VkRnV0dXJlID0KKyAgICAgICAgZmlsZURvd25sb2FkZXIKKyAgICAgICAgICAgIC5nZXQoKQorICAgICAgICAgICAgLmlzQ29udGVudENoYW5nZWQoCisgICAgICAgICAgICAgICAgQ2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldFVybCh1cmxUb0Rvd25sb2FkKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2FjaGVkRVRhZ09wdGlvbmFsKGdldENhY2hlZEVUYWcoYm9va2tlZXBpbmcpKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgIGlzQ29udGVudENoYW5nZWRGdXR1cmUsCisgICAgICAgIChmaW5hbCBDaGVja0NvbnRlbnRDaGFuZ2VSZXNwb25zZSByZXNwb25zZSkgLT4geworICAgICAgICAgIFN0YXR1cyBjdXJyZW50U3RhdHVzID0gYm9va2tlZXBpbmdSZWYuZ2V0KCkuZ2V0U3RhdHVzKCk7CisKKyAgICAgICAgICAvLyBJZiB0aGUgbWFuaWZlc3QgZmlsZSBvbiBzZXJ2ZXIgc2lkZSBoYXMgYmVlbiBtb2RpZmllZCBzaW5jZSBsYXN0IGRvd25sb2FkLCB0aGVuIHRoZQorICAgICAgICAgIC8vIG1hbmlmZXN0IGZpbGUgcHJldmlvdXNseSBkb3dubG9hZGVkIGlzIG5vdyBzdGFsZS4gV2UgbmVlZCB0byBkZWxldGUgaXQgYW5kIHJlLWRvd25sb2FkCisgICAgICAgICAgLy8gdGhlIGxhdGVzdCB2ZXJzaW9uLgorICAgICAgICAgIC8vCisgICAgICAgICAgLy8gSW4gY2FzZSBvZiB1cmwgY2hhbmdlcywgd2Ugc3RpbGwgd2FudCB0byBzZW5kIHRoZSBuZXR3b3JrIHJlcXVlc3QgdG8gZmV0Y2ggdGhlIEVUYWcuCisgICAgICAgICAgYm9vbGVhbiB1cmxVcGRhdGVkID0gIXVybFRvRG93bmxvYWQuZXF1YWxzKGJvb2trZWVwaW5nLmdldE1hbmlmZXN0RmlsZVVybCgpKTsKKyAgICAgICAgICBpZiAodXJsVXBkYXRlZCB8fCByZXNwb25zZS5jb250ZW50Q2hhbmdlZCgpKSB7CisgICAgICAgICAgICBMb2dVdGlsLmQoCisgICAgICAgICAgICAgICAgIiVzOiBNYW5pZmVzdCBmaWxlIG9uIHNlcnZlciB1cGRhdGVkLCB3aWxsIHJlLWRvd25sb2FkOyB1cmxUb0Rvd25sb2FkID0gJXM7IgorICAgICAgICAgICAgICAgICAgICArICIgbWFuaWZlc3RGaWxlVXJpID0gJXMiLAorICAgICAgICAgICAgICAgIFRBRywgdXJsVG9Eb3dubG9hZCwgbWFuaWZlc3RGaWxlVXJpKTsKKyAgICAgICAgICAgIGN1cnJlbnRTdGF0dXMgPSBTdGF0dXMuUEVORElORzsKKyAgICAgICAgICAgIGRlbGV0ZU1hbmlmZXN0RmlsZUNoZWNrZWQobWFuaWZlc3RGaWxlVXJpKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICBib29ra2VlcGluZ1JlZi5zZXQoCisgICAgICAgICAgICAgIGNyZWF0ZU1hbmlmZXN0RmlsZUJvb2trZWVwaW5nKAorICAgICAgICAgICAgICAgICAgdXJsVG9Eb3dubG9hZCwgY3VycmVudFN0YXR1cywgcmVzcG9uc2UuZnJlc2hFVGFnT3B0aW9uYWwoKSkpOworCisgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgfSwKKyAgICAgICAgYmFja2dyb3VuZEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjaGVja0ZvckNvbnRlbnRDaGFuZ2VBZnRlckRvd25sb2FkKAorICAgICAgU3RyaW5nIHVybFRvRG93bmxvYWQsCisgICAgICBVcmkgbWFuaWZlc3RGaWxlVXJpLAorICAgICAgQXRvbWljUmVmZXJlbmNlPE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nPiBib29ra2VlcGluZ1JlZikgeworICAgIExvZ1V0aWwuZCgiJXM6IEZpbmFsaXplIGZvciBkb3dubG9hZGluZyBtYW5pZmVzdCBmaWxlLiIsIFRBRyk7CisKKyAgICBpZiAoIWRlZHVwRG93bmxvYWRXaXRoRXRhZykgeworICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICB9CisKKyAgICBNYW5pZmVzdEZpbGVCb29ra2VlcGluZyBib29ra2VlcGluZyA9IGJvb2trZWVwaW5nUmVmLmdldCgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxDaGVja0NvbnRlbnRDaGFuZ2VSZXNwb25zZT4gaXNDb250ZW50Q2hhbmdlZEZ1dHVyZSA9CisgICAgICAgIGZpbGVEb3dubG9hZGVyCisgICAgICAgICAgICAuZ2V0KCkKKyAgICAgICAgICAgIC5pc0NvbnRlbnRDaGFuZ2VkKAorICAgICAgICAgICAgICAgIENoZWNrQ29udGVudENoYW5nZVJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRVcmwodXJsVG9Eb3dubG9hZCkKKyAgICAgICAgICAgICAgICAgICAgLnNldENhY2hlZEVUYWdPcHRpb25hbChnZXRDYWNoZWRFVGFnKGJvb2trZWVwaW5nKSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworCisgICAgcmV0dXJuIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICBpc0NvbnRlbnRDaGFuZ2VkRnV0dXJlLAorICAgICAgICAoZmluYWwgQ2hlY2tDb250ZW50Q2hhbmdlUmVzcG9uc2UgcmVzcG9uc2UpIC0+IHsKKyAgICAgICAgICAvLyBJZiB0aGUgbWFuaWZlc3QgZmlsZSBvbiBzZXJ2ZXIgaGFzIGNoYW5nZWQgZHVyaW5nIGRvd25sb2FkLiBUaGUgbWFuaWZlc3QgZmlsZSB3ZSBqdXN0CisgICAgICAgICAgLy8gZG93bmxvYWRlZCBpcyBzdGFsZSBkdXJpbmcgdGhlIGRvd25sb2FkLgorICAgICAgICAgIGlmIChyZXNwb25zZS5jb250ZW50Q2hhbmdlZCgpKSB7CisgICAgICAgICAgICBMb2dVdGlsLmUoCisgICAgICAgICAgICAgICAgIiVzOiBNYW5pZmVzdCBmaWxlIG9uIHNlcnZlciBjaGFuZ2VkIGR1cmluZyBkb3dubG9hZCwgZG93bmxvYWQgZmFpbGVkOyIKKyAgICAgICAgICAgICAgICAgICAgKyAiIHVybFRvRG93bmxvYWQgPSAlczsgbWFuaWZlc3RGaWxlVXJpID0gJXMiLAorICAgICAgICAgICAgICAgIFRBRywgdXJsVG9Eb3dubG9hZCwgbWFuaWZlc3RGaWxlVXJpKTsKKyAgICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoCisgICAgICAgICAgICAgICAgICAgICAgICBEb3dubG9hZFJlc3VsdENvZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuTUFOSUZFU1RfRklMRV9HUk9VUF9QT1BVTEFUT1JfQ09OVEVOVF9DSEFOR0VEX0RVUklOR19ET1dOTE9BRF9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgLnNldE1lc3NhZ2UoIk1hbmlmZXN0IGZpbGUgb24gc2VydmVyIGNoYW5nZWQgZHVyaW5nIGRvd25sb2FkLiIpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICBib29ra2VlcGluZ1JlZi5zZXQoCisgICAgICAgICAgICAgIGNyZWF0ZU1hbmlmZXN0RmlsZUJvb2trZWVwaW5nKAorICAgICAgICAgICAgICAgICAgdXJsVG9Eb3dubG9hZCwgU3RhdHVzLkRPV05MT0FERUQsIHJlc3BvbnNlLmZyZXNoRVRhZ09wdGlvbmFsKCkpKTsKKworICAgICAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgIH0sCisgICAgICAgIGJhY2tncm91bmRFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8T3B0aW9uYWw8TWFuaWZlc3RGaWxlQm9va2tlZXBpbmc+PiByZWFkQm9va2VlcGluZyhTdHJpbmcgbWFuaWZlc3RJZCkgeworICAgIHJldHVybiBEb3dubG9hZEV4Y2VwdGlvbi53cmFwSWZGYWlsZWQoCisgICAgICAgIG1hbmlmZXN0RmlsZU1ldGFkYXRhU3RvcmUucmVhZChtYW5pZmVzdElkKSwKKyAgICAgICAgRG93bmxvYWRSZXN1bHRDb2RlLk1BTklGRVNUX0ZJTEVfR1JPVVBfUE9QVUxBVE9SX01FVEFEQVRBX0lPX0VSUk9SLAorICAgICAgICAiRmFpbGVkIHRvIHJlYWQgYm9va2tlZXBpbmcuIik7CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gd3JpdGVCb29ra2VlcGluZygKKyAgICAgIFN0cmluZyBtYW5pZmVzdElkLCBNYW5pZmVzdEZpbGVCb29ra2VlcGluZyB2YWx1ZSkgeworICAgIHJldHVybiBEb3dubG9hZEV4Y2VwdGlvbi53cmFwSWZGYWlsZWQoCisgICAgICAgIG1hbmlmZXN0RmlsZU1ldGFkYXRhU3RvcmUudXBzZXJ0KG1hbmlmZXN0SWQsIHZhbHVlKSwKKyAgICAgICAgRG93bmxvYWRSZXN1bHRDb2RlLk1BTklGRVNUX0ZJTEVfR1JPVVBfUE9QVUxBVE9SX01FVEFEQVRBX0lPX0VSUk9SLAorICAgICAgICAiRmFpbGVkIHRvIHdyaXRlIGJvb2trZWVwaW5nLiIpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGRlbGV0ZU1hbmlmZXN0RmlsZUNoZWNrZWQoVXJpIG1hbmlmZXN0RmlsZVVyaSkgdGhyb3dzIERvd25sb2FkRXhjZXB0aW9uIHsKKyAgICB0cnkgeworICAgICAgZGVsZXRlTWFuaWZlc3RGaWxlKG1hbmlmZXN0RmlsZVVyaSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgLnNldENhdXNlKGUpCisgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZSgKKyAgICAgICAgICAgICAgRG93bmxvYWRSZXN1bHRDb2RlLk1BTklGRVNUX0ZJTEVfR1JPVVBfUE9QVUxBVE9SX0RFTEVURV9NQU5JRkVTVF9GSUxFX0VSUk9SKQorICAgICAgICAgIC5zZXRNZXNzYWdlKCJGYWlsZWQgdG8gZGVsZXRlIG1hbmlmZXN0IGZpbGUuIikKKyAgICAgICAgICAuYnVpbGQoKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgZGVsZXRlTWFuaWZlc3RGaWxlKFVyaSBtYW5pZmVzdEZpbGVVcmkpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgaWYgKGZpbGVTdG9yYWdlLmV4aXN0cyhtYW5pZmVzdEZpbGVVcmkpKSB7CisgICAgICBMb2dVdGlsLmQoIiVzOiBSZW1vdmluZyBtYW5pZmVzdCBmaWxlIGF0OiAlcyIsIFRBRywgbWFuaWZlc3RGaWxlVXJpKTsKKyAgICAgIGZpbGVTdG9yYWdlLmRlbGV0ZUZpbGUobWFuaWZlc3RGaWxlVXJpKTsKKyAgICB9IGVsc2UgeworICAgICAgTG9nVXRpbC5kKCIlczogTWFuaWZlc3QgZmlsZSBkb2Vzbid0IGV4aXN0OiAlcyIsIFRBRywgbWFuaWZlc3RGaWxlVXJpKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgbG9nUmVmcmVzaFJlc3VsdChEb3dubG9hZEV4Y2VwdGlvbiBlLCBNYW5pZmVzdEZpbGVGbGFnIG1hbmlmZXN0RmlsZUZsYWcpIHsKKyAgICBldmVudExvZ2dlci5sb2dNYW5pZmVzdEZpbGVHcm91cFBvcHVsYXRvclJlZnJlc2hSZXN1bHQoCisgICAgICAgIDAsCisgICAgICAgIG1hbmlmZXN0RmlsZUZsYWcuZ2V0TWFuaWZlc3RJZCgpLAorICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgIG1hbmlmZXN0RmlsZUZsYWcuZ2V0TWFuaWZlc3RGaWxlVXJsKCkpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGxvZ1JlZnJlc2hSZXN1bHQoaW50IGNvZGUsIE1hbmlmZXN0RmlsZUZsYWcgbWFuaWZlc3RGaWxlRmxhZykgeworICAgIGV2ZW50TG9nZ2VyLmxvZ01hbmlmZXN0RmlsZUdyb3VwUG9wdWxhdG9yUmVmcmVzaFJlc3VsdCgKKyAgICAgICAgY29kZSwKKyAgICAgICAgbWFuaWZlc3RGaWxlRmxhZy5nZXRNYW5pZmVzdElkKCksCisgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgbWFuaWZlc3RGaWxlRmxhZy5nZXRNYW5pZmVzdEZpbGVVcmwoKSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgbG9nQW5kVGhyb3dJZkZhaWxlZCgKKyAgICAgIEltbXV0YWJsZUxpc3Q8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4gZnV0dXJlcywKKyAgICAgIFN0cmluZyBtZXNzYWdlLAorICAgICAgTWFuaWZlc3RGaWxlRmxhZyBtYW5pZmVzdEZpbGVGbGFnKQorICAgICAgdGhyb3dzIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiB7CisgICAgRnV0dXJlQ2FsbGJhY2s8Vm9pZD4gbG9nUmVmcmVzaFJlc3VsdENhbGxiYWNrID0KKyAgICAgICAgbmV3IEZ1dHVyZUNhbGxiYWNrPFZvaWQ+KCkgeworICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgIHB1YmxpYyB2b2lkIG9uU3VjY2VzcyhWb2lkIHVudXNlZCkge30KKworICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgIHB1YmxpYyB2b2lkIG9uRmFpbHVyZShUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBEb3dubG9hZEV4Y2VwdGlvbikgeworICAgICAgICAgICAgICBsb2dSZWZyZXNoUmVzdWx0KChEb3dubG9hZEV4Y2VwdGlvbikgdCwgbWFuaWZlc3RGaWxlRmxhZyk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAvLyBIZXJlLCB3ZSBlbmNvdW50ZXJlZCBhbiBlcnJvciB0aGF0IGlzIHVuY2hlY2tlZC4gSWYgVU5LTk9XTl9FUlJPUiBpcyBvYnNlcnZlZCwgd2UKKyAgICAgICAgICAgICAgLy8gd2lsbCBuZWVkIHRvIGludmVzdGlnYXRlIHRoZSBjYXVzZSBhbmQgaGF2ZSBpdCBjaGVja2VkLgorICAgICAgICAgICAgICBsb2dSZWZyZXNoUmVzdWx0KAorICAgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgLnNldENhdXNlKHQpCisgICAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgICAuc2V0TWVzc2FnZSgiUmVmcmVzaCBmYWlsZWQuIikKKyAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSwKKyAgICAgICAgICAgICAgICAgIG1hbmlmZXN0RmlsZUZsYWcpOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICBBZ2dyZWdhdGVFeGNlcHRpb24udGhyb3dJZkZhaWxlZChmdXR1cmVzLCBPcHRpb25hbC5vZihsb2dSZWZyZXNoUmVzdWx0Q2FsbGJhY2spLCBtZXNzYWdlKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nIGNyZWF0ZURlZmF1bHRNYW5pZmVzdEZpbGVCb29ra2VlcGluZygKKyAgICAgIFN0cmluZyBtYW5pZmVzdEZpbGVVcmwpIHsKKyAgICByZXR1cm4gY3JlYXRlTWFuaWZlc3RGaWxlQm9va2tlZXBpbmcoCisgICAgICAgIG1hbmlmZXN0RmlsZVVybCwgU3RhdHVzLlBFTkRJTkcsIC8qIGVUYWdPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nIGNyZWF0ZU1hbmlmZXN0RmlsZUJvb2trZWVwaW5nKAorICAgICAgU3RyaW5nIG1hbmlmZXN0RmlsZVVybCwgU3RhdHVzIHN0YXR1cywgT3B0aW9uYWw8U3RyaW5nPiBlVGFnT3B0aW9uYWwpIHsKKyAgICBNYW5pZmVzdEZpbGVCb29ra2VlcGluZy5CdWlsZGVyIGJvb2trZWVwaW5nID0KKyAgICAgICAgTWFuaWZlc3RGaWxlQm9va2tlZXBpbmcubmV3QnVpbGRlcigpLnNldE1hbmlmZXN0RmlsZVVybChtYW5pZmVzdEZpbGVVcmwpLnNldFN0YXR1cyhzdGF0dXMpOworICAgIGlmIChlVGFnT3B0aW9uYWwuaXNQcmVzZW50KCkpIHsKKyAgICAgIGJvb2trZWVwaW5nLnNldENhY2hlZEV0YWcoZVRhZ09wdGlvbmFsLmdldCgpKTsKKyAgICB9CisgICAgcmV0dXJuIGJvb2trZWVwaW5nLmJ1aWxkKCk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBPcHRpb25hbDxTdHJpbmc+IGdldENhY2hlZEVUYWcoTWFuaWZlc3RGaWxlQm9va2tlZXBpbmcgYm9va2tlZXBpbmcpIHsKKyAgICByZXR1cm4gYm9va2tlZXBpbmcuaGFzQ2FjaGVkRXRhZygpCisgICAgICAgID8gT3B0aW9uYWwub2YoYm9va2tlZXBpbmcuZ2V0Q2FjaGVkRXRhZygpKQorICAgICAgICA6IE9wdGlvbmFsLmFic2VudCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9NYW5pZmVzdEZpbGVNZXRhZGF0YVN0b3JlLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9NYW5pZmVzdEZpbGVNZXRhZGF0YVN0b3JlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGQ4MDA4MAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01hbmlmZXN0RmlsZU1ldGFkYXRhU3RvcmUuamF2YQpAQCAtMCwwICsxLDI5IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5wb3B1bGF0b3I7CisKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5wb3B1bGF0b3IuTWV0YWRhdGFQcm90by5NYW5pZmVzdEZpbGVCb29ra2VlcGluZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworCisvKiogU3RvcmFnZSBtZWNoYW5pc20gZm9yIE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nLiAqLworaW50ZXJmYWNlIE1hbmlmZXN0RmlsZU1ldGFkYXRhU3RvcmUgeworICAvKiogUmV0dXJucyB0aGUgbWV0YWRhdGEgYXNzb2NpYXRlZCB3aXRoIHtAY29kZSBtYW5pZmVzdElkfSBpZiBpdCBleGlzdHMuICovCisgIExpc3RlbmFibGVGdXR1cmU8T3B0aW9uYWw8TWFuaWZlc3RGaWxlQm9va2tlZXBpbmc+PiByZWFkKFN0cmluZyBtYW5pZmVzdElkKTsKKworICAvKiogSW5zZXJ0cyBvciB1cGRhdGVzIHRoZSBtZXRhZGF0YSBhc3NvY2lhdGVkIHdpdGgge0Bjb2RlIG1hbmlmZXN0SWR9LiAqLworICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHVwc2VydChTdHJpbmcgbWFuaWZlc3RJZCwgTWFuaWZlc3RGaWxlQm9va2tlZXBpbmcgdmFsdWUpOworfQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTWlncmF0aW9uUHJveHlMb2NhbGVPdmVycmlkZXIuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDAxOWY1NQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyLmphdmEKQEAgLTAsMCArMSw1NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQucG9wdWxhdG9yOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZTsKKworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuU3VwcGxpZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZUdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uTWFuaWZlc3RDb25maWc7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKKworLyoqCisgKiBQcm94eSBvdmVycmlkZXIgdXNlZCBpbiB0aGUgbWlncmF0aW9uIG9mIE1hbmlmZXN0RmlsZUdyb3VwUG9wdWxhdG9yLgorICoKKyAqIDxwPntAY29kZSBmbGFnU3VwcGxpZXJ9IGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIE1hbmlmZXN0RmlsZUdyb3VwUG9wdWxhdG9yIGlzIGVuYWJsZWQuCisgKiBJdCBpcyBjYWxsZWQgZXZlcnkgdGltZSBhIGNsaWVudCBjYWxscyByZWZyZXNoRmlsZUdyb3Vwcy4gV2hlbiBpdCByZXR1cm5zIHRydWUsIGl0IGNhbGxzIHtAY29kZQorICogbG9jYWxlT3ZlcnJpZGVyLm92ZXJyaWRlKCl9OyB3aGVuIGl0IHJldHVybnMgZmFsc2UsIGl0IHJldHVybnMgYW4gZW1wdHkgbGlzdCB3aGljaCBtYWtlcyB0aGUKKyAqIE1hbmlmZXN0RmlsZUdyb3VwUG9wdWxhdG9yIG5vdCBhZGQgYW55IGRhdGEgZmlsZSBncm91cCB0byBNREQuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNaWdyYXRpb25Qcm94eUxvY2FsZU92ZXJyaWRlciBpbXBsZW1lbnRzIE1hbmlmZXN0Q29uZmlnT3ZlcnJpZGVyIHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJNaWdyYXRpb25Qcm94eUxvY2FsZU92ZXJyaWRlciI7CisKKyAgcHJpdmF0ZSBmaW5hbCBTdXBwbGllcjxCb29sZWFuPiBmbGFnU3VwcGxpZXI7CisgIHByaXZhdGUgZmluYWwgTG9jYWxlT3ZlcnJpZGVyIGxvY2FsZU92ZXJyaWRlcjsKKworICBwdWJsaWMgTWlncmF0aW9uUHJveHlMb2NhbGVPdmVycmlkZXIoCisgICAgICBMb2NhbGVPdmVycmlkZXIgbG9jYWxlT3ZlcnJpZGVyLCBTdXBwbGllcjxCb29sZWFuPiBmbGFnU3VwcGxpZXIpIHsKKyAgICB0aGlzLmZsYWdTdXBwbGllciA9IGZsYWdTdXBwbGllcjsKKyAgICB0aGlzLmxvY2FsZU92ZXJyaWRlciA9IGxvY2FsZU92ZXJyaWRlcjsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxMaXN0PERhdGFGaWxlR3JvdXA+PiBvdmVycmlkZShNYW5pZmVzdENvbmZpZyBtYW5pZmVzdENvbmZpZykgeworICAgIGlmIChmbGFnU3VwcGxpZXIuZ2V0KCkpIHsKKyAgICAgIHJldHVybiBsb2NhbGVPdmVycmlkZXIub3ZlcnJpZGUobWFuaWZlc3RDb25maWcpOworICAgIH0gZWxzZSB7CisgICAgICByZXR1cm4gaW1tZWRpYXRlRnV0dXJlKG5ldyBBcnJheUxpc3Q8PigpKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01pZ3JhdGlvblByb3h5UG9wdWxhdG9yLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9NaWdyYXRpb25Qcm94eVBvcHVsYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjNWY2MTAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9NaWdyYXRpb25Qcm94eVBvcHVsYXRvci5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnBvcHVsYXRvcjsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkZpbGVHcm91cFBvcHVsYXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Nb2JpbGVEYXRhRG93bmxvYWQ7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5TdXBwbGllcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKKworLyoqCisgKiBBIHtAY29kZSBNaWdyYXRpb25Qcm94eVBvcHVsYXRvcn0gY2FuIGJlIHVzZWQgYnkgYSBjbGllbnQgdG8gcnVuIG1pZ3JhdGlvbiBleHBlcmltZW50cyBmcm9tIG9uZQorICogZmlsZSBncm91cCBwb3B1bGF0b3IgdG8gYW5vdGhlci4KKyAqCisgKiA8cD57QGNvZGUgZmxhZ1N1cHBsaWVyfSBpcyB1c2VkIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBjb250cm9sIG9yIGV4cGVyaW1lbnQgcG9wdWxhdG9yIGlzIHVzZWQuCisgKiBJdCBpcyBjYWxsZWQgZXZlcnkgdGltZSBhIGNsaWVudCBjYWxscyByZWZyZXNoRmlsZUdyb3Vwcy4gV2hlbiBpdCByZXR1cm5zIHRydWUsIHtAY29kZQorICogZXhwZXJpbWVudEZpbGVHcm91cFBvcHVsYXRvcn0gaXMgZGVsZWdhdGVkIHRvIHJlZnJlc2ggZmlsZSBncm91cDsgd2hlbiBpdCByZXR1cm5zIGZhbHNlLCB7QGNvZGUKKyAqIGNvbnRyb2xGaWxlR3JvdXBQb3B1bGF0b3J9IGlzIGRlbGVnYXRlZCB0byByZWZyZXNoIGZpbGUgZ3JvdXAuIFRoaXMgZGVzaWduIGVuYWJsZXMgdGhlIGNsaWVudCB0bworICogcmVmcmVzaCBvbiB0aGUgY29ycmVjdCBwb3B1bGF0b3IgYmFzZWQgb24gbW9zdCB1cC10by1kYXRlIGZsYWcgdmFsdWUuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBNaWdyYXRpb25Qcm94eVBvcHVsYXRvciBpbXBsZW1lbnRzIEZpbGVHcm91cFBvcHVsYXRvciB7CisgIHByaXZhdGUgZmluYWwgRmlsZUdyb3VwUG9wdWxhdG9yIGNvbnRyb2xGaWxlR3JvdXBQb3B1bGF0b3I7CisgIHByaXZhdGUgZmluYWwgRmlsZUdyb3VwUG9wdWxhdG9yIGV4cGVyaW1lbnRGaWxlR3JvdXBQb3B1bGF0b3I7CisgIHByaXZhdGUgZmluYWwgU3VwcGxpZXI8Qm9vbGVhbj4gZmxhZ1N1cHBsaWVyOworCisgIHB1YmxpYyBNaWdyYXRpb25Qcm94eVBvcHVsYXRvcigKKyAgICAgIEZpbGVHcm91cFBvcHVsYXRvciBjb250cm9sRmlsZUdyb3VwUG9wdWxhdG9yLAorICAgICAgRmlsZUdyb3VwUG9wdWxhdG9yIGV4cGVyaW1lbnRGaWxlR3JvdXBQb3B1bGF0b3IsCisgICAgICBTdXBwbGllcjxCb29sZWFuPiBmbGFnU3VwcGxpZXIpIHsKKyAgICB0aGlzLmNvbnRyb2xGaWxlR3JvdXBQb3B1bGF0b3IgPSBjb250cm9sRmlsZUdyb3VwUG9wdWxhdG9yOworICAgIHRoaXMuZXhwZXJpbWVudEZpbGVHcm91cFBvcHVsYXRvciA9IGV4cGVyaW1lbnRGaWxlR3JvdXBQb3B1bGF0b3I7CisgICAgdGhpcy5mbGFnU3VwcGxpZXIgPSBmbGFnU3VwcGxpZXI7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVmcmVzaEZpbGVHcm91cHMoTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCkgeworICAgIGlmIChmbGFnU3VwcGxpZXIuZ2V0KCkpIHsKKyAgICAgIHJldHVybiBleHBlcmltZW50RmlsZUdyb3VwUG9wdWxhdG9yLnJlZnJlc2hGaWxlR3JvdXBzKG1vYmlsZURhdGFEb3dubG9hZCk7CisgICAgfSBlbHNlIHsKKyAgICAgIHJldHVybiBjb250cm9sRmlsZUdyb3VwUG9wdWxhdG9yLnJlZnJlc2hGaWxlR3JvdXBzKG1vYmlsZURhdGFEb3dubG9hZCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9TaGFyZWRQcmVmZXJlbmNlc01hbmlmZXN0RmlsZU1ldGFkYXRhLmphdmEgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9TaGFyZWRQcmVmZXJlbmNlc01hbmlmZXN0RmlsZU1ldGFkYXRhLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODY1NmU5MQotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL1NoYXJlZFByZWZlcmVuY2VzTWFuaWZlc3RGaWxlTWV0YWRhdGEuamF2YQpAQCAtMCwwICsxLDk0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5wb3B1bGF0b3I7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuU2hhcmVkUHJlZmVyZW5jZXM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQucG9wdWxhdG9yLk1ldGFkYXRhUHJvdG8uTWFuaWZlc3RGaWxlQm9va2tlZXBpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5TaGFyZWRQcmVmZXJlbmNlc1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5Qcm9wYWdhdGVkRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuU3VwcGxpZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5TdXBwbGllcnM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKKworLyoqIE1hbmlmZXN0RmlsZU1ldGFkYXRhU3RvcmUgYmFzZWQgb24gU2hhcmVkUHJlZmVyZW5jZXMuICovCitwdWJsaWMgZmluYWwgY2xhc3MgU2hhcmVkUHJlZmVyZW5jZXNNYW5pZmVzdEZpbGVNZXRhZGF0YSBpbXBsZW1lbnRzIE1hbmlmZXN0RmlsZU1ldGFkYXRhU3RvcmUgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTSEFSRURfUFJFRlNfTkFNRSA9ICJNYW5pZmVzdEZpbGVNZXRhZGF0YSI7CisKKyAgcHJpdmF0ZSBmaW5hbCBPYmplY3QgbG9jayA9IG5ldyBPYmplY3QoKTsKKworICBwcml2YXRlIGZpbmFsIFN1cHBsaWVyPFNoYXJlZFByZWZlcmVuY2VzPiBzaGFyZWRQcmVmczsKKyAgcHJpdmF0ZSBmaW5hbCBFeGVjdXRvciBiYWNrZ3JvdW5kRXhlY3V0b3I7CisKKyAgLyoqCisgICAqIEBwYXJhbSBzaGFyZWRQcmVmcyBtYXkgYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzLCBzbyBtZW1vaXphdGlvbiBpcyByZWNvbW1lbmRlZAorICAgKi8KKyAgcHVibGljIHN0YXRpYyBTaGFyZWRQcmVmZXJlbmNlc01hbmlmZXN0RmlsZU1ldGFkYXRhIGNyZWF0ZSgKKyAgICAgIFN1cHBsaWVyPFNoYXJlZFByZWZlcmVuY2VzPiBzaGFyZWRQcmVmcywgRXhlY3V0b3IgYmFja2dyb3VuZEV4ZWN1dG9yKSB7CisgICAgcmV0dXJuIG5ldyBTaGFyZWRQcmVmZXJlbmNlc01hbmlmZXN0RmlsZU1ldGFkYXRhKHNoYXJlZFByZWZzLCBiYWNrZ3JvdW5kRXhlY3V0b3IpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBTaGFyZWRQcmVmZXJlbmNlc01hbmlmZXN0RmlsZU1ldGFkYXRhIGNyZWF0ZUZyb21Db250ZXh0KAorICAgICAgQ29udGV4dCBjb250ZXh0LCBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWRPcHRpb25hbCwgRXhlY3V0b3IgYmFja2dyb3VuZEV4ZWN1dG9yKSB7CisgICAgLy8gQXZvaWQgY2FsbGluZyBnZXRTaGFyZWRQcmVmZXJlbmNlcyBvbiB0aGUgbWFpbiB0aHJlYWQuCisgICAgU3VwcGxpZXI8U2hhcmVkUHJlZmVyZW5jZXM+IHNoYXJlZFByZWZzID0KKyAgICAgICAgU3VwcGxpZXJzLm1lbW9pemUoCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcygKKyAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgU0hBUkVEX1BSRUZTX05BTUUsIGluc3RhbmNlSWRPcHRpb25hbCkpOworICAgIHJldHVybiBuZXcgU2hhcmVkUHJlZmVyZW5jZXNNYW5pZmVzdEZpbGVNZXRhZGF0YShzaGFyZWRQcmVmcywgYmFja2dyb3VuZEV4ZWN1dG9yKTsKKyAgfQorCisgIHByaXZhdGUgU2hhcmVkUHJlZmVyZW5jZXNNYW5pZmVzdEZpbGVNZXRhZGF0YSgKKyAgICAgIFN1cHBsaWVyPFNoYXJlZFByZWZlcmVuY2VzPiBzaGFyZWRQcmVmcywgRXhlY3V0b3IgYmFja2dyb3VuZEV4ZWN1dG9yKSB7CisgICAgdGhpcy5zaGFyZWRQcmVmcyA9IHNoYXJlZFByZWZzOworICAgIHRoaXMuYmFja2dyb3VuZEV4ZWN1dG9yID0gYmFja2dyb3VuZEV4ZWN1dG9yOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPE9wdGlvbmFsPE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nPj4gcmVhZChTdHJpbmcgbWFuaWZlc3RJZCkgeworICAgIHJldHVybiBQcm9wYWdhdGVkRnV0dXJlcy5zdWJtaXQoCisgICAgICAgICgpIC0+IHsKKyAgICAgICAgICBzeW5jaHJvbml6ZWQgKGxvY2spIHsKKyAgICAgICAgICAgIE1hbmlmZXN0RmlsZUJvb2trZWVwaW5nIHByb3RvID0KKyAgICAgICAgICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwucmVhZFByb3RvKAorICAgICAgICAgICAgICAgICAgICBzaGFyZWRQcmVmcy5nZXQoKSwgbWFuaWZlc3RJZCwgTWFuaWZlc3RGaWxlQm9va2tlZXBpbmcucGFyc2VyKCkpOworICAgICAgICAgICAgcmV0dXJuIE9wdGlvbmFsLmZyb21OdWxsYWJsZShwcm90byk7CisgICAgICAgICAgfQorICAgICAgICB9LAorICAgICAgICBiYWNrZ3JvdW5kRXhlY3V0b3IpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHVwc2VydChTdHJpbmcgbWFuaWZlc3RJZCwgTWFuaWZlc3RGaWxlQm9va2tlZXBpbmcgdmFsdWUpIHsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZ1dHVyZXMuc3VibWl0KAorICAgICAgICAoKSAtPiB7CisgICAgICAgICAgc3luY2hyb25pemVkIChsb2NrKSB7CisgICAgICAgICAgICBTaGFyZWRQcmVmZXJlbmNlcy5FZGl0b3IgZWRpdG9yID0gc2hhcmVkUHJlZnMuZ2V0KCkuZWRpdCgpOworICAgICAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLndyaXRlUHJvdG8oZWRpdG9yLCBtYW5pZmVzdElkLCB2YWx1ZSk7CisgICAgICAgICAgICBpZiAoIWVkaXRvci5jb21taXQoKSkgeworICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkZhaWxlZCB0byBjb21taXQiKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBudWxsOyAvLyBmb3IgQ2FsbGFibGUKKyAgICAgICAgICB9CisgICAgICAgIH0sCisgICAgICAgIGJhY2tncm91bmRFeGVjdXRvcik7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL1NpbmdsZURhdGFGaWxlR3JvdXBQb3B1bGF0b3IuamF2YSBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL1NpbmdsZURhdGFGaWxlR3JvdXBQb3B1bGF0b3IuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMGJkOGM4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvU2luZ2xlRGF0YUZpbGVHcm91cFBvcHVsYXRvci5qYXZhCkBAIC0wLDAgKzEsMTM3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5wb3B1bGF0b3I7CisKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkFkZEZpbGVHcm91cFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRmlsZUdyb3VwUG9wdWxhdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLk1vYmlsZURhdGFEb3dubG9hZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ1V0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVDYWxsYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlR3JvdXA7CisKKy8qKgorICogRmlsZUdyb3VwUG9wdWxhdG9yIHRoYXQgZ2V0cyBhIHNpbmdsZSBmaWxlIGdyb3VwIGZyb20gYSBzdXBwbGllciBhbmQgcG9wdWxhdGVzIGl0LgorICoKKyAqIDxwPkNsaWVudCBjYW4gc2V0IGFuIG9wdGlvbmFsIGZpbGUgZ3JvdXAgb3ZlcnJpZGVyIHRvIG92ZXJyaWRlIGZpZWxkcyBpbiB0aGUge0BsaW5rCisgKiBEYXRhRmlsZUdyb3VwfSBpZiBuZWVkZWQuCisgKgorICogPHA+VGhlIG92ZXJyaWRlciBjb3VsZCBhbHNvIGJlIHVzZWQgZm9yIG9uIGRldmljZSB0YXJnZXRpbmcgYW5kIGZpbHRlcmluZyBpbiB0aGUgY2FzZSB0aGF0IHRoZQorICogZmlsZSBncm91cCBpcyBwcm92aWRlZCBmcm9tIGEgc2VydmVyLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgU2luZ2xlRGF0YUZpbGVHcm91cFBvcHVsYXRvciBpbXBsZW1lbnRzIEZpbGVHcm91cFBvcHVsYXRvciB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJTaW5nbGVEYXRhRmlsZUdyb3VwUG9wIjsKKworICAvKiogQnVpbGRlciBmb3Ige0BsaW5rIFNpbmdsZURhdGFGaWxlR3JvdXBQb3B1bGF0b3J9LiAqLworICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgeworICAgIHByaXZhdGUgU3VwcGxpZXI8RGF0YUZpbGVHcm91cD4gZGF0YUZpbGVHcm91cFN1cHBsaWVyOworICAgIHByaXZhdGUgT3B0aW9uYWw8RGF0YUZpbGVHcm91cE92ZXJyaWRlcj4gb3ZlcnJpZGVyT3B0aW9uYWwgPSBPcHRpb25hbC5hYnNlbnQoKTsKKworICAgIHB1YmxpYyBCdWlsZGVyIHNldERhdGFGaWxlR3JvdXBTdXBwbGllcihTdXBwbGllcjxEYXRhRmlsZUdyb3VwPiBkYXRhRmlsZUdyb3VwU3VwcGxpZXIpIHsKKyAgICAgIHRoaXMuZGF0YUZpbGVHcm91cFN1cHBsaWVyID0gZGF0YUZpbGVHcm91cFN1cHBsaWVyOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgLyoqCisgICAgICogU2V0cyB0aGUgb3B0aW9uYWwgZmlsZSBncm91cCBvdmVycmlkZXIgdGhhdCB0YWtlcyB0aGUge0BsaW5rIERhdGFGaWxlR3JvdXB9IGFuZCByZXR1cm5zIGEKKyAgICAgKiB7QGxpbmsgRGF0YUZpbGVHcm91cH0gYWZ0ZXIgYmVpbmcgb3ZlcnJpZGRlbi4gSWYgdGhlIG92ZXJyaWRlciByZXR1cm5zIGEgbnVsbCBkYXRhIGZpbGUKKyAgICAgKiBncm91cCwgbm90aGluZyB3aWxsIGJlIHBvcHVsYXRlZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgQnVpbGRlciBzZXRPdmVycmlkZXJPcHRpb25hbChPcHRpb25hbDxEYXRhRmlsZUdyb3VwT3ZlcnJpZGVyPiBvdmVycmlkZXJPcHRpb25hbCkgeworICAgICAgdGhpcy5vdmVycmlkZXJPcHRpb25hbCA9IG92ZXJyaWRlck9wdGlvbmFsOworICAgICAgcmV0dXJuIHRoaXM7CisgICAgfQorCisgICAgcHVibGljIFNpbmdsZURhdGFGaWxlR3JvdXBQb3B1bGF0b3IgYnVpbGQoKSB7CisgICAgICByZXR1cm4gbmV3IFNpbmdsZURhdGFGaWxlR3JvdXBQb3B1bGF0b3IodGhpcyk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBmaW5hbCBTdXBwbGllcjxEYXRhRmlsZUdyb3VwPiBkYXRhRmlsZUdyb3VwU3VwcGxpZXI7CisgIHByaXZhdGUgZmluYWwgT3B0aW9uYWw8RGF0YUZpbGVHcm91cE92ZXJyaWRlcj4gb3ZlcnJpZGVyT3B0aW9uYWw7CisKKyAgLyoqIFJldHVybnMgYSBCdWlsZGVyIGZvciBTaW5nbGVEYXRhRmlsZUdyb3VwUG9wdWxhdG9yLiAqLworICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgYnVpbGRlcigpIHsKKyAgICByZXR1cm4gbmV3IEJ1aWxkZXIoKTsKKyAgfQorCisgIHByaXZhdGUgU2luZ2xlRGF0YUZpbGVHcm91cFBvcHVsYXRvcihCdWlsZGVyIGJ1aWxkZXIpIHsKKyAgICB0aGlzLmRhdGFGaWxlR3JvdXBTdXBwbGllciA9IGJ1aWxkZXIuZGF0YUZpbGVHcm91cFN1cHBsaWVyOworICAgIHRoaXMub3ZlcnJpZGVyT3B0aW9uYWwgPSBidWlsZGVyLm92ZXJyaWRlck9wdGlvbmFsOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJlZnJlc2hGaWxlR3JvdXBzKE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQpIHsKKyAgICBMb2dVdGlsLmQoIiVzOiBBZGQgZmlsZSBncm91cCB0byBNZGQuIiwgVEFHKTsKKworICAgIC8vIE92ZXJyaWRlIGRhdGEgZmlsZSBncm91cCBpZiB0aGUgb3ZlcnJpZGVyIGlzIHByZXNlbnQuIElmIHRoZSBvdmVycmlkZXIgcmV0dXJucyBhbiBhYnNlbnQKKyAgICAvLyBkYXRhIGZpbGUgZ3JvdXAsIG5vdGhpbmcgd2lsbCBiZSBwb3B1bGF0ZWQuCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxPcHRpb25hbDxEYXRhRmlsZUdyb3VwPj4gZGF0YUZpbGVHcm91cE9wdGlvbmFsRnV0dXJlID0KKyAgICAgICAgRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoT3B0aW9uYWwuYWJzZW50KCkpOworICAgIGlmIChkYXRhRmlsZUdyb3VwU3VwcGxpZXIuZ2V0KCkgIT0gbnVsbAorICAgICAgICAmJiAhZGF0YUZpbGVHcm91cFN1cHBsaWVyLmdldCgpLmdldEdyb3VwTmFtZSgpLmlzRW1wdHkoKSkgeworICAgICAgZGF0YUZpbGVHcm91cE9wdGlvbmFsRnV0dXJlID0KKyAgICAgICAgICBvdmVycmlkZXJPcHRpb25hbC5pc1ByZXNlbnQoKQorICAgICAgICAgICAgICA/IG92ZXJyaWRlck9wdGlvbmFsLmdldCgpLm92ZXJyaWRlKGRhdGFGaWxlR3JvdXBTdXBwbGllci5nZXQoKSkKKyAgICAgICAgICAgICAgOiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShPcHRpb25hbC5vZihkYXRhRmlsZUdyb3VwU3VwcGxpZXIuZ2V0KCkpKTsKKyAgICB9CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IGFkZEZpbGVHcm91cEZ1dHVyZSA9CisgICAgICAgIEZ1dHVyZXMudHJhbnNmb3JtQXN5bmMoCisgICAgICAgICAgICBkYXRhRmlsZUdyb3VwT3B0aW9uYWxGdXR1cmUsCisgICAgICAgICAgICBkYXRhRmlsZUdyb3VwT3B0aW9uYWwgLT4geworICAgICAgICAgICAgICBpZiAoZGF0YUZpbGVHcm91cE9wdGlvbmFsLmlzUHJlc2VudCgpCisgICAgICAgICAgICAgICAgICAmJiAhZGF0YUZpbGVHcm91cE9wdGlvbmFsLmdldCgpLmdldEdyb3VwTmFtZSgpLmlzRW1wdHkoKSkgeworICAgICAgICAgICAgICAgIHJldHVybiBtb2JpbGVEYXRhRG93bmxvYWQuYWRkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgLnNldERhdGFGaWxlR3JvdXAoZGF0YUZpbGVHcm91cE9wdGlvbmFsLmdldCgpKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIExvZ1V0aWwuZCgiJXM6IE5vdCBhZGRpbmcgZmlsZSBncm91cCBiZWNhdXNlIG9mIG92ZXJyaWRlci4iLCBUQUcpOworICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmFsc2UpOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3IoKSk7CisKKyAgICBGdXR1cmVzLmFkZENhbGxiYWNrKAorICAgICAgICBhZGRGaWxlR3JvdXBGdXR1cmUsCisgICAgICAgIG5ldyBGdXR1cmVDYWxsYmFjazxCb29sZWFuPigpIHsKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoQm9vbGVhbiByZXN1bHQpIHsKKyAgICAgICAgICAgIFN0cmluZyBncm91cE5hbWUgPSBkYXRhRmlsZUdyb3VwU3VwcGxpZXIuZ2V0KCkuZ2V0R3JvdXBOYW1lKCk7CisgICAgICAgICAgICBpZiAocmVzdWx0LmJvb2xlYW5WYWx1ZSgpKSB7CisgICAgICAgICAgICAgIExvZy5kKFRBRywgIkFkZGVkIGZpbGUgZ3JvdXAgIiArIGdyb3VwTmFtZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBMb2cuZShUQUcsICJGYWlsZWQgdG8gYWRkIGZpbGUgZ3JvdXAgIiArIGdyb3VwTmFtZSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorCisgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgcHVibGljIHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICBMb2cuZShUQUcsICJGYWlsZWQgdG8gYWRkIGZpbGUgZ3JvdXAiLCB0KTsKKyAgICAgICAgICB9CisgICAgICAgIH0sCisgICAgICAgIE1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3IoKSk7CisKKyAgICByZXR1cm4gRnV0dXJlcy53aGVuQWxsQ29tcGxldGUoYWRkRmlsZUdyb3VwRnV0dXJlKQorICAgICAgICAuY2FsbCgoKSAtPiBudWxsLCBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9wcm90by9BbmRyb2lkLmJwIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvcHJvdG8vQW5kcm9pZC5icApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNDJhMzM3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvcHJvdG8vQW5kcm9pZC5icApAQCAtMCwwICsxLDM5IEBACisKKy8vCisvLyBDb3B5cmlnaHQgKEMpIDIwMjIgVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdAorLy8KKy8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorLy8gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisvLworLy8gICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKy8vCisvLyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisvLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorLy8gV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisvLyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisvLyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKy8vCisKK2phdmFfbGlicmFyeSB7CisgICAgbmFtZTogIm1vYmlsZS1kYXRhLWRvd25sb2FkLXBvcHVsYXRvci1qYXZhLXByb3RvLWxpdGUiLAorICAgIHByb3RvOiB7CisgICAgICAgIHR5cGU6ICJsaXRlIiwKKyAgICAgICAgaW5jbHVkZV9kaXJzOiBbImV4dGVybmFsL3Byb3RvYnVmL3NyYyJdLAorICAgICAgICBjYW5vbmljYWxfcGF0aF9mcm9tX3Jvb3Q6IGZhbHNlLAorICAgICAgICAvL2xvY2FsX2luY2x1ZGVfZGlyczogWyJwcm90by8qIl0sCisgICAgfSwKKyAgICBzdGF0aWNfbGliczogWworICAgICAgICAibGlicHJvdG9idWYtamF2YS1saXRlIiwKKyAgICBdLAorICAgIHNyY3M6IFsKKyAgICAgICAgIioqLyoucHJvdG8iLAorICAgICAgICAiOmxpYnByb3RvYnVmLWludGVybmFsLXByb3RvcyJdLAorICAgIHNka192ZXJzaW9uOiAiY3VycmVudCIsCisgICAgbWluX3Nka192ZXJzaW9uOiAiMzAiLAorICAgIGphcmphcl9ydWxlczogImphcmphci1ydWxlcy50eHQiLAorICAgIGFwZXhfYXZhaWxhYmxlOiBbCisgICAgICAgICIvL2FwZXhfYXZhaWxhYmxlOnBsYXRmb3JtIiwKKyAgICAgICAgImNvbS5hbmRyb2lkLmFkc2VydmljZXMiLAorICAgIF0sCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvcHJvdG8vQlVJTEQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9wcm90by9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MWJlMjc2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvcHJvdG8vQlVJTEQKQEAgLTAsMCArMSwzNyBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbCisgICAgICAgICIvLzpfX3N1YnBhY2thZ2VzX18iLAorICAgIF0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCitwcm90b19saWJyYXJ5KAorICAgIG5hbWUgPSAibWV0YWRhdGFfcHJvdG8iLAorICAgIHNyY3MgPSBbIm1ldGFkYXRhLnByb3RvIl0sCisgICAgY2NfYXBpX3ZlcnNpb24gPSAyLAorICAgIGRlcHMgPSBbXSwKKyAgICBhbHdheXNsaW5rID0gMSwKKykKKworamF2YV9wcm90b19saWJyYXJ5KAorICAgIG5hbWUgPSAibWV0YWRhdGFfamF2YV9wcm90byIsCisgICAgZGVwcyA9IFsiOm1ldGFkYXRhX3Byb3RvIl0sCispCisKK2phdmFfbGl0ZV9wcm90b19saWJyYXJ5KAorICAgIG5hbWUgPSAibWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICBkZXBzID0gWyI6bWV0YWRhdGFfcHJvdG8iXSwKKykKZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL3Byb3RvL2phcmphci1ydWxlcy50eHQgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9wcm90by9qYXJqYXItcnVsZXMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzNWYzZjgKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9wcm90by9qYXJqYXItcnVsZXMudHh0CkBAIC0wLDAgKzEsMyBAQAorCisjIFVzZSBvdXIgc3RhdGljYWxseSBsaW5rZWQgcHJvdG9idWYgbGlicmFyeQorIyBydWxlIGNvbS5nb29nbGUucHJvdG9idWYuKiogY29tLmFuZHJvaWQuYWRzZXJ2aWNlcy5wcm90b2J1Zi5AMQpkaWZmIC0tZ2l0IGEvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvcHJvdG8vbWV0YWRhdGEucHJvdG8gYi9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9wcm90by9tZXRhZGF0YS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZGQyMTc3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvcHJvdG8vbWV0YWRhdGEucHJvdG8KQEAgLTAsMCArMSw0NiBAQAorLy8gQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworLy8KKy8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorLy8gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisvLworLy8gICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKy8vCisvLyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisvLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorLy8gV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisvLyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisvLyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIG1kaS5kb3dubG9hZC5wb3B1bGF0b3I7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQucG9wdWxhdG9yIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJNZXRhZGF0YVByb3RvIjsKKworLy8gQm9va2tlZXBzIHRoZSBtZXRhZGF0YSBvZiBtYW5pZmVzdCBmaWxlLgorLy8gTmV4dCB0YWc6IDQKK21lc3NhZ2UgTWFuaWZlc3RGaWxlQm9va2tlZXBpbmcgeworICAvLyBUaGUgdXJsIHdoZXJlIHRoZSBtYW5pZmVzdCBmaWxlIGlzIHNlcnZlZC4KKyAgb3B0aW9uYWwgc3RyaW5nIG1hbmlmZXN0X2ZpbGVfdXJsID0gMzsKKworICAvLyBUaGUgY2FjaGVkIEVUYWcgdGhhdCBpcyBmZXRjaGVkIGZyb20gdGhlIHRhcmdldCB1cmwgYW5kIHN0b3JlZCBvbiBkZXZpY2UuCisgIC8vIFRoaXMgaXMgdXNlZCBmb3IgY29udGVudCBjaGFuZ2UgZGV0ZWN0aW9uLgorICBvcHRpb25hbCBzdHJpbmcgY2FjaGVkX2V0YWcgPSAxOworCisgIC8vIFRoZSBzdGF0dXMgb2YgZG93bmxvYWRpbmcgdGhlIG1hbmlmZXN0IGZpbGUuCisgIGVudW0gU3RhdHVzIHsKKyAgICBJTlZBTElEID0gMDsKKworICAgIC8vIFRoZSBmaWxlIGlzIGFic2VudCBvciB0aGUgZG93bmxvYWQgaGFzIHN0YXJ0ZWQuCisgICAgUEVORElORyA9IDE7CisKKyAgICAvLyBUaGUgZG93bmxvYWQgaGFzIGNvbXBsZXRlZCBidXQgdGhlIGZpbGUgaGFzIG5vdCBiZWVuIHBhcnNlZC4KKyAgICBET1dOTE9BREVEID0gMjsKKworICAgIC8vIFRoZSBmaWxlIHdhcyBwYXJzZWQgYW5kIGZpbGUgZ3JvdXBzIHdlcmUgYWRkZWQgdG8gTURELgorICAgIENPTU1JVFRFRCA9IDM7CisgIH0KKworICBvcHRpb25hbCBTdGF0dXMgc3RhdHVzID0gMjsKK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZy9CVUlMRCBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZy9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOGFlODhlCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nL0JVSUxECkBAIC0wLDAgKzEsNDMgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJ0cmFjaW5nIiwKKyAgICBzcmNzID0gWworICAgICAgICAiVHJhY2VQcm9wYWdhdGlvbi5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICJAY29tX2dvb2dsZV9lcnJvcnByb25lX2Vycm9yX3Byb25lX2Fubm90YXRpb25zIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJjb25jdXJyZW50IiwKKyAgICBzcmNzID0gWworICAgICAgICAiUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5qYXZhIiwKKyAgICAgICAgIlByb3BhZ2F0ZWRGbHVlbnRGdXR1cmVzLmphdmEiLAorICAgICAgICAiUHJvcGFnYXRlZEZ1dHVyZXMuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQG9yZ19jaGVja2VyZnJhbWV3b3JrX3F1YWwiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3RyYWNpbmcvUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nL1Byb3BhZ2F0ZWRGbHVlbnRGdXR1cmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZGY2ZTQ5Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nL1Byb3BhZ2F0ZWRGbHVlbnRGdXR1cmUuamF2YQpAQCAtMCwwICsxLDEwMiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZzsKKworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuRnVuY3Rpb247CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkFzeW5jRnVuY3Rpb247CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZvcndhcmRpbmdMaXN0ZW5hYmxlRnV0dXJlLlNpbXBsZUZvcndhcmRpbmdMaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVDYWxsYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TY2hlZHVsZWRFeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CitpbXBvcnQgb3JnLmNoZWNrZXJmcmFtZXdvcmsuY2hlY2tlci5udWxsbmVzcy5xdWFsLk51bGxhYmxlOworCisvKioKKyAqIFNpbWlsYXIgdG8ge0BsaW5rIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GbHVlbnRGdXR1cmV9LCBidXQgd2l0aCB0cmFjZSBwcm9wYWdhdGlvbi4KKyAqIE5vdGUgdGhhdCB0aGUge0BsaW5rIExpc3RlbmFibGVGdXR1cmUjYWRkTGlzdGVuZXIoUnVubmFibGUsIEV4ZWN1dG9yKX0gbWV0aG9kIDxiPmRvZXMgbm90PC9iPgorICogcHJvcGFnYXRlIHRyYWNlcy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmU8ViBleHRlbmRzIEBOdWxsYWJsZSBPYmplY3Q+CisgICAgZXh0ZW5kcyBTaW1wbGVGb3J3YXJkaW5nTGlzdGVuYWJsZUZ1dHVyZTxWPiB7CisKKyAgcHJpdmF0ZSBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlKExpc3RlbmFibGVGdXR1cmU8Vj4gZGVsZWdhdGUpIHsKKyAgICBzdXBlcihkZWxlZ2F0ZSk7CisgIH0KKworICAvKiogU2VlIHtAbGluayBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRmx1ZW50RnV0dXJlI2Zyb20oTGlzdGVuYWJsZUZ1dHVyZSl9LiAqLworICBwdWJsaWMgc3RhdGljIDxWIGV4dGVuZHMgQE51bGxhYmxlIE9iamVjdD4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZTxWPiBmcm9tKAorICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWPiBmdXR1cmUpIHsKKyAgICByZXR1cm4gZnV0dXJlIGluc3RhbmNlb2YgUHJvcGFnYXRlZEZsdWVudEZ1dHVyZQorICAgICAgICA/IChQcm9wYWdhdGVkRmx1ZW50RnV0dXJlPFY+KSBmdXR1cmUKKyAgICAgICAgOiBuZXcgUHJvcGFnYXRlZEZsdWVudEZ1dHVyZTw+KGZ1dHVyZSk7CisgIH0KKworICAvKioKKyAgICogU2VlIHtAbGluayBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRmx1ZW50RnV0dXJlI2NhdGNoaW5nKENsYXNzLCBGdW5jdGlvbiwgRXhlY3V0b3IpfS4KKyAgICovCisgIHB1YmxpYyBmaW5hbCA8WCBleHRlbmRzIFRocm93YWJsZT4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZTxWPiBjYXRjaGluZygKKyAgICAgIENsYXNzPFg+IGV4Y2VwdGlvblR5cGUsIEZ1bmN0aW9uPD8gc3VwZXIgWCwgPyBleHRlbmRzIFY+IGZhbGxiYWNrLCBFeGVjdXRvciBleGVjdXRvcikgeworICAgIHJldHVybiBuZXcgUHJvcGFnYXRlZEZsdWVudEZ1dHVyZTw+KAorICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy5jYXRjaGluZyhkZWxlZ2F0ZSgpLCBleGNlcHRpb25UeXBlLCBmYWxsYmFjaywgZXhlY3V0b3IpKTsKKyAgfQorCisgIC8qKgorICAgKiBTZWUge0BsaW5rIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GbHVlbnRGdXR1cmUjY2F0Y2hpbmdBc3luYyhDbGFzcywgQXN5bmNGdW5jdGlvbiwKKyAgICogRXhlY3V0b3IpfS4KKyAgICovCisgIHB1YmxpYyBmaW5hbCA8WCBleHRlbmRzIFRocm93YWJsZT4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZTxWPiBjYXRjaGluZ0FzeW5jKAorICAgICAgQ2xhc3M8WD4gZXhjZXB0aW9uVHlwZSwgQXN5bmNGdW5jdGlvbjw/IHN1cGVyIFgsID8gZXh0ZW5kcyBWPiBmYWxsYmFjaywgRXhlY3V0b3IgZXhlY3V0b3IpIHsKKyAgICByZXR1cm4gbmV3IFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmU8PigKKyAgICAgICAgUHJvcGFnYXRlZEZ1dHVyZXMuY2F0Y2hpbmdBc3luYyhkZWxlZ2F0ZSgpLCBleGNlcHRpb25UeXBlLCBmYWxsYmFjaywgZXhlY3V0b3IpKTsKKyAgfQorCisgIC8qKgorICAgKiBTZWUge0BsaW5rIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GbHVlbnRGdXR1cmUjd2l0aFRpbWVvdXQobG9uZywgVGltZVVuaXQsCisgICAqIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSl9LgorICAgKi8KKyAgcHVibGljIGZpbmFsIFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmU8Vj4gd2l0aFRpbWVvdXQoCisgICAgICBsb25nIHRpbWVvdXQsIFRpbWVVbml0IHVuaXQsIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSBzY2hlZHVsZWRFeGVjdXRvcikgeworICAgIHJldHVybiBuZXcgUHJvcGFnYXRlZEZsdWVudEZ1dHVyZTw+KAorICAgICAgICBGdXR1cmVzLndpdGhUaW1lb3V0KGRlbGVnYXRlKCksIHRpbWVvdXQsIHVuaXQsIHNjaGVkdWxlZEV4ZWN1dG9yKSk7CisgIH0KKworICAvKioKKyAgICogU2VlIHtAbGluayBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRmx1ZW50RnV0dXJlI3RyYW5zZm9ybUFzeW5jKEFzeW5jRnVuY3Rpb24sCisgICAqIEV4ZWN1dG9yKX0uCisgICAqLworICBwdWJsaWMgZmluYWwgPFQgZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0PiBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlPFQ+IHRyYW5zZm9ybUFzeW5jKAorICAgICAgQXN5bmNGdW5jdGlvbjw/IHN1cGVyIFYsIFQ+IGZ1bmN0aW9uLCBFeGVjdXRvciBleGVjdXRvcikgeworICAgIHJldHVybiBuZXcgUHJvcGFnYXRlZEZsdWVudEZ1dHVyZTw+KAorICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy50cmFuc2Zvcm1Bc3luYyhkZWxlZ2F0ZSgpLCBmdW5jdGlvbiwgZXhlY3V0b3IpKTsKKyAgfQorCisgIC8qKiBTZWUge0BsaW5rIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GbHVlbnRGdXR1cmUjdHJhbnNmb3JtKEZ1bmN0aW9uLCBFeGVjdXRvcil9LiAqLworICBwdWJsaWMgZmluYWwgPFQgZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0PiBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlPFQ+IHRyYW5zZm9ybSgKKyAgICAgIEZ1bmN0aW9uPD8gc3VwZXIgViwgVD4gZnVuY3Rpb24sIEV4ZWN1dG9yIGV4ZWN1dG9yKSB7CisgICAgcmV0dXJuIG5ldyBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlPD4oCisgICAgICAgIFByb3BhZ2F0ZWRGdXR1cmVzLnRyYW5zZm9ybShkZWxlZ2F0ZSgpLCBmdW5jdGlvbiwgZXhlY3V0b3IpKTsKKyAgfQorCisgIC8qKgorICAgKiBTZWUge0BsaW5rIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GbHVlbnRGdXR1cmUjYWRkQ2FsbGJhY2soRnV0dXJlQ2FsbGJhY2ssCisgICAqIEV4ZWN1dG9yKX0uCisgICAqLworICBwdWJsaWMgZmluYWwgdm9pZCBhZGRDYWxsYmFjayhGdXR1cmVDYWxsYmFjazw/IHN1cGVyIFY+IGNhbGxiYWNrLCBFeGVjdXRvciBleGVjdXRvcikgeworICAgIFByb3BhZ2F0ZWRGdXR1cmVzLmFkZENhbGxiYWNrKGRlbGVnYXRlKCksIGNhbGxiYWNrLCBleGVjdXRvcik7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZy9Qcm9wYWdhdGVkRmx1ZW50RnV0dXJlcy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nL1Byb3BhZ2F0ZWRGbHVlbnRGdXR1cmVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTk0ZWRiMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZy9Qcm9wYWdhdGVkRmx1ZW50RnV0dXJlcy5qYXZhCkBAIC0wLDAgKzEsNDUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRyYWNpbmc7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcuY2hlY2tlcmZyYW1ld29yay5jaGVja2VyLm51bGxuZXNzLnF1YWwuTnVsbGFibGU7CisKKy8qKgorICogV3JhcHBlciBhcm91bmQge0BsaW5rIEZ1dHVyZXN9IGFuZCB7QGxpbmsgUHJvcGFnYXRlZEZ1dHVyZXN9IHRoYXQgcmV0dXJucyB7QGxpbmsKKyAqIFByb3BhZ2F0ZWRGbHVlbnRGdXR1cmV9LgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUHJvcGFnYXRlZEZsdWVudEZ1dHVyZXMgeworCisgIHByaXZhdGUgUHJvcGFnYXRlZEZsdWVudEZ1dHVyZXMoKSB7fQorCisgIC8qKgorICAgKiBAc2VlIEZ1dHVyZXMjYWxsQXNMaXN0KExpc3RlbmFibGVGdXR1cmVbXSkKKyAgICovCisgIHB1YmxpYyBzdGF0aWMgPFQgZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0PiBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlPExpc3Q8VD4+IGFsbEFzTGlzdCgKKyAgICAgIExpc3RlbmFibGVGdXR1cmU8PyBleHRlbmRzIFQ+Li4uIGZ1dHVyZXMpIHsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKEZ1dHVyZXMuYWxsQXNMaXN0KGZ1dHVyZXMpKTsKKyAgfQorCisgIC8qKiBTZWUge0BsaW5rIEZ1dHVyZXMjc3VjY2Vzc2Z1bEFzTGlzdChMaXN0ZW5hYmxlRnV0dXJlW10pfS4gKi8KKyAgcHVibGljIHN0YXRpYyA8VCBleHRlbmRzIEBOdWxsYWJsZSBPYmplY3Q+CisgICAgICBQcm9wYWdhdGVkRmx1ZW50RnV0dXJlPExpc3Q8QE51bGxhYmxlIFQ+PiBzdWNjZXNzZnVsQXNMaXN0KAorICAgICAgICAgIExpc3RlbmFibGVGdXR1cmU8PyBleHRlbmRzIFQ+Li4uIGZ1dHVyZXMpIHsKKyAgICByZXR1cm4gUHJvcGFnYXRlZEZsdWVudEZ1dHVyZS5mcm9tKEZ1dHVyZXMuc3VjY2Vzc2Z1bEFzTGlzdChmdXR1cmVzKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZy9Qcm9wYWdhdGVkRnV0dXJlcy5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nL1Byb3BhZ2F0ZWRGdXR1cmVzLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjg2ZGQyMAotLS0gL2Rldi9udWxsCisrKyBiL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdHJhY2luZy9Qcm9wYWdhdGVkRnV0dXJlcy5qYXZhCkBAIC0wLDAgKzEsMTM0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nOworCitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5GdW5jdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQXN5bmNDYWxsYWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQXN5bmNGdW5jdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlQ2FsbGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuRnV0dXJlQ29tYmluZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGU7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OworaW1wb3J0IG9yZy5jaGVja2VyZnJhbWV3b3JrLmNoZWNrZXIubnVsbG5lc3MucXVhbC5OdWxsYWJsZTsKKworLyoqIFdyYXBwZXIgYXJvdW5kIHtAbGluayBGdXR1cmVzfS4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBQcm9wYWdhdGVkRnV0dXJlcyB7CisKKyAgcHJpdmF0ZSBQcm9wYWdhdGVkRnV0dXJlcygpIHt9CisKKyAgcHVibGljIHN0YXRpYyA8SSBleHRlbmRzIEBOdWxsYWJsZSBPYmplY3QsIE8gZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0PgorICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxPPiB0cmFuc2Zvcm1Bc3luYygKKyAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPEk+IGlucHV0LAorICAgICAgICAgIEFzeW5jRnVuY3Rpb248PyBzdXBlciBJLCA/IGV4dGVuZHMgTz4gZnVuY3Rpb24sCisgICAgICAgICAgRXhlY3V0b3IgZXhlY3V0b3IpIHsKKyAgICByZXR1cm4gRnV0dXJlcy50cmFuc2Zvcm1Bc3luYyhpbnB1dCwgZnVuY3Rpb24sIGV4ZWN1dG9yKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgPEkgZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0LCBPIGV4dGVuZHMgQE51bGxhYmxlIE9iamVjdD4KKyAgICAgIExpc3RlbmFibGVGdXR1cmU8Tz4gdHJhbnNmb3JtKAorICAgICAgICAgIExpc3RlbmFibGVGdXR1cmU8ST4gaW5wdXQsIEZ1bmN0aW9uPD8gc3VwZXIgSSwgPyBleHRlbmRzIE8+IGZ1bmN0aW9uLCBFeGVjdXRvciBleGVjdXRvcikgeworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybShpbnB1dCwgZnVuY3Rpb24sIGV4ZWN1dG9yKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgPFYgZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0PiB2b2lkIGFkZENhbGxiYWNrKAorICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWPiBmdXR1cmUsIEZ1dHVyZUNhbGxiYWNrPD8gc3VwZXIgVj4gY2FsbGJhY2ssIEV4ZWN1dG9yIGV4ZWN1dG9yKSB7CisgICAgRnV0dXJlcy5hZGRDYWxsYmFjayhmdXR1cmUsIGNhbGxiYWNrLCBleGVjdXRvcik7CisgIH0KKworICBwdWJsaWMgc3RhdGljIDxWIGV4dGVuZHMgQE51bGxhYmxlIE9iamVjdCwgWCBleHRlbmRzIFRocm93YWJsZT4gTGlzdGVuYWJsZUZ1dHVyZTxWPiBjYXRjaGluZygKKyAgICAgIExpc3RlbmFibGVGdXR1cmU8PyBleHRlbmRzIFY+IGlucHV0LAorICAgICAgQ2xhc3M8WD4gZXhjZXB0aW9uVHlwZSwKKyAgICAgIEZ1bmN0aW9uPD8gc3VwZXIgWCwgPyBleHRlbmRzIFY+IGZhbGxiYWNrLAorICAgICAgRXhlY3V0b3IgZXhlY3V0b3IpIHsKKyAgICByZXR1cm4gRnV0dXJlcy5jYXRjaGluZyhpbnB1dCwgZXhjZXB0aW9uVHlwZSwgZmFsbGJhY2ssIGV4ZWN1dG9yKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgPFYgZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0LCBYIGV4dGVuZHMgVGhyb3dhYmxlPiBMaXN0ZW5hYmxlRnV0dXJlPFY+IGNhdGNoaW5nQXN5bmMoCisgICAgICBMaXN0ZW5hYmxlRnV0dXJlPD8gZXh0ZW5kcyBWPiBpbnB1dCwKKyAgICAgIENsYXNzPFg+IGV4Y2VwdGlvblR5cGUsCisgICAgICBBc3luY0Z1bmN0aW9uPD8gc3VwZXIgWCwgPyBleHRlbmRzIFY+IGZhbGxiYWNrLAorICAgICAgRXhlY3V0b3IgZXhlY3V0b3IpIHsKKyAgICByZXR1cm4gRnV0dXJlcy5jYXRjaGluZ0FzeW5jKGlucHV0LCBleGNlcHRpb25UeXBlLCBmYWxsYmFjaywgZXhlY3V0b3IpOworICB9CisKKyAgcHVibGljIHN0YXRpYyA8ViBleHRlbmRzIEBOdWxsYWJsZSBPYmplY3Q+IExpc3RlbmFibGVGdXR1cmU8Vj4gc3VibWl0KAorICAgICAgQ2FsbGFibGU8Vj4gY2FsbGFibGUsIEV4ZWN1dG9yIGV4ZWN1dG9yKSB7CisgICAgcmV0dXJuIEZ1dHVyZXMuc3VibWl0KGNhbGxhYmxlLCBleGVjdXRvcik7CisgIH0KKworICBwdWJsaWMgc3RhdGljIExpc3RlbmFibGVGdXR1cmU8QE51bGxhYmxlIFZvaWQ+IHN1Ym1pdChSdW5uYWJsZSBydW5uYWJsZSwgRXhlY3V0b3IgZXhlY3V0b3IpIHsKKyAgICByZXR1cm4gRnV0dXJlcy5zdWJtaXQocnVubmFibGUsIGV4ZWN1dG9yKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgPFYgZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0PiBMaXN0ZW5hYmxlRnV0dXJlPFY+IHN1Ym1pdEFzeW5jKAorICAgICAgQXN5bmNDYWxsYWJsZTxWPiBjYWxsYWJsZSwgRXhlY3V0b3IgZXhlY3V0b3IpIHsKKyAgICByZXR1cm4gRnV0dXJlcy5zdWJtaXRBc3luYyhjYWxsYWJsZSwgZXhlY3V0b3IpOworICB9CisKKyAgcHVibGljIHN0YXRpYyA8ViBleHRlbmRzIEBOdWxsYWJsZSBPYmplY3Q+IExpc3RlbmFibGVGdXR1cmU8Vj4gc2NoZWR1bGVBc3luYygKKyAgICAgIEFzeW5jQ2FsbGFibGU8Vj4gY2FsbGFibGUsIGxvbmcgZGVsYXksIFRpbWVVbml0IHRpbWVVbml0LCBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3IpIHsKKyAgICByZXR1cm4gRnV0dXJlcy5zY2hlZHVsZUFzeW5jKGNhbGxhYmxlLCBkZWxheSwgdGltZVVuaXQsIGV4ZWN1dG9yKTsKKyAgfQorCisgIEBTYWZlVmFyYXJncworICBwdWJsaWMgc3RhdGljIDxWIGV4dGVuZHMgQE51bGxhYmxlIE9iamVjdD4gUHJvcGFnYXRlZEZ1dHVyZUNvbWJpbmVyPFY+IHdoZW5BbGxDb21wbGV0ZSgKKyAgICAgIExpc3RlbmFibGVGdXR1cmU8PyBleHRlbmRzIFY+Li4uIGZ1dHVyZXMpIHsKKyAgICByZXR1cm4gbmV3IFByb3BhZ2F0ZWRGdXR1cmVDb21iaW5lcjw+KEZ1dHVyZXMud2hlbkFsbENvbXBsZXRlKGZ1dHVyZXMpKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgPFYgZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0PiBQcm9wYWdhdGVkRnV0dXJlQ29tYmluZXI8Vj4gd2hlbkFsbENvbXBsZXRlKAorICAgICAgSXRlcmFibGU8PyBleHRlbmRzIExpc3RlbmFibGVGdXR1cmU8PyBleHRlbmRzIFY+PiBmdXR1cmVzKSB7CisgICAgcmV0dXJuIG5ldyBQcm9wYWdhdGVkRnV0dXJlQ29tYmluZXI8PihGdXR1cmVzLndoZW5BbGxDb21wbGV0ZShmdXR1cmVzKSk7CisgIH0KKworICBAU2FmZVZhcmFyZ3MKKyAgcHVibGljIHN0YXRpYyA8ViBleHRlbmRzIEBOdWxsYWJsZSBPYmplY3Q+IFByb3BhZ2F0ZWRGdXR1cmVDb21iaW5lcjxWPiB3aGVuQWxsU3VjY2VlZCgKKyAgICAgIExpc3RlbmFibGVGdXR1cmU8PyBleHRlbmRzIFY+Li4uIGZ1dHVyZXMpIHsKKyAgICByZXR1cm4gbmV3IFByb3BhZ2F0ZWRGdXR1cmVDb21iaW5lcjw+KEZ1dHVyZXMud2hlbkFsbFN1Y2NlZWQoZnV0dXJlcykpOworICB9CisKKyAgcHVibGljIHN0YXRpYyA8ViBleHRlbmRzIEBOdWxsYWJsZSBPYmplY3Q+IFByb3BhZ2F0ZWRGdXR1cmVDb21iaW5lcjxWPiB3aGVuQWxsU3VjY2VlZCgKKyAgICAgIEl0ZXJhYmxlPD8gZXh0ZW5kcyBMaXN0ZW5hYmxlRnV0dXJlPD8gZXh0ZW5kcyBWPj4gZnV0dXJlcykgeworICAgIHJldHVybiBuZXcgUHJvcGFnYXRlZEZ1dHVyZUNvbWJpbmVyPD4oRnV0dXJlcy53aGVuQWxsU3VjY2VlZChmdXR1cmVzKSk7CisgIH0KKworICAvKiogV3JhcHBlciBhcm91bmQge0BsaW5rIEZ1dHVyZUNvbWJpbmVyfS4gKi8KKyAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQcm9wYWdhdGVkRnV0dXJlQ29tYmluZXI8ViBleHRlbmRzIEBOdWxsYWJsZSBPYmplY3Q+IHsKKyAgICBwcml2YXRlIGZpbmFsIEZ1dHVyZUNvbWJpbmVyPFY+IGZ1dHVyZUNvbWJpbmVyOworCisgICAgcHJpdmF0ZSBQcm9wYWdhdGVkRnV0dXJlQ29tYmluZXIoRnV0dXJlQ29tYmluZXI8Vj4gZnV0dXJlQ29tYmluZXIpIHsKKyAgICAgIHRoaXMuZnV0dXJlQ29tYmluZXIgPSBmdXR1cmVDb21iaW5lcjsKKyAgICB9CisKKyAgICBwdWJsaWMgPEMgZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0PiBMaXN0ZW5hYmxlRnV0dXJlPEM+IGNhbGxBc3luYygKKyAgICAgICAgQXN5bmNDYWxsYWJsZTxDPiBjb21iaW5lciwgRXhlY3V0b3IgZXhlY3V0b3IpIHsKKyAgICAgIHJldHVybiBmdXR1cmVDb21iaW5lci5jYWxsQXN5bmMoY29tYmluZXIsIGV4ZWN1dG9yKTsKKyAgICB9CisKKyAgICBwdWJsaWMgPEMgZXh0ZW5kcyBATnVsbGFibGUgT2JqZWN0PiBMaXN0ZW5hYmxlRnV0dXJlPEM+IGNhbGwoCisgICAgICAgIENhbGxhYmxlPEM+IGNvbWJpbmVyLCBFeGVjdXRvciBleGVjdXRvcikgeworICAgICAgcmV0dXJuIGZ1dHVyZUNvbWJpbmVyLmNhbGwoY29tYmluZXIsIGV4ZWN1dG9yKTsKKyAgICB9CisKKyAgICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTw/PiBydW4oZmluYWwgUnVubmFibGUgY29tYmluZXIsIEV4ZWN1dG9yIGV4ZWN1dG9yKSB7CisgICAgICByZXR1cm4gZnV0dXJlQ29tYmluZXIucnVuKGNvbWJpbmVyLCBleGVjdXRvcik7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3RyYWNpbmcvVHJhY2VQcm9wYWdhdGlvbi5qYXZhIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nL1RyYWNlUHJvcGFnYXRpb24uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YzFlZTEzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90cmFjaW5nL1RyYWNlUHJvcGFnYXRpb24uamF2YQpAQCAtMCwwICsxLDY1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50cmFjaW5nOworCitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5GdW5jdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQXN5bmNDYWxsYWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQXN5bmNGdW5jdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQ2xvc2luZ0Z1dHVyZS5DbG9zaW5nRnVuY3Rpb247CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZUNhbGxiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuZXJyb3Jwcm9uZS5hbm5vdGF0aW9ucy5DaGVja1JldHVyblZhbHVlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNhbGxhYmxlOworCisvKioKKyAqIENvbnRhaW5zIGRlY29yYXRvcnMgZm9yIHByb3BhZ2F0aW5nIHRoZSBjdXJyZW50IHRyYWNlIGludG8gYSBjYWxsYmFjay4gV2hlbiB0aGUgd3JhcHBlZCBjYWxsYmFjaworICogcnVucywgaXQgd2lsbCBydW4gdW5kZXIgdGhlIHNhbWUgdHJhY2UgdGhlIHdyYXBwZXIgd2FzIGNyZWF0ZWQgaW4uCisgKi8KK0BDaGVja1JldHVyblZhbHVlCitwdWJsaWMgZmluYWwgY2xhc3MgVHJhY2VQcm9wYWdhdGlvbiB7CisKKyAgQENoZWNrUmV0dXJuVmFsdWUKKyAgcHVibGljIHN0YXRpYyA8Vj4gQXN5bmNDYWxsYWJsZTxWPiBwcm9wYWdhdGVBc3luY0NhbGxhYmxlKGZpbmFsIEFzeW5jQ2FsbGFibGU8Vj4gYXN5bmNDYWxsYWJsZSkgeworICAgIHJldHVybiBhc3luY0NhbGxhYmxlOworICB9CisKKyAgQENoZWNrUmV0dXJuVmFsdWUKKyAgcHVibGljIHN0YXRpYyA8SSwgTz4gQXN5bmNGdW5jdGlvbjxJLCBPPiBwcm9wYWdhdGVBc3luY0Z1bmN0aW9uKAorICAgICAgZmluYWwgQXN5bmNGdW5jdGlvbjxJLCBPPiBmdW5jdGlvbikgeworICAgIHJldHVybiBmdW5jdGlvbjsKKyAgfQorCisgIEBDaGVja1JldHVyblZhbHVlCisgIHB1YmxpYyBzdGF0aWMgPFY+IENhbGxhYmxlPFY+IHByb3BhZ2F0ZUNhbGxhYmxlKGZpbmFsIENhbGxhYmxlPFY+IGNhbGxhYmxlKSB7CisgICAgcmV0dXJuIGNhbGxhYmxlOworICB9CisKKyAgQENoZWNrUmV0dXJuVmFsdWUKKyAgcHVibGljIHN0YXRpYyA8SSwgTz4gRnVuY3Rpb248SSwgTz4gcHJvcGFnYXRlRnVuY3Rpb24oZmluYWwgRnVuY3Rpb248SSwgTz4gZnVuY3Rpb24pIHsKKyAgICByZXR1cm4gZnVuY3Rpb247CisgIH0KKworICBAQ2hlY2tSZXR1cm5WYWx1ZQorICBwdWJsaWMgc3RhdGljIDxUPiBGdXR1cmVDYWxsYmFjazxUPiBwcm9wYWdhdGVGdXR1cmVDYWxsYmFjayhmaW5hbCBGdXR1cmVDYWxsYmFjazxUPiBjYWxsYmFjaykgeworICAgIHJldHVybiBjYWxsYmFjazsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgPEksIE8+IENsb3NpbmdGdW5jdGlvbjxJLCBPPiBwcm9wYWdhdGVDbG9zaW5nRnVuY3Rpb24oCisgICAgICBmaW5hbCBDbG9zaW5nRnVuY3Rpb248SSwgTz4gY2xvc2luZ0Z1bmN0aW9uKSB7CisgICAgcmV0dXJuIGNsb3NpbmdGdW5jdGlvbjsKKyAgfQorCisgIHByaXZhdGUgVHJhY2VQcm9wYWdhdGlvbigpIHt9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvQWdncmVnYXRlRXhjZXB0aW9uVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0FnZ3JlZ2F0ZUV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZWNlYzBmCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0FnZ3JlZ2F0ZUV4Y2VwdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDE3OSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlQ2FuY2VsbGVkRnV0dXJlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmU7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb24uRG93bmxvYWRSZXN1bHRDb2RlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVDYWxsYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FuY2VsbGF0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworLyoqIFRlc3RzIGZvciB7QGxpbmsgQWdncmVnYXRlRXhjZXB0aW9ufS4gKi8KK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBBZ2dyZWdhdGVFeGNlcHRpb25UZXN0IHsKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdW53cmFwRXhjZXB0aW9uX3JlY3Vyc2l2ZWx5VW53cmFwRXhlY3V0aW9uRXhjZXB0aW9uKCkgeworICAgIERvd25sb2FkRXhjZXB0aW9uIGRvd25sb2FkRXhjZXB0aW9uID0KKyAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUikuYnVpbGQoKTsKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXhlY3V0aW9uRXhjZXB0aW9uMSA9IG5ldyBFeGVjdXRpb25FeGNlcHRpb24oZG93bmxvYWRFeGNlcHRpb24pOworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleGVjdXRpb25FeGNlcHRpb24yID0gbmV3IEV4ZWN1dGlvbkV4Y2VwdGlvbihleGVjdXRpb25FeGNlcHRpb24xKTsKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXhlY3V0aW9uRXhjZXB0aW9uMyA9IG5ldyBFeGVjdXRpb25FeGNlcHRpb24oZXhlY3V0aW9uRXhjZXB0aW9uMik7CisKKyAgICBUaHJvd2FibGUgdGhyb3dhYmxlID0gQWdncmVnYXRlRXhjZXB0aW9uLnVud3JhcEV4Y2VwdGlvbihleGVjdXRpb25FeGNlcHRpb24zKTsKKyAgICBhc3NlcnRUaGF0KHRocm93YWJsZSkuaXNFcXVhbFRvKGRvd25sb2FkRXhjZXB0aW9uKTsKKyAgICBhc3NlcnRUaGF0KHRocm93YWJsZSkuaGFzTWVzc2FnZVRoYXQoKS5jb250YWlucygiVU5LTk9XTl9FUlJPUiIpOworICAgIGFzc2VydFRoYXQodGhyb3dhYmxlKS5oYXNDYXVzZVRoYXQoKS5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVud3JhcEV4Y2VwdGlvbl9rZWVwT3RoZXJFeGNlcHRpb25zKCkgeworICAgIE51bGxQb2ludGVyRXhjZXB0aW9uIG51bGxQb2ludGVyRXhjZXB0aW9uID0gbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJOUEUiKTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkb3dubG9hZEV4Y2VwdGlvbiA9CisgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUikKKyAgICAgICAgICAgIC5zZXRDYXVzZShudWxsUG9pbnRlckV4Y2VwdGlvbikKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgVGhyb3dhYmxlIHRocm93YWJsZSA9IEFnZ3JlZ2F0ZUV4Y2VwdGlvbi51bndyYXBFeGNlcHRpb24oZG93bmxvYWRFeGNlcHRpb24pOworICAgIGFzc2VydFRoYXQodGhyb3dhYmxlKS5pc0VxdWFsVG8oZG93bmxvYWRFeGNlcHRpb24pOworICAgIGFzc2VydFRoYXQodGhyb3dhYmxlKS5oYXNNZXNzYWdlVGhhdCgpLmNvbnRhaW5zKCJVTktOT1dOX0VSUk9SIik7CisgICAgYXNzZXJ0VGhhdCh0aHJvd2FibGUpLmhhc0NhdXNlVGhhdCgpLmlzRXF1YWxUbyhudWxsUG9pbnRlckV4Y2VwdGlvbik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0aHJvd2FibGVUb1N0cmluZ19tYXhDYXVzZURlcHRoQ3V0b2ZmKCkgeworICAgIFRocm93YWJsZSB0aHJvd2FibGUgPQorICAgICAgICBuZXcgSU9FeGNlcHRpb24oCisgICAgICAgICAgICAiT25lIiwKKyAgICAgICAgICAgIG5ldyBJT0V4Y2VwdGlvbigKKyAgICAgICAgICAgICAgICAiVHdvIiwKKyAgICAgICAgICAgICAgICBuZXcgSU9FeGNlcHRpb24oCisgICAgICAgICAgICAgICAgICAgICJUaHJlZSIsCisgICAgICAgICAgICAgICAgICAgIG5ldyBJT0V4Y2VwdGlvbigiRm91ciIsIG5ldyBJT0V4Y2VwdGlvbigiRml2ZSIsIG5ldyBJT0V4Y2VwdGlvbigiU2l4IikpKSkpKTsKKyAgICBhc3NlcnRUaGF0KEFnZ3JlZ2F0ZUV4Y2VwdGlvbi50aHJvd2FibGVUb1N0cmluZyh0aHJvd2FibGUpKQorICAgICAgICAuaXNFcXVhbFRvKAorICAgICAgICAgICAgImphdmEuaW8uSU9FeGNlcHRpb246IE9uZSIKKyAgICAgICAgICAgICAgICArICJcbkNhdXNlZCBieTogamF2YS5pby5JT0V4Y2VwdGlvbjogVHdvIgorICAgICAgICAgICAgICAgICsgIlxuQ2F1c2VkIGJ5OiBqYXZhLmlvLklPRXhjZXB0aW9uOiBUaHJlZSIKKyAgICAgICAgICAgICAgICArICJcbkNhdXNlZCBieTogamF2YS5pby5JT0V4Y2VwdGlvbjogRm91ciIKKyAgICAgICAgICAgICAgICArICJcbkNhdXNlZCBieTogamF2YS5pby5JT0V4Y2VwdGlvbjogRml2ZSIKKyAgICAgICAgICAgICAgICArICJcbiguLi4pIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0aHJvd0lmRmFpbGVkX211bHRpcGxlRXhjZXB0aW9ucygpIHsKKyAgICBMaXN0PExpc3RlbmFibGVGdXR1cmU8Vm9pZD4+IGZ1dHVyZXMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgIC8vIEZpcnN0IDEwIGZ1dHVyZXMgZmFpbGVkLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgZnV0dXJlcy5hZGQoCisgICAgICAgICAgaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLlVOS05PV05fRVJST1IpCisgICAgICAgICAgICAgICAgICAuc2V0TWVzc2FnZShTdHJpbmcuZm9ybWF0KCJFUlJPUl8jJWQiLCBpICsgMSkpCisgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkpOworICAgIH0KKyAgICAvLyBOZXh0IDEwIGZ1dHVyZXMgYXJlIGNhbmNlbGVkLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgZnV0dXJlcy5hZGQoaW1tZWRpYXRlQ2FuY2VsbGVkRnV0dXJlKCkpOworICAgIH0KKyAgICAvLyBUaGUgcmVtYWluaW5nIDEwIGZ1dHVyZXMgc3VjY2VlZGVkLgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgZnV0dXJlcy5hZGQoaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKyAgICB9CisKKyAgICBBZ2dyZWdhdGVFeGNlcHRpb24gZXhjZXB0aW9uID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgQWdncmVnYXRlRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBZ2dyZWdhdGVFeGNlcHRpb24udGhyb3dJZkZhaWxlZChmdXR1cmVzLCAiRmFpbGVkIikpOworICAgIEltbXV0YWJsZUxpc3Q8VGhyb3dhYmxlPiBmYWlsdXJlcyA9IGV4Y2VwdGlvbi5nZXRGYWlsdXJlcygpOworICAgIGFzc2VydFRoYXQoZmFpbHVyZXMpLmhhc1NpemUoMjApOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldChpKSkuaXNOb3ROdWxsKCk7CisgICAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldChpKSkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICAgIGFzc2VydFRoYXQoZmFpbHVyZXMuZ2V0KGkpKS5oYXNNZXNzYWdlVGhhdCgpLmNvbnRhaW5zKCJFUlJPUiIpOworICAgIH0KKyAgICBmb3IgKGludCBpID0gMTA7IGkgPCAyMDsgaSsrKSB7CisgICAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldChpKSkuaXNOb3ROdWxsKCk7CisgICAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldChpKSkuaXNJbnN0YW5jZU9mKENhbmNlbGxhdGlvbkV4Y2VwdGlvbi5jbGFzcyk7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGhyb3dJZkZhaWxlZF93aXRoQ2FsbGJhY2tfaW52b2tlc0NhbGxiYWNrKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTGlzdDxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PiBmdXR1cmVzID0gbmV3IEFycmF5TGlzdDw+KCk7CisKKyAgICAvLyBGaXJzdCAxMCBmdXR1cmVzIGZhaWxlZC4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgIGZ1dHVyZXMuYWRkKAorICAgICAgICAgIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5VTktOT1dOX0VSUk9SKQorICAgICAgICAgICAgICAgICAgLnNldE1lc3NhZ2UoU3RyaW5nLmZvcm1hdCgiRVJST1JfIyVkIiwgaSArIDEpKQorICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpKTsKKyAgICB9CisgICAgLy8gTmV4dCAxMCBmdXR1cmVzIGFyZSBjYW5jZWxlZC4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgIGZ1dHVyZXMuYWRkKGltbWVkaWF0ZUNhbmNlbGxlZEZ1dHVyZSgpKTsKKyAgICB9CisgICAgLy8gVGhlIHJlbWFpbmluZyAxMCBmdXR1cmVzIHN1Y2NlZWRlZC4KKyAgICBmb3IgKGludCBpID0gMDsgaSA8IDEwOyBpKyspIHsKKyAgICAgIGZ1dHVyZXMuYWRkKGltbWVkaWF0ZVZvaWRGdXR1cmUoKSk7CisgICAgfQorCisgICAgQXRvbWljSW50ZWdlciBzdWNjZXNzQ291bnQgPSBuZXcgQXRvbWljSW50ZWdlcigwKTsKKyAgICBBdG9taWNJbnRlZ2VyIGZhaWx1cmVDb3VudCA9IG5ldyBBdG9taWNJbnRlZ2VyKDApOworICAgIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiBleGNlcHRpb24gPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBBZ2dyZWdhdGVFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIEFnZ3JlZ2F0ZUV4Y2VwdGlvbi50aHJvd0lmRmFpbGVkKAorICAgICAgICAgICAgICAgICAgICBmdXR1cmVzLAorICAgICAgICAgICAgICAgICAgICBPcHRpb25hbC5vZigKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBGdXR1cmVDYWxsYmFjazxWb2lkPigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uU3VjY2VzcyhWb2lkIHVudXNlZCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDb3VudC5nZXRBbmRJbmNyZW1lbnQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkZhaWx1cmUoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsdXJlQ291bnQuZ2V0QW5kSW5jcmVtZW50KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0pLAorICAgICAgICAgICAgICAgICAgICAiRmFpbGVkIikpOworCisgICAgLy8gTWFrZSBzdXJlIHRoYXQgb25TdWNjZXNzIGlzIGNhbGxlZCAxMCB0aW1lcywgYW5kIG9uRmFpbHVyZSBpcyBjYWxsZWQgMjAgdGltZXMuCisgICAgYXNzZXJ0VGhhdChleGNlcHRpb24uZ2V0RmFpbHVyZXMoKSkuaGFzU2l6ZSgyMCk7CisgICAgYXNzZXJ0VGhhdChzdWNjZXNzQ291bnQuZ2V0KCkpLmlzRXF1YWxUbygxMCk7CisgICAgYXNzZXJ0VGhhdChmYWlsdXJlQ291bnQuZ2V0KCkpLmlzRXF1YWxUbygyMCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9BbmRyb2lkTWFuaWZlc3QueG1sIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0FuZHJvaWRNYW5pZmVzdC54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTQ1ZjcxYwotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9BbmRyb2lkTWFuaWZlc3QueG1sCkBAIC0wLDAgKzEsMzQgQEAKKzwhLS0KKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCistLT4KKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9InV0Zi04Ij8+Cis8bWFuaWZlc3QgeG1sbnM6YW5kcm9pZD0iaHR0cDovL3NjaGVtYXMuYW5kcm9pZC5jb20vYXBrL3Jlcy9hbmRyb2lkIgorICBwYWNrYWdlPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZCIgPgorCisgIDx1c2VzLXNkayBhbmRyb2lkOm1pblNka1ZlcnNpb249IjE2IiAvPgorICA8dXNlcy1wZXJtaXNzaW9uIGFuZHJvaWQ6bmFtZT0iYW5kcm9pZC5wZXJtaXNzaW9uLklOVEVSTkVUIi8+CisgIDx1c2VzLXBlcm1pc3Npb24KKyAgICBhbmRyb2lkOm5hbWU9ImNvbS5nb29nbGUuYW5kcm9pZC5nbXMucGVybWlzc2lvbi5CSU5EX05FVFdPUktfVEFTS19TRVJWSUNFIi8+CisgIDx1c2VzLXBlcm1pc3Npb24gYW5kcm9pZDpuYW1lPSJhbmRyb2lkLnBlcm1pc3Npb24uQUNDRVNTX05FVFdPUktfU1RBVEUiLz4KKworICA8YXBwbGljYXRpb24gYW5kcm9pZDpuYW1lPSJhbmRyb2lkLnN1cHBvcnQubXVsdGlkZXguTXVsdGlEZXhBcHBsaWNhdGlvbiI+CisgIDwvYXBwbGljYXRpb24+CisKKyAgPGluc3RydW1lbnRhdGlvbgorICAgIGFuZHJvaWQ6bmFtZT0iY29tLmdvb2dsZS5hbmRyb2lkLmFwcHMuY29tbW9uLnRlc3RpbmcudGVzdHJ1bm5lci5Hb29nbGUzSW5zdHJ1bWVudGF0aW9uVGVzdFJ1bm5lciIKKyAgICBhbmRyb2lkOnRhcmdldFBhY2thZ2U9ImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkIiAvPgorPC9tYW5pZmVzdD4KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jODBmZjU4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0JVSUxECkBAIC0wLDAgKzEsMzc5IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCIvL3Rvb2xzL2J1aWxkX2RlZnMvdGVzdGluZzpiemxfbGlicmFyeS5iemwiLCAiYnpsX2xpYnJhcnkiKQorbG9hZCgiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6dGVzdF9kZWZzLmJ6bCIsICJtZGRfYW5kcm9pZF90ZXN0IiwgIm1kZF9sb2NhbF90ZXN0IikKK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xvY2FsX3Rlc3QiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCittZGRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIk1vYmlsZURhdGFEb3dubG9hZFRlc3QiLAorICAgIHNyY3MgPSBbIk1vYmlsZURhdGFEb3dubG9hZFRlc3QuamF2YSJdLAorICAgIHRlc3RfY2xhc3MgPSAiY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuTW9iaWxlRGF0YURvd25sb2FkVGVzdCIsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkTGlzdGVuZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZpbGVTb3VyY2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpVc2FnZUV2ZW50IiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hY2NvdW50OkFjY291bnRVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFuZHJvaWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOk1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6RXZlbnRMb2dnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpQcm90b0NvbnZlcnNpb25VdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yOkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIiwKKyAgICAgICAgIi8vcHJvdG86Y2xpZW50X2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86YW55X3Byb3RvIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86cHJvdG9idWZfbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9wcm90b2J1Zi8vOndyYXBwZXJzX3Byb3RvIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiQWdncmVnYXRlRXhjZXB0aW9uVGVzdCIsCisgICAgc3JjcyA9IFsiQWdncmVnYXRlRXhjZXB0aW9uVGVzdC5qYXZhIl0sCisgICAgbWFuaWZlc3RfdmFsdWVzID0geworICAgICAgICAibWluU2RrVmVyc2lvbiI6ICIxNiIsCisgICAgICAgICJ0YXJnZXRTZGtWZXJzaW9uIjogIjI3IiwKKyAgICB9LAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6QWdncmVnYXRlRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpEb3dubG9hZEV4Y2VwdGlvbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkRvd25sb2FkRXhjZXB0aW9uVGVzdCIsCisgICAgc3JjcyA9IFsiRG93bmxvYWRFeGNlcHRpb25UZXN0LmphdmEiXSwKKyAgICBtYW5pZmVzdF92YWx1ZXMgPSB7CisgICAgICAgICJtaW5TZGtWZXJzaW9uIjogIjE2IiwKKyAgICAgICAgInRhcmdldFNka1ZlcnNpb24iOiAiMjciLAorICAgIH0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpEb3dubG9hZEV4Y2VwdGlvbiIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK21kZF9hbmRyb2lkX3Rlc3QoCisgICAgbmFtZSA9ICJNb2JpbGVEYXRhRG93bmxvYWRJbnRlZ3JhdGlvblRlc3QiLAorICAgIHNpemUgPSAibGFyZ2UiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJNb2JpbGVEYXRhRG93bmxvYWRJbnRlZ3JhdGlvblRlc3QuamF2YSIsCisgICAgICAgICJUZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmphdmEiLAorICAgICAgICAiVHdvU3RlcFBvcHVsYXRvci5qYXZhIiwKKyAgICAgICAgIlppcEZvbGRlckZpbGVHcm91cFBvcHVsYXRvci5qYXZhIiwKKyAgICBdLAorICAgIGRhdGEgPSBbCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0ZGF0YTppbnRlZ3JhdGlvbl90ZXN0X2RhdGFfZmlsZXMiLAorICAgIF0sCisgICAgbWFuaWZlc3QgPSAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpBbmRyb2lkTWFuaWZlc3QueG1sIiwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpBZ2dyZWdhdGVFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6TG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hY2NvdW50OkFjY291bnRVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyOkZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFuZHJvaWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZF9hZGFwdGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpEaXJlY3RvcnlVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yOk5ldHdvcmtVc2FnZU1vbml0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3RyYWNpbmciLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6RmFrZVRpbWVTb3VyY2UiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpUZXN0RmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpUZXN0RmxhZ3MiLAorICAgICAgICAiLy9wcm90bzpjbGllbnRfY29uZmlnX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL3Byb3RvOmRvd25sb2FkX2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkX3Nka19saW51eCIsCisgICAgICAgICJAYW5kcm9pZHhfY29yZV9jb3JlIiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBjcm9uZXQtYXBpIiwKKyAgICAgICAgIkBqdW5pdCIsCisgICAgICAgICJAbW9ja2l0byIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK21kZF9hbmRyb2lkX3Rlc3QoCisgICAgbmFtZSA9ICJEb3dubG9hZEZpbGVHcm91cEludGVncmF0aW9uVGVzdCIsCisgICAgc2l6ZSA9ICJsYXJnZSIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIkRvd25sb2FkRmlsZUdyb3VwSW50ZWdyYXRpb25UZXN0LmphdmEiLAorICAgICAgICAiVGVzdEZpbGVHcm91cFBvcHVsYXRvci5qYXZhIiwKKyAgICBdLAorICAgIG1hbmlmZXN0ID0gIkFuZHJvaWRNYW5pZmVzdC54bWwiLAorICAgIHRhZ3MgPSBbInJlcXVpcmVzLW5ldDpleHRlcm5hbCJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkFnZ3JlZ2F0ZUV4Y2VwdGlvbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkTGlzdGVuZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyOkZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvZGFnZ2VyL2Rvd25sb2FkZXIyOmJhc2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9kYWdnZXIvZG93bmxvYWRlcjI6YmFzZV9kZXBzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFuZHJvaWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvaW50ZWdyYXRpb24vZG93bmxvYWRlcjpkb3dubG9hZGVyMl9zcCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOmNvbXByZXNzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yOkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yOk5ldHdvcmtVc2FnZU1vbml0b3IiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6VGVzdEZsYWdzIiwKKyAgICAgICAgIi8vcHJvdG86Y2xpZW50X2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkX3Nka19saW51eCIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAY3JvbmV0LWFwaSIsCisgICAgICAgICJAanVuaXQiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCittZGRfYW5kcm9pZF90ZXN0KAorICAgIG5hbWUgPSAiRG93bmxvYWRGaWxlR3JvdXBBbmRyb2lkU2hhcmluZ0ludGVncmF0aW9uVGVzdCIsCisgICAgc2l6ZSA9ICJsYXJnZSIsCisgICAgdGltZW91dCA9ICJsb25nIiwKKyAgICBzcmNzID0gWworICAgICAgICAiRG93bmxvYWRGaWxlR3JvdXBBbmRyb2lkU2hhcmluZ0ludGVncmF0aW9uVGVzdC5qYXZhIiwKKyAgICAgICAgIlRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuamF2YSIsCisgICAgXSwKKyAgICBkYXRhID0gWworICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGE6aW50ZWdyYXRpb25fdGVzdF9kYXRhX2ZpbGVzIiwKKyAgICBdLAorICAgIG1hbmlmZXN0ID0gIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6QW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgdGFyZ2V0X2RldmljZXMgPSBbIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2dlbmVyaWNfcGhvbmU6Z29vZ2xlXzMwX3g4NiJdLCAgIyBCbG9iIFNoYXJpbmcgYXZhaWxhYmxlIGluIFIrCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRMaXN0ZW5lciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RmxhZ3MiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkxvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6TW9iaWxlRGF0YURvd25sb2FkQnVpbGRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlcjpGaWxlRG93bmxvYWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczphbmRyb2lkIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmJsb2JfdXJpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmJsb2JzdG9yZV9iYWNrZW5kIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtczpjb21wcmVzcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpOZXR3b3JrVXNhZ2VNb25pdG9yIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6VGVzdEZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6VGVzdEZsYWdzIiwKKyAgICAgICAgIi8vcHJvdG86Y2xpZW50X2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkX3Nka19saW51eCIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAanVuaXQiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCittZGRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkRvd25sb2FkRmlsZVRlc3QiLAorICAgIHNyY3MgPSBbIkRvd25sb2FkRmlsZVRlc3QuamF2YSJdLAorICAgIHRlc3RfY2xhc3MgPSAiY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRGaWxlVGVzdCIsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkTGlzdGVuZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOk1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXI6RmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlOkRvd25sb2FkTGlzdGVuZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3I6RG93bmxvYWRQcm9ncmVzc01vbml0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3I6TmV0d29ya1VzYWdlTW9uaXRvciIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOkJsb2NraW5nRmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpGYWtlVGltZVNvdXJjZSIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOlRlc3RGbGFncyIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAY3JvbmV0LWFwaSIsCisgICAgICAgICJAbW9ja2l0byIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK21kZF9hbmRyb2lkX3Rlc3QoCisgICAgbmFtZSA9ICJEb3dubG9hZEZpbGVJbnRlZ3JhdGlvblRlc3QiLAorICAgIHNpemUgPSAibGFyZ2UiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJEb3dubG9hZEZpbGVJbnRlZ3JhdGlvblRlc3QuamF2YSIsCisgICAgXSwKKyAgICBtYW5pZmVzdCA9ICJBbmRyb2lkTWFuaWZlc3QueG1sIiwKKyAgICB0YWdzID0gWyJyZXF1aXJlcy1uZXQ6ZXh0ZXJuYWwiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpBZ2dyZWdhdGVFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpEb3dubG9hZExpc3RlbmVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6TW9iaWxlRGF0YURvd25sb2FkQnVpbGRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlcjpGaWxlRG93bmxvYWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL2RhZ2dlci9kb3dubG9hZGVyMjpiYXNlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvZGFnZ2VyL2Rvd25sb2FkZXIyOmJhc2VfZGVwcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczphbmRyb2lkIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXI6ZG93bmxvYWRlcjJfc3AiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtczpjb21wcmVzcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpOZXR3b3JrVXNhZ2VNb25pdG9yIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6QmxvY2tpbmdGaWxlRG93bmxvYWRlciIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOkZha2VUaW1lU291cmNlIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6VGVzdEZsYWdzIiwKKyAgICAgICAgIi8vcHJvdG86Y2xpZW50X2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkX3Nka19saW51eCIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAY3JvbmV0LWFwaSIsCisgICAgICAgICJAanVuaXQiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCittZGRfYW5kcm9pZF90ZXN0KAorICAgIG5hbWUgPSAiSW1wb3J0RmlsZXNJbnRlZ3JhdGlvblRlc3QiLAorICAgIHNpemUgPSAibGFyZ2UiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJJbXBvcnRGaWxlc0ludGVncmF0aW9uVGVzdC5qYXZhIiwKKyAgICAgICAgIlRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuamF2YSIsCisgICAgXSwKKyAgICBkYXRhID0gWworICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGE6aW50ZWdyYXRpb25fdGVzdF9kYXRhX2ZpbGVzIiwKKyAgICBdLAorICAgIG1hbmlmZXN0ID0gIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6QW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6QWdncmVnYXRlRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpEb3dubG9hZEV4Y2VwdGlvbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RmlsZVNvdXJjZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RmxhZ3MiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOk1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXI6RmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvaW5saW5lOklubGluZUZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvZGFnZ2VyL2Rvd25sb2FkZXIyOmJhc2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9kYWdnZXIvZG93bmxvYWRlcjI6YmFzZV9kZXBzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFuZHJvaWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpmYWtlX2ZpbGVfYmFja2VuZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9pbnRlZ3JhdGlvbi9kb3dubG9hZGVyOmRvd25sb2FkZXIyX3NwIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyZWFtIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6Y29tcHJlc3MiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3I6RG93bmxvYWRQcm9ncmVzc01vbml0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3I6TmV0d29ya1VzYWdlTW9uaXRvciIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOkJsb2NraW5nRmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpUZXN0RmxhZ3MiLAorICAgICAgICAiLy9wcm90bzpjbGllbnRfY29uZmlnX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL3Byb3RvOmRvd25sb2FkX2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGFuZHJvaWRfc2RrX2xpbnV4IiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86cHJvdG9idWZfbGl0ZSIsCisgICAgICAgICJAY3JvbmV0LWFwaSIsCisgICAgICAgICJAanVuaXQiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCittZGRfYW5kcm9pZF90ZXN0KAorICAgIG5hbWUgPSAiTWRkR2FyYmFnZUNvbGxlY3Rpb25XaXRoQW5kcm9pZFNoYXJpbmdJbnRlZ3JhdGlvblRlc3QiLAorICAgIHNpemUgPSAibGFyZ2UiLAorICAgIHRpbWVvdXQgPSAibG9uZyIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIk1kZEdhcmJhZ2VDb2xsZWN0aW9uV2l0aEFuZHJvaWRTaGFyaW5nSW50ZWdyYXRpb25UZXN0LmphdmEiLAorICAgICAgICAiVGVzdEZpbGVHcm91cFBvcHVsYXRvci5qYXZhIiwKKyAgICBdLAorICAgIGRhdGEgPSBbCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0ZGF0YTppbnRlZ3JhdGlvbl90ZXN0X2RhdGFfZmlsZXMiLAorICAgIF0sCisgICAgbWFuaWZlc3QgPSAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpBbmRyb2lkTWFuaWZlc3QueG1sIiwKKyAgICB0YXJnZXRfZGV2aWNlcyA9IFsiLy90b29scy9hbmRyb2lkL2VtdWxhdGVkX2RldmljZXMvZ2VuZXJpY19waG9uZTpnb29nbGVfMzBfeDg2Il0sICAjIEJsb2IgU2hhcmluZyBhdmFpbGFibGUgaW4gUisKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpEb3dubG9hZExpc3RlbmVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGbGFncyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6TG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyOkZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFuZHJvaWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YmxvYl91cmkiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YmxvYnN0b3JlX2JhY2tlbmQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOmNvbXByZXNzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yOkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yOk5ldHdvcmtVc2FnZU1vbml0b3IiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TWRkVGVzdFV0aWwiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpUZXN0RmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpUZXN0RmxhZ3MiLAorICAgICAgICAiLy9wcm90bzpjbGllbnRfY29uZmlnX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL3Byb3RvOmRvd25sb2FkX2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGFuZHJvaWRfc2RrX2xpbnV4IiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBqdW5pdCIsCisgICAgICAgICJAbW9ja2l0byIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2J6bF9saWJyYXJ5KAorICAgIG5hbWUgPSAidGVzdF9kZWZzX2J6bCIsCisgICAgc3JjcyA9IFsidGVzdF9kZWZzLmJ6bCJdLAorICAgIHBhcnNlX3Rlc3RzID0gRmFsc2UsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vZGV2dG9vbHMvYnVpbGRfY2xlYW5lci9za3lsYXJrOmJ1aWxkX2RlZnNfbGliIiwKKyAgICAgICAgIi8vZGV2dG9vbHMvZGVwcy9jaGVjazpkZXBzX2NoZWNrIiwKKyAgICAgICAgIi8vdG9vbHMvYnVpbGRfZGVmcy9hbmRyb2lkOnJ1bGVzX2J6bCIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Eb3dubG9hZEV4Y2VwdGlvblRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Eb3dubG9hZEV4Y2VwdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZWQxYzZlCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkRXhjZXB0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLmxhYnMudHJ1dGguRnV0dXJlU3ViamVjdC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZTsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uLkRvd25sb2FkUmVzdWx0Q29kZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCisvKiogVGVzdHMgZm9yIHtAbGluayBEb3dubG9hZEV4Y2VwdGlvbn0uICovCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgRG93bmxvYWRFeGNlcHRpb25UZXN0IHsKKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB3cmFwSWZGYWlsZWRfZnV0dXJlRmFpbHNfd3JhcHNGYWlsZWRGdXR1cmVXaXRoRG93bmxvYWRFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGZ1dHVyZSA9IGltbWVkaWF0ZUZhaWxlZEZ1dHVyZShuZXcgSU9FeGNlcHRpb24oImNhdXNlIikpOworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gd3JhcHBlZEZ1dHVyZSA9CisgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLndyYXBJZkZhaWxlZCgKKyAgICAgICAgICAgIGZ1dHVyZSwgRG93bmxvYWRSZXN1bHRDb2RlLkFORFJPSURfRE9XTkxPQURFUl9IVFRQX0VSUk9SLCAiZmFpbGVkIik7CisgICAgYXNzZXJ0VGhhdCh3cmFwcGVkRnV0dXJlKS53aGVuRG9uZSgpLmlzRmFpbGVkV2l0aChEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgYXNzZXJ0VGhhdCh3cmFwcGVkRnV0dXJlKS53aGVuRG9uZSgpLmhhc0ZhaWx1cmVUaGF0KCkuaGFzTWVzc2FnZVRoYXQoKS5pc0VxdWFsVG8oImZhaWxlZCIpOworICAgIGFzc2VydFRoYXQod3JhcHBlZEZ1dHVyZSkKKyAgICAgICAgLndoZW5Eb25lKCkKKyAgICAgICAgLmhhc0ZhaWx1cmVUaGF0KCkKKyAgICAgICAgLmhhc0NhdXNlVGhhdCgpCisgICAgICAgIC5pc0luc3RhbmNlT2YoSU9FeGNlcHRpb24uY2xhc3MpOworICAgIGFzc2VydFRoYXQod3JhcHBlZEZ1dHVyZSkKKyAgICAgICAgLndoZW5Eb25lKCkKKyAgICAgICAgLmhhc0ZhaWx1cmVUaGF0KCkKKyAgICAgICAgLmhhc0NhdXNlVGhhdCgpCisgICAgICAgIC5oYXNNZXNzYWdlVGhhdCgpCisgICAgICAgIC5pc0VxdWFsVG8oImNhdXNlIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB3cmFwSWZGYWlsZWRfZnV0dXJlU3VjY2VlZHNfbm9vcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIExpc3RlbmFibGVGdXR1cmU8SW50ZWdlcj4gZnV0dXJlID0gaW1tZWRpYXRlRnV0dXJlKDcpOworICAgIExpc3RlbmFibGVGdXR1cmU8SW50ZWdlcj4gd3JhcHBlZEZ1dHVyZSA9CisgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLndyYXBJZkZhaWxlZCgKKyAgICAgICAgICAgIGZ1dHVyZSwgRG93bmxvYWRSZXN1bHRDb2RlLkFORFJPSURfRE9XTkxPQURFUl9IVFRQX0VSUk9SLCAiZmFpbGVkIik7CisgICAgYXNzZXJ0VGhhdCh3cmFwcGVkRnV0dXJlKS53aGVuRG9uZSgpLmhhc1ZhbHVlKDcpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvRG93bmxvYWRGaWxlR3JvdXBBbmRyb2lkU2hhcmluZ0ludGVncmF0aW9uVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkRmlsZUdyb3VwQW5kcm9pZFNoYXJpbmdJbnRlZ3JhdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MDNkNTczCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkRmlsZUdyb3VwQW5kcm9pZFNoYXJpbmdJbnRlZ3JhdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDYyMiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGVzdEZpbGVHcm91cFBvcHVsYXRvci5GSUxFX0NIRUNLU1VNOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UZXN0RmlsZUdyb3VwUG9wdWxhdG9yLkZJTEVfSUQ7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuRklMRV9TSVpFOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UZXN0RmlsZUdyb3VwUG9wdWxhdG9yLkZJTEVfVVJMOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdC5TRUNPTkRTOworCitpbXBvcnQgYW5kcm9pZC5hcHAuYmxvYi5CbG9iU3RvcmVNYW5hZ2VyOworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmV4dC5qdW5pdC5ydW5uZXJzLkFuZHJvaWRKVW5pdDQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5BbmRyb2lkRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5CbG9iU3RvcmVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuQmxvYlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuQ29tcHJlc3NUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubW9uaXRvci5Eb3dubG9hZFByb2dyZXNzTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLk5ldHdvcmtVc2FnZU1vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5UZXN0RmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5UZXN0RmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5CYXNlRW5jb2Rpbmc7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5DbGllbnRDb25maWdQcm90by5DbGllbnRGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkNsaWVudENvbmZpZ1Byb3RvLkNsaWVudEZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlR3JvdXA7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5Eb3dubG9hZENvbmRpdGlvbnMuRGV2aWNlTmV0d29ya1BvbGljeTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnNlY3VyaXR5Lk1lc3NhZ2VEaWdlc3Q7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TY2hlZHVsZWRFeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgb3JnLmp1bml0LkFmdGVyOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworCitAUnVuV2l0aChBbmRyb2lkSlVuaXQ0LmNsYXNzKQorcHVibGljIGNsYXNzIERvd25sb2FkRmlsZUdyb3VwQW5kcm9pZFNoYXJpbmdJbnRlZ3JhdGlvblRlc3QgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiRG93bmxvYWRGaWxlR3JvdXBJbnRlZ3JhdGlvblRlc3QiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0RPV05MT0FEX0ZJTEVfR1JPVVBfV0FJVF9USU1FX1NFQ1MgPSAzMDA7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfREFUQV9SRUxBVElWRV9QQVRIID0KKyAgICAgICJ0aGlyZF9wYXJ0eS9qYXZhX3NyYy9hbmRyb2lkX2xpYnMvbW9iaWxlZGF0YWRvd25sb2FkL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0ZGF0YS8iOworCisgIC8vIE5vdGU6IENvbnRyb2wgRXhlY3V0b3IgbXVzdCBub3QgYmUgYSBzaW5nbGUgdGhyZWFkIGV4ZWN1dG9yLgorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2UgQ09OVFJPTF9FWEVDVVRPUiA9CisgICAgICBNb3JlRXhlY3V0b3JzLmxpc3RlbmluZ0RlY29yYXRvcihFeGVjdXRvcnMubmV3Q2FjaGVkVGhyZWFkUG9vbCgpKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIERPV05MT0FEX0VYRUNVVE9SID0KKyAgICAgIEV4ZWN1dG9ycy5uZXdTY2hlZHVsZWRUaHJlYWRQb29sKDIpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0dST1VQX1RPX1NIQVJFXzEgPSAidGVzdC1ncm91cC0xIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfR1JPVVBfVE9fU0hBUkVfMiA9ICJ0ZXN0LWdyb3VwLTIiOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0lEXzEgPSAidGVzdC1maWxlLXRvLXNoYXJlLTEiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9DSEVDS1NVTV8xID0gImZjYzk2YjI3MjYzM2NkZjZjNGJiZDJkNzc1MTJjY2E1MWJmYjFkYmQiOyAvLyBTSEFfMQorICBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfQU5EUk9JRF9TSEFSSU5HX0NIRUNLU1VNXzEgPQorICAgICAgIjIyNTAxN2I1ZDVlYzM1NzMyOTQwYWY4MTNiMWFiN2JlNTE5MWU0YzUyNjU5OTUzZTc1YTFhMzZhMTM5OGM0OGQiOyAvLyBTSEFfMjU2CisgIHN0YXRpYyBmaW5hbCBpbnQgRklMRV9TSVpFXzEgPSA1NzsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX1VSTF8xID0gImh0dHBzOi8vd3d3LmdzdGF0aWMuY29tL2ljaW5nL2lkZC9zYW1wbGVfZ3JvdXAvc3RlcDEudHh0IjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9JRF8yID0gInRlc3QtZmlsZS10by1zaGFyZS0yIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfQ0hFQ0tTVU1fMiA9ICIyMmQ1NjVjOTUxMWM1NzUyYmFhYjhhM2JiZjdiOTU1YmQyY2E2NmZkIjsgLy8gU0hBXzEKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0FORFJPSURfU0hBUklOR19DSEVDS1NVTV8yID0KKyAgICAgICI5ODg2M2Q1NmQ2ODNmNmYxZmRmMTdiMzg4NzNhNDgxZjQ3YTMyMTZlMDUzMTQ3NTBmOWIzODQyMjBhZjQxOGFiIjsgLy8gU0hBXzI1NgorICBzdGF0aWMgZmluYWwgaW50IEZJTEVfU0laRV8yID0gMTM7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9VUkxfMiA9ICJodHRwczovL3d3dy5nc3RhdGljLmNvbS9pY2luZy9pZGQvc2FtcGxlX2dyb3VwL3N0ZXAyLnR4dCI7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29udGV4dCBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKworICBATW9jayBwcml2YXRlIFRhc2tTY2hlZHVsZXIgbW9ja1Rhc2tTY2hlZHVsZXI7CisgIEBNb2NrIHByaXZhdGUgTmV0d29ya1VzYWdlTW9uaXRvciBtb2NrTmV0d29ya1VzYWdlTW9uaXRvcjsKKyAgQE1vY2sgcHJpdmF0ZSBEb3dubG9hZFByb2dyZXNzTW9uaXRvciBtb2NrRG93bmxvYWRQcm9ncmVzc01vbml0b3I7CisgIEBNb2NrIHByaXZhdGUgTG9nZ2VyIG1vY2tMb2dnZXI7CisKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIEJsb2JTdG9yZUJhY2tlbmQgYmxvYlN0b3JlQmFja2VuZDsKKyAgcHJpdmF0ZSBCbG9iU3RvcmVNYW5hZ2VyIGJsb2JTdG9yZU1hbmFnZXI7CisgIHByaXZhdGUgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZDsKKworICBwcml2YXRlIGZpbmFsIFRlc3RGbGFncyBmbGFncyA9IG5ldyBUZXN0RmxhZ3MoKTsKKworICBAUnVsZSBwdWJsaWMgZmluYWwgTW9ja2l0b1J1bGUgbW9ja3MgPSBNb2NraXRvSlVuaXQucnVsZSgpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmbGFncy5tZGRBbmRyb2lkU2hhcmluZ1NhbXBsZUludGVydmFsID0gT3B0aW9uYWwub2YoMSk7CisgICAgZmxhZ3MubWRkRGVmYXVsdFNhbXBsZUludGVydmFsID0gT3B0aW9uYWwub2YoMSk7CisgICAgYmxvYlN0b3JlQmFja2VuZCA9IG5ldyBCbG9iU3RvcmVCYWNrZW5kKGNvbnRleHQpOworICAgIGJsb2JTdG9yZU1hbmFnZXIgPSAoQmxvYlN0b3JlTWFuYWdlcikgY29udGV4dC5nZXRTeXN0ZW1TZXJ2aWNlKENvbnRleHQuQkxPQl9TVE9SRV9TRVJWSUNFKTsKKworICAgIGZpbGVTdG9yYWdlID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICAvKiBiYWNrZW5kcz0gKi8gSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgICAgICBBbmRyb2lkRmlsZUJhY2tlbmQuYnVpbGRlcihjb250ZXh0KS5idWlsZCgpLAorICAgICAgICAgICAgICAgIGJsb2JTdG9yZUJhY2tlbmQsCisgICAgICAgICAgICAgICAgbmV3IEphdmFGaWxlQmFja2VuZCgpKSwKKyAgICAgICAgICAgIC8qIHRyYW5zZm9ybXM9ICovIEltbXV0YWJsZUxpc3Qub2YobmV3IENvbXByZXNzVHJhbnNmb3JtKCkpLAorICAgICAgICAgICAgLyogbW9uaXRvcnM9ICovIEltbXV0YWJsZUxpc3Qub2YobW9ja05ldHdvcmtVc2FnZU1vbml0b3IsIG1vY2tEb3dubG9hZFByb2dyZXNzTW9uaXRvcikpOworCisgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGZpbGVEb3dubG9hZGVyU3VwcGxpZXIgPQorICAgICAgICAoKSAtPgorICAgICAgICAgICAgbmV3IFRlc3RGaWxlRG93bmxvYWRlcigKKyAgICAgICAgICAgICAgICBURVNUX0RBVEFfUkVMQVRJVkVfUEFUSCwKKyAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgICAgICBNb3JlRXhlY3V0b3JzLmxpc3RlbmluZ0RlY29yYXRvcihET1dOTE9BRF9FWEVDVVRPUikpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlci5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRDb250ZXh0KGNvbnRleHQpCisgICAgICAgICAgICAuc2V0Q29udHJvbEV4ZWN1dG9yKENPTlRST0xfRVhFQ1VUT1IpCisgICAgICAgICAgICAuc2V0RmlsZURvd25sb2FkZXJTdXBwbGllcihmaWxlRG93bmxvYWRlclN1cHBsaWVyKQorICAgICAgICAgICAgLnNldFRhc2tTY2hlZHVsZXIoT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpKQorICAgICAgICAgICAgLnNldERlbHRhRGVjb2Rlck9wdGlvbmFsKE9wdGlvbmFsLmFic2VudCgpKQorICAgICAgICAgICAgLnNldEZpbGVTdG9yYWdlKGZpbGVTdG9yYWdlKQorICAgICAgICAgICAgLnNldE5ldHdvcmtVc2FnZU1vbml0b3IobW9ja05ldHdvcmtVc2FnZU1vbml0b3IpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRNb25pdG9yT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKSkKKyAgICAgICAgICAgIC5zZXRMb2dnZXJPcHRpb25hbChPcHRpb25hbC5vZihtb2NrTG9nZ2VyKSkKKyAgICAgICAgICAgIC5zZXRGbGFnc09wdGlvbmFsKE9wdGlvbmFsLm9mKGZsYWdzKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICB9CisKKyAgQEFmdGVyCisgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgbW9iaWxlRGF0YURvd25sb2FkLmNsZWFyKCkuZ2V0KCk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgY29tcHV0ZURpZ2VzdChieXRlW10gYnl0ZUNvbnRlbnQsIFN0cmluZyBhbGdvcml0aG0pIHRocm93cyBFeGNlcHRpb24geworICAgIE1lc3NhZ2VEaWdlc3QgbWVzc2FnZURpZ2VzdCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoYWxnb3JpdGhtKTsKKyAgICBpZiAobWVzc2FnZURpZ2VzdCA9PSBudWxsKSB7CisgICAgICByZXR1cm4gIiI7CisgICAgfQorICAgIHJldHVybiBCYXNlRW5jb2RpbmcuYmFzZTE2KCkubG93ZXJDYXNlKCkuZW5jb2RlKG1lc3NhZ2VEaWdlc3QuZGlnZXN0KGJ5dGVDb250ZW50KSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvbmVBbmRyb2lkU2hhcmVkRmlsZV9ibG9iU3RvcmVCYWNrZW5kTm90UmVnaXN0ZXJlZF9maWxlRG93bmxvYWRlZEFuZFN0b3JlZExvY2FsbHkoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmlsZVN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIC8qIGJhY2tlbmRzPSAqLyBJbW11dGFibGVMaXN0Lm9mKAorICAgICAgICAgICAgICAgIEFuZHJvaWRGaWxlQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLmJ1aWxkKCksIG5ldyBKYXZhRmlsZUJhY2tlbmQoKSksCisgICAgICAgICAgICAvKiB0cmFuc2Zvcm1zPSAqLyBJbW11dGFibGVMaXN0Lm9mKG5ldyBDb21wcmVzc1RyYW5zZm9ybSgpKSwKKyAgICAgICAgICAgIC8qIG1vbml0b3JzPSAqLyBJbW11dGFibGVMaXN0Lm9mKG1vY2tOZXR3b3JrVXNhZ2VNb25pdG9yLCBtb2NrRG93bmxvYWRQcm9ncmVzc01vbml0b3IpKTsKKworICAgIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyID0KKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIG5ldyBUZXN0RmlsZURvd25sb2FkZXIoCisgICAgICAgICAgICAgICAgVEVTVF9EQVRBX1JFTEFUSVZFX1BBVEgsCisgICAgICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAgICAgTW9yZUV4ZWN1dG9ycy5saXN0ZW5pbmdEZWNvcmF0b3IoRE9XTkxPQURfRVhFQ1VUT1IpKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0Q29udGV4dChjb250ZXh0KQorICAgICAgICAgICAgLnNldENvbnRyb2xFeGVjdXRvcihDT05UUk9MX0VYRUNVVE9SKQorICAgICAgICAgICAgLnNldEZpbGVEb3dubG9hZGVyU3VwcGxpZXIoZmlsZURvd25sb2FkZXJTdXBwbGllcikKKyAgICAgICAgICAgIC5zZXRUYXNrU2NoZWR1bGVyKE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSkKKyAgICAgICAgICAgIC5zZXREZWx0YURlY29kZXJPcHRpb25hbChPcHRpb25hbC5hYnNlbnQoKSkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RvcmFnZShmaWxlU3RvcmFnZSkKKyAgICAgICAgICAgIC5zZXROZXR3b3JrVXNhZ2VNb25pdG9yKG1vY2tOZXR3b3JrVXNhZ2VNb25pdG9yKQorICAgICAgICAgICAgLnNldERvd25sb2FkTW9uaXRvck9wdGlvbmFsKE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZFByb2dyZXNzTW9uaXRvcikpCisgICAgICAgICAgICAuc2V0TG9nZ2VyT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0xvZ2dlcikpCisgICAgICAgICAgICAuc2V0RmxhZ3NPcHRpb25hbChPcHRpb25hbC5vZihmbGFncykpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIFVyaSBhbmRyb2lkVXJpID0KKyAgICAgICAgQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEJsb2JQYXJhbWV0ZXJzKEZJTEVfQU5EUk9JRF9TSEFSSU5HX0NIRUNLU1VNXzEpLmJ1aWxkKCk7CisKKyAgICAvLyBBIGZpbGUgZ3JvdXAgd2l0aCBvbmUgYW5kcm9pZC1zaGFyZWQgZmlsZSBhbmQgb25lIG5vbi1hbmRyb2lkU2hhcmVkIGZpbGUKKyAgICBEYXRhRmlsZUdyb3VwIGdyb3VwV2l0aEZpbGVUb1NoYXJlID0KKyAgICAgICAgVGVzdEZpbGVHcm91cFBvcHVsYXRvci5jcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgICAgICAgRklMRV9HUk9VUF9UT19TSEFSRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzEsIEZJTEVfSUR9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMSwgRklMRV9TSVpFfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xLCBGSUxFX0NIRUNLU1VNfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9BTkRST0lEX1NIQVJJTkdfQ0hFQ0tTVU1fMSwgIiJ9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8xLCBGSUxFX1VSTH0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKTsKKworICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgICAgICAuYWRkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXREYXRhRmlsZUdyb3VwKGdyb3VwV2l0aEZpbGVUb1NoYXJlKS5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmlzVHJ1ZSgpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfVE9fU0hBUkVfMSkKKyAgICAgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbCgKKyAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwub2YoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRG93bmxvYWRMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uUHJvZ3Jlc3MobG9uZyBjdXJyZW50U2l6ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5pKFRBRywgIm9uUHJvZ3Jlc3MgIiArIGN1cnJlbnRTaXplKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkNvbXBsZXRlKENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuaShUQUcsICJvbkNvbXBsZXRlICIgKyBjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9KSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmdldChNQVhfRE9XTkxPQURfRklMRV9HUk9VUF9XQUlUX1RJTUVfU0VDUywgU0VDT05EUyk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKAorICAgICAgICAgICAgICAgIEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX1RPX1NIQVJFXzEpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cCkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX1RPX1NIQVJFXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMik7CisKKyAgICBDbGllbnRGaWxlIGNsaWVudEZpbGUgPSBjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVJZCgpKS5pc0VxdWFsVG8oRklMRV9JRF8xKTsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKGNsaWVudEZpbGUuZ2V0RmlsZVVyaSgpKTsKKyAgICBhc3NlcnRUaGF0KHVyaSkuaXNOb3RFcXVhbFRvKGFuZHJvaWRVcmkpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZmlsZVNpemUodXJpKSkuaXNFcXVhbFRvKEZJTEVfU0laRV8xKTsKKworICAgIGNsaWVudEZpbGUgPSBjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKS5nZXQoMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVJZCgpKS5pc0VxdWFsVG8oRklMRV9JRCk7CisgICAgdXJpID0gVXJpLnBhcnNlKGNsaWVudEZpbGUuZ2V0RmlsZVVyaSgpKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmZpbGVTaXplKHVyaSkpLmlzRXF1YWxUbyhGSUxFX1NJWkUpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb25lQW5kcm9pZFNoYXJlZEZpbGVfdHdvRmlsZUdyb3Vwc19kb3dubG9hZGVkT25seU9uY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgYW5kcm9pZFVyaSA9CisgICAgICAgIEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRCbG9iUGFyYW1ldGVycyhGSUxFX0FORFJPSURfU0hBUklOR19DSEVDS1NVTV8xKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKGFuZHJvaWRVcmkpKS5pc0ZhbHNlKCk7CisKKyAgICAvLyBncm91cFdpdGhGaWxlVG9TaGFyZTEgYW5kIGdyb3VwV2l0aEZpbGVUb1NoYXJlMiBjb250YWluIHRoZSBzYW1lIGZpbGUgY29uZmlndXJlZCB0byBiZQorICAgIC8vIHNoYXJlZC4KKyAgICBEYXRhRmlsZUdyb3VwIGdyb3VwV2l0aEZpbGVUb1NoYXJlMSA9CisgICAgICAgIFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfVE9fU0hBUkVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0FORFJPSURfU0hBUklOR19DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKTsKKworICAgIGxvbmcgb25lRGF5TGF0ZXJJblNlY29uZHMgPQorICAgICAgICBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMCArIDg2NDAwOyAvLyBpbiBvbmUgZGF5CisgICAgZ3JvdXBXaXRoRmlsZVRvU2hhcmUxID0KKyAgICAgICAgZ3JvdXBXaXRoRmlsZVRvU2hhcmUxLnRvQnVpbGRlcigpLnNldEV4cGlyYXRpb25EYXRlKG9uZURheUxhdGVySW5TZWNvbmRzKS5idWlsZCgpOworCisgICAgRGF0YUZpbGVHcm91cCBncm91cFdpdGhGaWxlVG9TaGFyZTIgPQorICAgICAgICBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICBGSUxFX0dST1VQX1RPX1NIQVJFXzIsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9BTkRST0lEX1NIQVJJTkdfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSyk7CisKKyAgICBsb25nIHR3b0RheXNMYXRlckluU2Vjb25kcyA9CisgICAgICAgIENhbGVuZGFyLmdldEluc3RhbmNlKCkuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwICsgMTcyODAwOyAvLyBpbiB0d28gZGF5cworICAgIGdyb3VwV2l0aEZpbGVUb1NoYXJlMiA9CisgICAgICAgIGdyb3VwV2l0aEZpbGVUb1NoYXJlMi50b0J1aWxkZXIoKS5zZXRFeHBpcmF0aW9uRGF0ZSh0d29EYXlzTGF0ZXJJblNlY29uZHMpLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREYXRhRmlsZUdyb3VwKGdyb3VwV2l0aEZpbGVUb1NoYXJlMSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmlzVHJ1ZSgpOworCisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RGF0YUZpbGVHcm91cChncm91cFdpdGhGaWxlVG9TaGFyZTIpCisgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX1RPX1NIQVJFXzEpCisgICAgICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoCisgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsLm9mKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERvd25sb2FkTGlzdGVuZXIoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblByb2dyZXNzKGxvbmcgY3VycmVudFNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuaShUQUcsICJvblByb2dyZXNzICIgKyBjdXJyZW50U2l6ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Db21wbGV0ZShDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmkoVEFHLCAib25Db21wbGV0ZSAiICsgY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoTUFYX0RPV05MT0FEX0ZJTEVfR1JPVVBfV0FJVF9USU1FX1NFQ1MsIFNFQ09ORFMpOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICBHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9UT19TSEFSRV8xKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXApLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9UT19TSEFSRV8xKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSURfMSk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZShjbGllbnRGaWxlLmdldEZpbGVVcmkoKSk7CisKKyAgICAvLyBUaGUgZmlsZSBpcyBub3cgYXZhaWxhYmxlIGluIHRoZSBhbmRyb2lkIHNoYXJlZCBzdG9yYWdlLgorICAgIGFzc2VydFRoYXQodXJpKS5pc0VxdWFsVG8oYW5kcm9pZFVyaSk7CisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHModXJpKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkpLmhhc1NpemUoMSk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKAorICAgICAgICAgICAgRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9UT19TSEFSRV8yKQorICAgICAgICAgICAgICAgIC5zZXRMaXN0ZW5lck9wdGlvbmFsKAorICAgICAgICAgICAgICAgICAgICBPcHRpb25hbC5vZigKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBEb3dubG9hZExpc3RlbmVyKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmkoVEFHLCAib25Qcm9ncmVzcyAiICsgY3VycmVudFNpemUpOworICAgICAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uQ29tcGxldGUoQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5pKFRBRywgIm9uQ29tcGxldGUgIiArIGNsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0pKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuZ2V0KE1BWF9ET1dOTE9BRF9GSUxFX0dST1VQX1dBSVRfVElNRV9TRUNTLCBTRUNPTkRTKTsKKworICAgIFN0cmluZyBkZWJ1Z1N0cmluZyA9IG1vYmlsZURhdGFEb3dubG9hZC5nZXREZWJ1Z0luZm9Bc1N0cmluZygpOworICAgIExvZy5pKFRBRywgIk1ERCBMaWIgZHVtcDoiKTsKKyAgICBmb3IgKFN0cmluZyBsaW5lIDogZGVidWdTdHJpbmcuc3BsaXQoIlxuIiwgLTEpKSB7CisgICAgICBMb2cuaShUQUcsIGxpbmUpOworICAgIH0KKworICAgIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICBHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9UT19TSEFSRV8yKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXApLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9UT19TSEFSRV8yKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworCisgICAgY2xpZW50RmlsZSA9IGNsaWVudEZpbGVHcm91cC5nZXRGaWxlTGlzdCgpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RmlsZUlkKCkpLmlzRXF1YWxUbyhGSUxFX0lEXzEpOworICAgIHVyaSA9IFVyaS5wYXJzZShjbGllbnRGaWxlLmdldEZpbGVVcmkoKSk7CisKKyAgICAvLyBUaGUgZmlsZSBpcyBzdGlsbCBhdmFpbGFibGUgaW4gdGhlIGFuZHJvaWQgc2hhcmVkIHN0b3JhZ2UuCisgICAgYXNzZXJ0VGhhdCh1cmkpLmlzRXF1YWxUbyhhbmRyb2lkVXJpKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyh1cmkpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKSkuaGFzU2l6ZSgxKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGZpbGVBdmFpbGFibGVJblNoYXJlZFN0b3JhZ2VfbmV2ZXJEb3dubG9hZGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIGNvbnRlbnQgPSAiZmlsZUF2YWlsYWJsZUluU2hhcmVkU3RvcmFnZV9uZXZlckRvd25sb2FkZWQiLmdldEJ5dGVzKCk7CisgICAgU3RyaW5nIGFuZHJvaWRDaGVja3N1bSA9IGNvbXB1dGVEaWdlc3QoY29udGVudCwgIlNIQS0yNTYiKTsKKyAgICBTdHJpbmcgY2hlY2tzdW0gPSBjb21wdXRlRGlnZXN0KGNvbnRlbnQsICJTSEEtMSIpOworICAgIFVyaSBhbmRyb2lkVXJpID0gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEJsb2JQYXJhbWV0ZXJzKGFuZHJvaWRDaGVja3N1bSkuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQoYmxvYlN0b3JlQmFja2VuZC5leGlzdHMoYW5kcm9pZFVyaSkpLmlzRmFsc2UoKTsKKworICAgIC8vIFdyaXRlIGZpbGUgaW4gdGhlIHNoYXJlZCBzdG9yYWdlCisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gYmxvYlN0b3JlQmFja2VuZC5vcGVuRm9yV3JpdGUoYW5kcm9pZFVyaSkpIHsKKyAgICAgIGFzc2VydFRoYXQob3V0KS5pc05vdE51bGwoKTsKKyAgICAgIG91dC53cml0ZShjb250ZW50KTsKKyAgICB9CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVCYWNrZW5kLmV4aXN0cyhhbmRyb2lkVXJpKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkpLmlzRW1wdHkoKTsKKworICAgIC8vIEEgZmlsZSBncm91cCB3aXRoIG9uZSBhbmRyb2lkLXNoYXJlZCBmaWxlIGFuZCBvbmUgbm9uLWFuZHJvaWRTaGFyZWQgZmlsZQorICAgIERhdGFGaWxlR3JvdXAgZ3JvdXBXaXRoRmlsZVRvU2hhcmUxID0KKyAgICAgICAgVGVzdEZpbGVHcm91cFBvcHVsYXRvci5jcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgICAgICAgRklMRV9HUk9VUF9UT19TSEFSRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzEsIEZJTEVfSUR9LAorICAgICAgICAgICAgbmV3IGludFtdIHtjb250ZW50Lmxlbmd0aCwgRklMRV9TSVpFfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7Y2hlY2tzdW0sIEZJTEVfQ0hFQ0tTVU19LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHthbmRyb2lkQ2hlY2tzdW0sICIifSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7Imh0dHBzOi8vcmFuZG9tLXVybCIsIEZJTEVfVVJMfSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05fQU5ZX05FVFdPUkspOworCisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RGF0YUZpbGVHcm91cChncm91cFdpdGhGaWxlVG9TaGFyZTEpCisgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX1RPX1NIQVJFXzEpCisgICAgICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoCisgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsLm9mKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERvd25sb2FkTGlzdGVuZXIoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblByb2dyZXNzKGxvbmcgY3VycmVudFNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuaShUQUcsICJvblByb2dyZXNzICIgKyBjdXJyZW50U2l6ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Db21wbGV0ZShDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmkoVEFHLCAib25Db21wbGV0ZSAiICsgY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoTUFYX0RPV05MT0FEX0ZJTEVfR1JPVVBfV0FJVF9USU1FX1NFQ1MsIFNFQ09ORFMpOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICBHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9UT19TSEFSRV8xKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXApLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9UT19TSEFSRV8xKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDIpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSURfMSk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZShjbGllbnRGaWxlLmdldEZpbGVVcmkoKSk7CisKKyAgICAvLyBUaGUgZmlsZSBpcyBhdmFpbGFibGUgaW4gdGhlIGFuZHJvaWQgc2hhcmVkIHN0b3JhZ2UuCisgICAgYXNzZXJ0VGhhdCh1cmkpLmlzRXF1YWxUbyhhbmRyb2lkVXJpKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhhbmRyb2lkVXJpKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkpLmhhc1NpemUoMSk7CisKKyAgICBjbGllbnRGaWxlID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSUQpOworICAgIHVyaSA9IFVyaS5wYXJzZShjbGllbnRGaWxlLmdldEZpbGVVcmkoKSk7CisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5maWxlU2l6ZSh1cmkpKS5pc0VxdWFsVG8oRklMRV9TSVpFKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGZpbGVEb3dubG9hZGVkRm9yRmlyc3RGaWxlR3JvdXBfdGhlblNoYXJlZEZvclNlY29uZEZpbGVHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSBhbmRyb2lkVXJpID0KKyAgICAgICAgQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEJsb2JQYXJhbWV0ZXJzKEZJTEVfQU5EUk9JRF9TSEFSSU5HX0NIRUNLU1VNXzIpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVCYWNrZW5kLmV4aXN0cyhhbmRyb2lkVXJpKSkuaXNGYWxzZSgpOworCisgICAgLy8gQ3JlYXRlIG5vbi1hbmRyb2lkLXNoYXJlZCBmaWxlIGdyb3VwLgorICAgIERhdGFGaWxlR3JvdXAgZ3JvdXBXaXRoRmlsZVRvU2hhcmUxID0KKyAgICAgICAgVGVzdEZpbGVHcm91cFBvcHVsYXRvci5jcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgICAgICAgRklMRV9HUk9VUF9UT19TSEFSRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzJ9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzJ9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSyk7CisKKyAgICBsb25nIGxhdGVyVGltZVNlY3MgPSBDYWxlbmRhci5nZXRJbnN0YW5jZSgpLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMCArIDg2NDAwOyAvLyBpbiBvbmUgZGF5CisgICAgZ3JvdXBXaXRoRmlsZVRvU2hhcmUxID0KKyAgICAgICAgZ3JvdXBXaXRoRmlsZVRvU2hhcmUxLnRvQnVpbGRlcigpLnNldEV4cGlyYXRpb25EYXRlKGxhdGVyVGltZVNlY3MpLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREYXRhRmlsZUdyb3VwKGdyb3VwV2l0aEZpbGVUb1NoYXJlMSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmlzVHJ1ZSgpOworCisgICAgLy8gZ3JvdXBXaXRoRmlsZVRvU2hhcmUyIGhhcyB0aGUgc2FtZSBmaWxlIGFzIHRoZSBwcmV2aW91cyBmaWxlIGdyb3VwIGJ1dCBpdCBoYXMgYmVlbiBjb25maWd1cmVkCisgICAgLy8gdG8gYmUgc2hhcmUuCisgICAgRGF0YUZpbGVHcm91cCBncm91cFdpdGhGaWxlVG9TaGFyZTIgPQorICAgICAgICBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICBGSUxFX0dST1VQX1RPX1NIQVJFXzIsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMn0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8yfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8yfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9BTkRST0lEX1NIQVJJTkdfQ0hFQ0tTVU1fMn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzJ9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSyk7CisKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREYXRhRmlsZUdyb3VwKGdyb3VwV2l0aEZpbGVUb1NoYXJlMikKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmlzVHJ1ZSgpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfVE9fU0hBUkVfMSkKKyAgICAgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbCgKKyAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwub2YoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRG93bmxvYWRMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uUHJvZ3Jlc3MobG9uZyBjdXJyZW50U2l6ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5pKFRBRywgIm9uUHJvZ3Jlc3MgIiArIGN1cnJlbnRTaXplKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkNvbXBsZXRlKENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuaShUQUcsICJvbkNvbXBsZXRlICIgKyBjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9KSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmdldChNQVhfRE9XTkxPQURfRklMRV9HUk9VUF9XQUlUX1RJTUVfU0VDUywgU0VDT05EUyk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKAorICAgICAgICAgICAgICAgIEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX1RPX1NIQVJFXzEpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cCkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX1RPX1NIQVJFXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisKKyAgICBDbGllbnRGaWxlIGNsaWVudEZpbGUgPSBjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVJZCgpKS5pc0VxdWFsVG8oRklMRV9JRF8yKTsKKworICAgIC8vIEZpbGUgc3RvcmVkIGxvY2FsbHkKKyAgICBVcmkgbG9jYWxVcmkgPSBVcmkucGFyc2UoY2xpZW50RmlsZS5nZXRGaWxlVXJpKCkpOworICAgIGFzc2VydFRoYXQobG9jYWxVcmkpLmlzTm90RXF1YWxUbyhhbmRyb2lkVXJpKTsKKyAgICBhc3NlcnRUaGF0KGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKSkuaXNFbXB0eSgpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfVE9fU0hBUkVfMikKKyAgICAgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbCgKKyAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwub2YoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRG93bmxvYWRMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uUHJvZ3Jlc3MobG9uZyBjdXJyZW50U2l6ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5pKFRBRywgIm9uUHJvZ3Jlc3MgIiArIGN1cnJlbnRTaXplKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkNvbXBsZXRlKENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuaShUQUcsICJvbkNvbXBsZXRlICIgKyBjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9KSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmdldChNQVhfRE9XTkxPQURfRklMRV9HUk9VUF9XQUlUX1RJTUVfU0VDUywgU0VDT05EUyk7CisKKyAgICBTdHJpbmcgZGVidWdTdHJpbmcgPSBtb2JpbGVEYXRhRG93bmxvYWQuZ2V0RGVidWdJbmZvQXNTdHJpbmcoKTsKKyAgICBMb2cuaShUQUcsICJNREQgTGliIGR1bXA6Iik7CisgICAgZm9yIChTdHJpbmcgbGluZSA6IGRlYnVnU3RyaW5nLnNwbGl0KCJcbiIsIC0xKSkgeworICAgICAgTG9nLmkoVEFHLCBsaW5lKTsKKyAgICB9CisKKyAgICBjbGllbnRGaWxlR3JvdXAgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgIC5nZXRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgR2V0RmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfVE9fU0hBUkVfMikuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwKS5pc05vdE51bGwoKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfVE9fU0hBUkVfMik7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygxKTsKKworICAgIGNsaWVudEZpbGUgPSBjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVJZCgpKS5pc0VxdWFsVG8oRklMRV9JRF8yKTsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKGNsaWVudEZpbGUuZ2V0RmlsZVVyaSgpKTsKKworICAgIC8vIFRoZSBmaWxlIGlzIG5vdyBhdmFpbGFibGUgaW4gdGhlIHNoYXJlZCBzdG9yYWdlLgorICAgIGFzc2VydFRoYXQodXJpKS5pc05vdEVxdWFsVG8obG9jYWxVcmkpOworICAgIGFzc2VydFRoYXQodXJpKS5pc0VxdWFsVG8oYW5kcm9pZFVyaSk7CisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHModXJpKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkpLmhhc1NpemUoMSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Eb3dubG9hZEZpbGVHcm91cEludGVncmF0aW9uVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkRmlsZUdyb3VwSW50ZWdyYXRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzViMzIzOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Eb3dubG9hZEZpbGVHcm91cEludGVncmF0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDExIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UZXN0RmlsZUdyb3VwUG9wdWxhdG9yLkZJTEVfQ0hFQ0tTVU07CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuRklMRV9HUk9VUF9OQU1FOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UZXN0RmlsZUdyb3VwUG9wdWxhdG9yLkZJTEVfSUQ7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuRklMRV9TSVpFOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UZXN0RmlsZUdyb3VwUG9wdWxhdG9yLkZJTEVfVVJMOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudXRpbC5Mb2c7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuZXh0Lmp1bml0LnJ1bm5lcnMuQW5kcm9pZEpVbml0NDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZC5kYWdnZXIuZG93bmxvYWRlcjIuQmFzZUZpbGVEb3dubG9hZGVyTW9kdWxlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmludGVncmF0aW9uLmRvd25sb2FkZXIuU2hhcmVkUHJlZmVyZW5jZXNEb3dubG9hZE1ldGFkYXRhOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5Db21wcmVzc1RyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuTmV0d29ya1VzYWdlTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLkJsb2NraW5nRmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5UZXN0RmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlQ2FsbGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5DbGllbnRDb25maWdQcm90by5DbGllbnRGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkNsaWVudENvbmZpZ1Byb3RvLkNsaWVudEZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlR3JvdXA7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5Eb3dubG9hZENvbmRpdGlvbnMuRGV2aWNlTmV0d29ya1BvbGljeTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Nb2NrOworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9KVW5pdDsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvUnVsZTsKKworQFJ1bldpdGgoQW5kcm9pZEpVbml0NC5jbGFzcykKK3B1YmxpYyBjbGFzcyBEb3dubG9hZEZpbGVHcm91cEludGVncmF0aW9uVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJEb3dubG9hZEZpbGVHcm91cEludGVncmF0aW9uVGVzdCI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfRE9XTkxPQURfRklMRV9HUk9VUF9XQUlUX1RJTUVfU0VDUyA9IDMwMDsKKworICAvLyBOb3RlOiBDb250cm9sIEV4ZWN1dG9yIG11c3Qgbm90IGJlIGEgc2luZ2xlIHRocmVhZCBleGVjdXRvci4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlIENPTlRST0xfRVhFQ1VUT1IgPQorICAgICAgTW9yZUV4ZWN1dG9ycy5saXN0ZW5pbmdEZWNvcmF0b3IoRXhlY3V0b3JzLm5ld0NhY2hlZFRocmVhZFBvb2woKSk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSBET1dOTE9BRF9FWEVDVVRPUiA9CisgICAgICBFeGVjdXRvcnMubmV3U2NoZWR1bGVkVGhyZWFkUG9vbCgyKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlIGxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSA9CisgICAgICBNb3JlRXhlY3V0b3JzLmxpc3RlbmluZ0RlY29yYXRvcihET1dOTE9BRF9FWEVDVVRPUik7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfR1JPVVBfTkFNRV9JTlNFQ1VSRV9VUkwgPSAidGVzdC1ncm91cC1pbnNlY3VyZS11cmwiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9HUk9VUF9OQU1FX01VTFRJUExFX0ZJTEVTID0gInRlc3QtZ3JvdXAtbXVsdGlwbGUtZmlsZXMiOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0lEXzEgPSAidGVzdC1maWxlLTEiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9JRF8yID0gInRlc3QtZmlsZS0yIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfQ0hFQ0tTVU1fMSA9ICJhMWNiYTlkODdiMTQ0MGY0MWNlOWU3ZGEzOGM0M2UxZjZiZDdkNWRmIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfQ0hFQ0tTVU1fMiA9ICJjYjI0NTlkOWYxYjUwODk5M2FiYTM2YTVmZmQ5NDJhN2UwZDQ5ZWQ2IjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfTk9UX0VYSVNUX1VSTCA9CisgICAgICAiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vaWNpbmcvaWRkL25vdGV4aXN0L2ZpbGUudHh0IjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb250ZXh0IGNvbnRleHQgPSBBcHBsaWNhdGlvblByb3ZpZGVyLmdldEFwcGxpY2F0aW9uQ29udGV4dCgpOworCisgIEBNb2NrIHByaXZhdGUgVGFza1NjaGVkdWxlciBtb2NrVGFza1NjaGVkdWxlcjsKKyAgQE1vY2sgcHJpdmF0ZSBOZXR3b3JrVXNhZ2VNb25pdG9yIG1vY2tOZXR3b3JrVXNhZ2VNb25pdG9yOworICBATW9jayBwcml2YXRlIERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIG1vY2tEb3dubG9hZFByb2dyZXNzTW9uaXRvcjsKKworICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2U7CisKKyAgcHJpdmF0ZSBmaW5hbCBUZXN0RmxhZ3MgZmxhZ3MgPSBuZXcgVGVzdEZsYWdzKCk7CisKKyAgQFJ1bGUgcHVibGljIGZpbmFsIE1vY2tpdG9SdWxlIG1vY2tzID0gTW9ja2l0b0pVbml0LnJ1bGUoKTsKKworICAvKiBEaWZmZXJlbnRpYXRlcyBiZXR3ZWVuIERvd25sb2FkZXIgbGlicmFyaWVzIGZvciBzaGFyZWQgdGVzdCBtZXRob2QgYXNzZXJ0aW9ucy4gKi8KKyAgcHJpdmF0ZSBlbnVtIERvd25sb2FkZXJWZXJzaW9uIHsKKyAgICBWMgorICB9CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworCisgICAgZmlsZVN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIC8qIGJhY2tlbmRzPSAqLyBJbW11dGFibGVMaXN0Lm9mKEFuZHJvaWRGaWxlQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLmJ1aWxkKCkpLAorICAgICAgICAgICAgLyogdHJhbnNmb3Jtcz0gKi8gSW1tdXRhYmxlTGlzdC5vZihuZXcgQ29tcHJlc3NUcmFuc2Zvcm0oKSksCisgICAgICAgICAgICAvKiBtb25pdG9ycz0gKi8gSW1tdXRhYmxlTGlzdC5vZihtb2NrTmV0d29ya1VzYWdlTW9uaXRvciwgbW9ja0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZEFuZFJlYWRfZG93bmxvYWRlcjIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllciA9CisgICAgICAgICgpIC0+CisgICAgICAgICAgICBCYXNlRmlsZURvd25sb2FkZXJNb2R1bGUuY3JlYXRlT2Zmcm9hZDJGaWxlRG93bmxvYWRlcigKKyAgICAgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgICAgIERPV05MT0FEX0VYRUNVVE9SLAorICAgICAgICAgICAgICAgIENPTlRST0xfRVhFQ1VUT1IsCisgICAgICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAgICAgbmV3IFNoYXJlZFByZWZlcmVuY2VzRG93bmxvYWRNZXRhZGF0YSgKKyAgICAgICAgICAgICAgICAgICAgY29udGV4dC5nZXRTaGFyZWRQcmVmZXJlbmNlcygiZG93bmxvYWRtZXRhZGF0YSIsIDApLCBsaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2UpLAorICAgICAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZFByb2dyZXNzTW9uaXRvciksCisgICAgICAgICAgICAgICAgLyogdXJsRW5naW5lT3B0aW9uYWw9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgICAgIC8qIGV4Y2VwdGlvbkhhbmRsZXJPcHRpb25hbD0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgLyogYXV0aFRva2VuUHJvdmlkZXJPcHRpb25hbD0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgLyogdHJhZmZpY1RhZz0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgZmxhZ3MpOworCisgICAgdGVzdERvd25sb2FkQW5kUmVhZChmaWxlRG93bmxvYWRlclN1cHBsaWVyLCBEb3dubG9hZGVyVmVyc2lvbi5WMik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZEZhaWxlZF9kb3dubG9hZGVyMigpIHRocm93cyBFeGNlcHRpb24geworICAgIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyID0KKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIEJhc2VGaWxlRG93bmxvYWRlck1vZHVsZS5jcmVhdGVPZmZyb2FkMkZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICAgICAgRE9XTkxPQURfRVhFQ1VUT1IsCisgICAgICAgICAgICAgICAgQ09OVFJPTF9FWEVDVVRPUiwKKyAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgICAgICBuZXcgU2hhcmVkUHJlZmVyZW5jZXNEb3dubG9hZE1ldGFkYXRhKAorICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmdldFNoYXJlZFByZWZlcmVuY2VzKCJkb3dubG9hZG1ldGFkYXRhIiwgMCksIGxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSksCisgICAgICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKSwKKyAgICAgICAgICAgICAgICAvKiB1cmxFbmdpbmVPcHRpb25hbD0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgLyogZXhjZXB0aW9uSGFuZGxlck9wdGlvbmFsPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgICAvKiBhdXRoVG9rZW5Qcm92aWRlck9wdGlvbmFsPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgICAvKiB0cmFmZmljVGFnPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgICBmbGFncyk7CisKKyAgICB0ZXN0RG93bmxvYWRGYWlsZWQoZmlsZURvd25sb2FkZXJTdXBwbGllciwgRG93bmxvYWRlclZlcnNpb24uVjIpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHRlc3REb3dubG9hZEZhaWxlZCgKKyAgICAgIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyLCBEb3dubG9hZGVyVmVyc2lvbiB2ZXJzaW9uKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlci5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRDb250ZXh0KGNvbnRleHQpCisgICAgICAgICAgICAuc2V0Q29udHJvbEV4ZWN1dG9yKENPTlRST0xfRVhFQ1VUT1IpCisgICAgICAgICAgICAuc2V0RmlsZURvd25sb2FkZXJTdXBwbGllcihmaWxlRG93bmxvYWRlclN1cHBsaWVyKQorICAgICAgICAgICAgLnNldFRhc2tTY2hlZHVsZXIoT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpKQorICAgICAgICAgICAgLnNldERlbHRhRGVjb2Rlck9wdGlvbmFsKE9wdGlvbmFsLmFic2VudCgpKQorICAgICAgICAgICAgLnNldEZpbGVTdG9yYWdlKGZpbGVTdG9yYWdlKQorICAgICAgICAgICAgLnNldE5ldHdvcmtVc2FnZU1vbml0b3IobW9ja05ldHdvcmtVc2FnZU1vbml0b3IpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRNb25pdG9yT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKSkKKyAgICAgICAgICAgIC5zZXRGbGFnc09wdGlvbmFsKE9wdGlvbmFsLm9mKGZsYWdzKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gVGhlIGRhdGEgZmlsZSBncm91cCBoYXMgYSBmaWxlIHdpdGggaW5zZWN1cmUgdXJsLgorICAgIERhdGFGaWxlR3JvdXAgZ3JvdXBXaXRoSW5zZWN1cmVVcmwgPQorICAgICAgICBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfSU5TRUNVUkVfVVJMLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEfSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTX0sCisgICAgICAgICAgICAvLyBNYWtlIHRoZSB1cmwgaW5zZWN1cmUuIFRoaXMgd291bGQgbGVhZCB0byBkb3dubG9hZCBmYWlsdXJlLgorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTC5yZXBsYWNlKCJodHRwcyIsICJodHRwIil9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSyk7CisKKyAgICAvLyBUaGUgZGF0YSBmaWxlIGdyb3VwIGhhcyBhIGZpbGUgd2l0aCBub24tZXhpc3RlbnQgdXJsLCBhbmQgYSBmaWxlIHdpdGggaW5zZWN1cmUgdXJsLgorICAgIERhdGFGaWxlR3JvdXAgZ3JvdXBXaXRoTXVsdGlwbGVGaWxlcyA9CisgICAgICAgIFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV9NVUxUSVBMRV9GSUxFUywKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xLCBGSUxFX0lEXzJ9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkUsIEZJTEVfU0laRX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMSwgRklMRV9DSEVDS1NVTV8yfSwKKyAgICAgICAgICAgIC8vIFRoZSBmaXJzdCBmaWxlIHVybCBkb2Vzbid0IGV4aXN0IGFuZCB0aGUgc2Vjb25kIGZpbGUgdXJsIGlzIGluc2VjdXJlLgorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX05PVF9FWElTVF9VUkwsIEZJTEVfVVJMLnJlcGxhY2UoImh0dHBzIiwgImh0dHAiKX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKTsKKworICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgICAgICAuYWRkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXREYXRhRmlsZUdyb3VwKGdyb3VwV2l0aEluc2VjdXJlVXJsKS5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmlzVHJ1ZSgpOworCisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RGF0YUZpbGVHcm91cChncm91cFdpdGhNdWx0aXBsZUZpbGVzKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXhjZXB0aW9uID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgKCkgLT4KKyAgICAgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgICAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FX0lOU0VDVVJFX1VSTCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAgICAgLmdldChNQVhfRE9XTkxPQURfRklMRV9HUk9VUF9XQUlUX1RJTUVfU0VDUywgVGltZVVuaXQuU0VDT05EUykpOworICAgIGFzc2VydFRoYXQoZXhjZXB0aW9uKS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoQWdncmVnYXRlRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBBZ2dyZWdhdGVFeGNlcHRpb24gY2F1c2UgPSAoQWdncmVnYXRlRXhjZXB0aW9uKSBleGNlcHRpb24uZ2V0Q2F1c2UoKTsKKyAgICBhc3NlcnRUaGF0KGNhdXNlKS5pc05vdE51bGwoKTsKKyAgICBJbW11dGFibGVMaXN0PFRocm93YWJsZT4gZmFpbHVyZXMgPSBjYXVzZS5nZXRGYWlsdXJlcygpOworICAgIGFzc2VydFRoYXQoZmFpbHVyZXMpLmhhc1NpemUoMSk7CisgICAgYXNzZXJ0VGhhdChmYWlsdXJlcy5nZXQoMCkpLmlzSW5zdGFuY2VPZihEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgYXNzZXJ0VGhhdChmYWlsdXJlcy5nZXQoMCkpLmhhc01lc3NhZ2VUaGF0KCkuY29udGFpbnMoIklOU0VDVVJFX1VSTF9FUlJPUiIpOworCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4Y2VwdGlvbjIgPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgICAgICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfTVVMVElQTEVfRklMRVMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoTUFYX0RPV05MT0FEX0ZJTEVfR1JPVVBfV0FJVF9USU1FX1NFQ1MsIFRpbWVVbml0LlNFQ09ORFMpKTsKKyAgICBhc3NlcnRUaGF0KGV4Y2VwdGlvbjIpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihBZ2dyZWdhdGVFeGNlcHRpb24uY2xhc3MpOworICAgIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiBjYXVzZTIgPSAoQWdncmVnYXRlRXhjZXB0aW9uKSBleGNlcHRpb24yLmdldENhdXNlKCk7CisgICAgYXNzZXJ0VGhhdChjYXVzZTIpLmlzTm90TnVsbCgpOworICAgIEltbXV0YWJsZUxpc3Q8VGhyb3dhYmxlPiBmYWlsdXJlczIgPSBjYXVzZTIuZ2V0RmFpbHVyZXMoKTsKKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzMikuaGFzU2l6ZSgyKTsKKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzMi5nZXQoMCkpLmlzSW5zdGFuY2VPZihEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgc3dpdGNoICh2ZXJzaW9uKSB7CisgICAgICBjYXNlIFYyOgorICAgICAgICBhc3NlcnRUaGF0KGZhaWx1cmVzMi5nZXQoMCkpCisgICAgICAgICAgICAuaGFzQ2F1c2VUaGF0KCkKKyAgICAgICAgICAgIC5oYXNNZXNzYWdlVGhhdCgpCisgICAgICAgICAgICAuY29udGFpbnNNYXRjaCgiaHR0cFN0YXR1c0NvZGU9NDA0Iik7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzMi5nZXQoMSkpLmlzSW5zdGFuY2VPZihEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgYXNzZXJ0VGhhdChmYWlsdXJlczIuZ2V0KDEpKS5oYXNNZXNzYWdlVGhhdCgpLmNvbnRhaW5zKCJJTlNFQ1VSRV9VUkxfRVJST1IiKTsKKworICAgIHN3aXRjaCAodmVyc2lvbikgeworICAgICAgY2FzZSBWMjoKKyAgICAgICAgLy8gTm8tb3AKKyAgICB9CisgIH0KKworICBwcml2YXRlIHZvaWQgdGVzdERvd25sb2FkQW5kUmVhZCgKKyAgICAgIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyLCBEb3dubG9hZGVyVmVyc2lvbiB2ZXJzaW9uKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yIHRlc3RGaWxlR3JvdXBQb3B1bGF0b3IgPSBuZXcgVGVzdEZpbGVHcm91cFBvcHVsYXRvcihjb250ZXh0KTsKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlci5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRDb250ZXh0KGNvbnRleHQpCisgICAgICAgICAgICAuc2V0Q29udHJvbEV4ZWN1dG9yKENPTlRST0xfRVhFQ1VUT1IpCisgICAgICAgICAgICAuc2V0RmlsZURvd25sb2FkZXJTdXBwbGllcihmaWxlRG93bmxvYWRlclN1cHBsaWVyKQorICAgICAgICAgICAgLmFkZEZpbGVHcm91cFBvcHVsYXRvcih0ZXN0RmlsZUdyb3VwUG9wdWxhdG9yKQorICAgICAgICAgICAgLnNldFRhc2tTY2hlZHVsZXIoT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpKQorICAgICAgICAgICAgLnNldERlbHRhRGVjb2Rlck9wdGlvbmFsKE9wdGlvbmFsLmFic2VudCgpKQorICAgICAgICAgICAgLnNldEZpbGVTdG9yYWdlKGZpbGVTdG9yYWdlKQorICAgICAgICAgICAgLnNldE5ldHdvcmtVc2FnZU1vbml0b3IobW9ja05ldHdvcmtVc2FnZU1vbml0b3IpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRNb25pdG9yT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKSkKKyAgICAgICAgICAgIC5zZXRGbGFnc09wdGlvbmFsKE9wdGlvbmFsLm9mKGZsYWdzKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgdGVzdEZpbGVHcm91cFBvcHVsYXRvci5yZWZyZXNoRmlsZUdyb3Vwcyhtb2JpbGVEYXRhRG93bmxvYWQpLmdldCgpOworICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoCisgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsLm9mKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERvd25sb2FkTGlzdGVuZXIoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblByb2dyZXNzKGxvbmcgY3VycmVudFNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuaShUQUcsICJvblByb2dyZXNzICIgKyBjdXJyZW50U2l6ZSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Db21wbGV0ZShDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmkoVEFHLCAib25Db21wbGV0ZSAiICsgY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgfSkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoTUFYX0RPV05MT0FEX0ZJTEVfR1JPVVBfV0FJVF9USU1FX1NFQ1MsIFRpbWVVbml0LlNFQ09ORFMpOworCisgICAgU3RyaW5nIGRlYnVnU3RyaW5nID0gbW9iaWxlRGF0YURvd25sb2FkLmdldERlYnVnSW5mb0FzU3RyaW5nKCk7CisgICAgTG9nLmkoVEFHLCAiTUREIExpYiBkdW1wOiIpOworICAgIGZvciAoU3RyaW5nIGxpbmUgOiBkZWJ1Z1N0cmluZy5zcGxpdCgiXG4iLCAtMSkpIHsKKyAgICAgIExvZy5pKFRBRywgbGluZSk7CisgICAgfQorCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cChHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXApLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSUQpOworICAgIFVyaSBhbmRyb2lkVXJpID0gVXJpLnBhcnNlKGNsaWVudEZpbGUuZ2V0RmlsZVVyaSgpKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmZpbGVTaXplKGFuZHJvaWRVcmkpKS5pc0VxdWFsVG8oRklMRV9TSVpFKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZC5jbGVhcigpLmdldCgpOworCisgICAgc3dpdGNoICh2ZXJzaW9uKSB7CisgICAgICBjYXNlIFYyOgorICAgICAgICAvLyBOby1vcAorICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNhbmNlbERvd25sb2FkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gSW4gdGhpcyB0ZXN0IHdlIHdpbGwgc3RhcnQgYSBkb3dubG9hZCBhbmQgbWFrZSBzdXJlIHRoYXQgY2FsbGluZyBjYW5jZWwgb24gdGhlIHJldHVybmVkCisgICAgLy8gZnV0dXJlIHdpbGwgY2FuY2VsIHRoZSBkb3dubG9hZC4KKyAgICAvLyBXZSBjcmVhdGUgYSBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIHRoYXQgYWxsb3dzIHRoZSBkb3dubG9hZCB0byBiZSBibG9ja2VkIGluZGVmaW5pdGVseS4KKyAgICAvLyBXZSBhbHNvIHByb3ZpZGUgYSBkZWxlZ2F0ZSBGaWxlRG93bmxvYWRlciB0aGF0IGF0dGFjaGVzIGEgRnV0dXJlQ2FsbGJhY2sgdG8gdGhlIGludGVybmFsCisgICAgLy8gZG93bmxvYWQgZnV0dXJlIGFuZCBmYWlsIGlmIHRoZSBmdXR1cmUgaXMgbm90IGNhbmNlbGxlZC4KKyAgICBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIGJsb2NraW5nRmlsZURvd25sb2FkZXIgPQorICAgICAgICBuZXcgQmxvY2tpbmdGaWxlRG93bmxvYWRlcigKKyAgICAgICAgICAgIGxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSwKKyAgICAgICAgICAgIG5ldyBGaWxlRG93bmxvYWRlcigpIHsKKyAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHN0YXJ0RG93bmxvYWRpbmcoRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCkgeworICAgICAgICAgICAgICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRUYXNrRnV0dXJlID0gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgRnV0dXJlcy5hZGRDYWxsYmFjaygKKyAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRUYXNrRnV0dXJlLAorICAgICAgICAgICAgICAgICAgICBuZXcgRnV0dXJlQ2FsbGJhY2s8Vm9pZD4oKSB7CisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25TdWNjZXNzKFZvaWQgcmVzdWx0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvLyBTaG91bGQgbm90IGdldCBoZXJlIHNpbmNlIHdlIHdpbGwgY2FuY2VsIHRoZSBmdXR1cmUuCisgICAgICAgICAgICAgICAgICAgICAgICBmYWlsKCk7CisgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGRvd25sb2FkVGFza0Z1dHVyZS5pc0NhbmNlbGxlZCgpKS5pc1RydWUoKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmkoVEFHLCAiZG93bmxvYWRUYXNrIGlzIGNhbmNlbGxlZCEiKTsKKyAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgIGxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIGRvd25sb2FkVGFza0Z1dHVyZTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSk7CisgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IG5ldmVyRmluaXNoRG93bmxvYWRlciA9ICgpIC0+IGJsb2NraW5nRmlsZURvd25sb2FkZXI7CisKKyAgICAvLyBVc2UgbmV2ZXIgZmluaXNoIGRvd25sb2FkZXIgdG8gdGVzdCB3aGV0aGVyIHRoZSBjYW5jZWxsYXRpb24gb24gdGhlIGRvd25sb2FkRnV0dXJlIHdvdWxkCisgICAgLy8gY2FuY2VsIGFsbCB0aGUgcGFyZW50IGZ1dHVyZXMuCisgICAgVGVzdEZpbGVHcm91cFBvcHVsYXRvciB0ZXN0RmlsZUdyb3VwUG9wdWxhdG9yID0gbmV3IFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IoY29udGV4dCk7CisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0Q29udGV4dChjb250ZXh0KQorICAgICAgICAgICAgLnNldENvbnRyb2xFeGVjdXRvcihDT05UUk9MX0VYRUNVVE9SKQorICAgICAgICAgICAgLnNldEZpbGVEb3dubG9hZGVyU3VwcGxpZXIobmV2ZXJGaW5pc2hEb3dubG9hZGVyKQorICAgICAgICAgICAgLmFkZEZpbGVHcm91cFBvcHVsYXRvcih0ZXN0RmlsZUdyb3VwUG9wdWxhdG9yKQorICAgICAgICAgICAgLnNldFRhc2tTY2hlZHVsZXIoT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpKQorICAgICAgICAgICAgLnNldERlbHRhRGVjb2Rlck9wdGlvbmFsKE9wdGlvbmFsLmFic2VudCgpKQorICAgICAgICAgICAgLnNldEZpbGVTdG9yYWdlKGZpbGVTdG9yYWdlKQorICAgICAgICAgICAgLnNldE5ldHdvcmtVc2FnZU1vbml0b3IobW9ja05ldHdvcmtVc2FnZU1vbml0b3IpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRNb25pdG9yT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKSkKKyAgICAgICAgICAgIC5zZXRGbGFnc09wdGlvbmFsKE9wdGlvbmFsLm9mKGZsYWdzKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgdGVzdEZpbGVHcm91cFBvcHVsYXRvci5yZWZyZXNoRmlsZUdyb3Vwcyhtb2JpbGVEYXRhRG93bmxvYWQpLmdldCgpOworCisgICAgLy8gTm93IHN0YXJ0IHRvIGRvd25sb2FkIHRoZSBmaWxlIGdyb3VwLgorICAgIExpc3RlbmFibGVGdXR1cmU8Q2xpZW50RmlsZUdyb3VwPiBkb3dubG9hZEZpbGVHcm91cEZ1dHVyZSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkuYnVpbGQoKSk7CisKKyAgICAvLyBOb3RlOiB3ZSBjb3VsZCBoYXZlIGEgcmFjZSBjb25kaXRpb24gaGVyZSBiZXR3ZWVuIHdoZW4gd2UgY2FsbCB0aGUKKyAgICAvLyBkb3dubG9hZEZpbGVHcm91cEZ1dHVyZS5jYW5jZWwgYW5kIHdoZW4gdGhlIEZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcgaXMgZXhlY3V0ZWQuCisgICAgLy8gVGhlIGZvbGxvd2luZyBjYWxsIHdpbGwgZW5zdXJlIHRoYXQgd2Ugd2lsbCBvbmx5IGNhbGwgY2FuY2VsIG9uIHRoZSBkb3dubG9hZEZpbGVHcm91cEZ1dHVyZQorICAgIC8vIHdoZW4gdGhlIGFjdHVhbCBkb3dubG9hZCBoYXMgaGFwcGVuZWQgKHRoZSBkb3dubG9hZFRhc2tGdXR1cmUpLgorICAgIC8vIFRoaXMgd2lsbCBibG9jayB1bnRpbCB0aGUgZG93bmxvYWRUYXNrRnV0dXJlIHN0YXJ0cy4KKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLndhaXRGb3JEb3dubG9hZFN0YXJ0ZWQoKTsKKworICAgIC8vIENhbmNlbCB0aGUgZG93bmxvYWRGaWxlR3JvdXBGdXR1cmUsIGl0IHNob3VsZCBjYXNjYWRlIGNhbmNlbGxhdGlvbiB0byBkb3dubG9hZFRhc2tGdXR1cmUuCisgICAgZG93bmxvYWRGaWxlR3JvdXBGdXR1cmUuY2FuY2VsKHRydWUgLyptYXkgaW50ZXJydXB0Ki8pOworCisgICAgLy8gQWxsb3cgdGhlIGRvd25sb2FkIHRvIGNvbnRpbnVlIGFuZCB0cmlnZ2VyIG91ciBkZWxlZ2F0ZSBGaWxlRG93bmxvYWRlci4gSWYgdGhlIGZ1dHVyZSBpc24ndAorICAgIC8vIGNhbmNlbGxlZCwgdGhlIG9uU3VjY2VzcyBjYWxsYmFjayBzaG91bGQgZmFpbCB0aGUgdGVzdC4KKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLmZpbmlzaERvd25sb2FkaW5nKCk7CisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci53YWl0Rm9yRG93bmxvYWRDb21wbGV0ZWQoKTsKKworICAgIGFzc2VydFRoYXQoZG93bmxvYWRGaWxlR3JvdXBGdXR1cmUuaXNDYW5jZWxsZWQoKSkuaXNUcnVlKCk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuY2xlYXIoKS5nZXQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkRmlsZUludGVncmF0aW9uVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkRmlsZUludGVncmF0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUxYjM3YTAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvRG93bmxvYWRGaWxlSW50ZWdyYXRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwyMjAgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uLkRvd25sb2FkUmVzdWx0Q29kZS5BTkRST0lEX0RPV05MT0FERVJfSFRUUF9FUlJPUjsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuYW55OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnZlcmlmeTsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5leHQuanVuaXQucnVubmVycy5BbmRyb2lkSlVuaXQ0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRDb25zdHJhaW50czsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZC5kYWdnZXIuZG93bmxvYWRlcjIuQmFzZUZpbGVEb3dubG9hZGVyTW9kdWxlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5pbnRlZ3JhdGlvbi5kb3dubG9hZGVyLlNoYXJlZFByZWZlcmVuY2VzRG93bmxvYWRNZXRhZGF0YTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuTmV0d29ya1VzYWdlTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLkJsb2NraW5nRmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5GYWtlVGltZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLlRlc3RGbGFnczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuU3VwcGxpZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FuY2VsbGF0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworCitAUnVuV2l0aChBbmRyb2lkSlVuaXQ0LmNsYXNzKQorcHVibGljIGNsYXNzIERvd25sb2FkRmlsZUludGVncmF0aW9uVGVzdCB7CisKKyAgQFJ1bGUgcHVibGljIGZpbmFsIE1vY2tpdG9SdWxlIG1vY2tzID0gTW9ja2l0b0pVbml0LnJ1bGUoKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIkRvd25sb2FkRmlsZUludGVncmF0aW9uVGVzdCI7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEZJTEVfU0laRSA9IDU1NDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfVVJMID0gImh0dHBzOi8vd3d3LmdzdGF0aWMuY29tL3N1Z2dlc3QtZGV2L29kd3MxX2VtcHR5LmphciI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBET0VTX05PVF9FWElTVF9GSUxFX1VSTCA9CisgICAgICAiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vbm9uLWV4aXN0aW5nL3N1Z2dlc3QtZGV2L25vdC1leGlzdC50eHQiOworCisgIC8vIE5vdGU6IENvbnRyb2wgRXhlY3V0b3IgbXVzdCBub3QgYmUgYSBzaW5nbGUgdGhyZWFkIGV4ZWN1dG9yLgorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2UgQ09OVFJPTF9FWEVDVVRPUiA9CisgICAgICBNb3JlRXhlY3V0b3JzLmxpc3RlbmluZ0RlY29yYXRvcihFeGVjdXRvcnMubmV3Q2FjaGVkVGhyZWFkUG9vbCgpKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIERPV05MT0FEX0VYRUNVVE9SID0KKyAgICAgIEV4ZWN1dG9ycy5uZXdTY2hlZHVsZWRUaHJlYWRQb29sKDIpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbnRleHQgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisKKyAgcHJpdmF0ZSBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkOworCisgIHByaXZhdGUgZmluYWwgVXJpIGRlc3RpbmF0aW9uRmlsZVVyaSA9CisgICAgICBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0TW9kdWxlKCJtZGQiKS5zZXRSZWxhdGl2ZVBhdGgoImZpbGVfMSIpLmJ1aWxkKCk7CisKKyAgcHJpdmF0ZSBEb3dubG9hZFByb2dyZXNzTW9uaXRvciBkb3dubG9hZFByb2dyZXNzTW9uaXRvcjsKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyOworICBwcml2YXRlIGZpbmFsIEZha2VUaW1lU291cmNlIGNsb2NrID0gbmV3IEZha2VUaW1lU291cmNlKCk7CisKKyAgQE1vY2sgcHJpdmF0ZSBTaW5nbGVGaWxlRG93bmxvYWRMaXN0ZW5lciBtb2NrRG93bmxvYWRMaXN0ZW5lcjsKKyAgQE1vY2sgcHJpdmF0ZSBOZXR3b3JrVXNhZ2VNb25pdG9yIG1vY2tOZXR3b3JrVXNhZ2VNb25pdG9yOworCisgIHByaXZhdGUgZmluYWwgVGVzdEZsYWdzIGZsYWdzID0gbmV3IFRlc3RGbGFncygpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBkb3dubG9hZFByb2dyZXNzTW9uaXRvciA9IG5ldyBEb3dubG9hZFByb2dyZXNzTW9uaXRvcihjbG9jaywgQ09OVFJPTF9FWEVDVVRPUik7CisKKyAgICBmaWxlU3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgLyogYmFja2VuZHM9ICovIEltbXV0YWJsZUxpc3Qub2YoQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuYnVpbGQoKSksCisgICAgICAgICAgICAvKiB0cmFuc2Zvcm1zPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICAvKiBtb25pdG9ycz0gKi8gSW1tdXRhYmxlTGlzdC5vZihkb3dubG9hZFByb2dyZXNzTW9uaXRvcikpOworCisgICAgZmlsZURvd25sb2FkZXJTdXBwbGllciA9CisgICAgICAgICgpIC0+CisgICAgICAgICAgICBCYXNlRmlsZURvd25sb2FkZXJNb2R1bGUuY3JlYXRlT2Zmcm9hZDJGaWxlRG93bmxvYWRlcigKKyAgICAgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgICAgIERPV05MT0FEX0VYRUNVVE9SLAorICAgICAgICAgICAgICAgIENPTlRST0xfRVhFQ1VUT1IsCisgICAgICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAgICAgbmV3IFNoYXJlZFByZWZlcmVuY2VzRG93bmxvYWRNZXRhZGF0YSgKKyAgICAgICAgICAgICAgICAgICAgY29udGV4dC5nZXRTaGFyZWRQcmVmZXJlbmNlcygiZG93bmxvYWRtZXRhZGF0YSIsIDApLCBDT05UUk9MX0VYRUNVVE9SKSwKKyAgICAgICAgICAgICAgICBPcHRpb25hbC5vZihkb3dubG9hZFByb2dyZXNzTW9uaXRvciksCisgICAgICAgICAgICAgICAgLyogdXJsRW5naW5lT3B0aW9uYWw9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgICAgIC8qIGV4Y2VwdGlvbkhhbmRsZXJPcHRpb25hbD0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgLyogYXV0aFRva2VuUHJvdmlkZXJPcHRpb25hbD0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgLyogdHJhZmZpY1RhZz0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgZmxhZ3MpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlX3N1Y2Nlc3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhkZXN0aW5hdGlvbkZpbGVVcmkpKS5pc0ZhbHNlKCk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQgPSBnZXRNb2JpbGVEYXRhRG93bmxvYWQoZmlsZURvd25sb2FkZXJTdXBwbGllcik7CisKKyAgICBTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGVzdGluYXRpb25GaWxlVXJpKGRlc3RpbmF0aW9uRmlsZVVyaSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCkKKyAgICAgICAgICAgIC5zZXRMaXN0ZW5lck9wdGlvbmFsKE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZExpc3RlbmVyKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9IG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGUoZG93bmxvYWRSZXF1ZXN0KTsKKyAgICBkb3dubG9hZEZ1dHVyZS5nZXQoKTsKKworICAgIC8vIFZlcmlmeSB0aGUgZmlsZSBpcyBkb3dubG9hZGVkLgorICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKGRlc3RpbmF0aW9uRmlsZVVyaSkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZmlsZVNpemUoZGVzdGluYXRpb25GaWxlVXJpKSkuaXNFcXVhbFRvKEZJTEVfU0laRSk7CisgICAgZmlsZVN0b3JhZ2UuZGVsZXRlRmlsZShkZXN0aW5hdGlvbkZpbGVVcmkpOworCisgICAgLy8gVmVyaWZ5IHRoZSBkb3dubG9hZExpc3RlbmVyIGlzIGNhbGxlZC4KKyAgICAvLyBTbGVlcCBmb3IgMSBzZWMgdG8gd2FpdCBmb3IgdGhlIEZ1dHVyZSdzIGNhbGxiYWNrIHRvIGZpbmlzaC4KKyAgICBUaHJlYWQuc2xlZXAoLyptaWxsaXM9Ki8gMTAwMCk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyKS5vbkNvbXBsZXRlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZEZpbGVfZmFpbHVyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKGRlc3RpbmF0aW9uRmlsZVVyaSkpLmlzRmFsc2UoKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZCA9IGdldE1vYmlsZURhdGFEb3dubG9hZChmaWxlRG93bmxvYWRlclN1cHBsaWVyKTsKKworICAgIC8vIFRyeWluZyB0byBkb3dubG9hZCBkb2Vzbid0IGV4aXN0IFVSTC4KKyAgICBTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGVzdGluYXRpb25GaWxlVXJpKGRlc3RpbmF0aW9uRmlsZVVyaSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKERPRVNfTk9UX0VYSVNUX0ZJTEVfVVJMKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCkKKyAgICAgICAgICAgIC5zZXRMaXN0ZW5lck9wdGlvbmFsKE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZExpc3RlbmVyKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9IG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGUoZG93bmxvYWRSZXF1ZXN0KTsKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPSBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCBkb3dubG9hZEZ1dHVyZTo6Z2V0KTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIGFzc2VydFRoYXQoKChEb3dubG9hZEV4Y2VwdGlvbikgZXguZ2V0Q2F1c2UoKSkuZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpCisgICAgICAgIC5pc0VxdWFsVG8oQU5EUk9JRF9ET1dOTE9BREVSX0hUVFBfRVJST1IpOworCisgICAgLy8gVmVyaWZ5IHRoZSBmaWxlIGlzIGRvd25sb2FkZWQuCisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMoZGVzdGluYXRpb25GaWxlVXJpKSkuaXNGYWxzZSgpOworCisgICAgLy8gVmVyaWZ5IHRoZSBkb3dubG9hZExpc3RlbmVyIGlzIGNhbGxlZC4KKyAgICAvLyBTbGVlcCBmb3IgMSBzZWMgdG8gd2FpdCBmb3IgdGhlIEZ1dHVyZSdzIGNhbGxiYWNrIHRvIGZpbmlzaC4KKyAgICBUaHJlYWQuc2xlZXAoLyptaWxsaXM9Ki8gMTAwMCk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyKS5vbkZhaWx1cmUoYW55KERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZEZpbGVfY2FuY2VsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gUmVpbml0aWFsaXplIGRvd25sb2FkZXIgd2l0aCBhIEJsb2NraW5nRmlsZURvd25sb2FkZXIgdG8gZW5zdXJlIGRvd25sb2FkIHJlbWFpbnMgaW4gcHJvZ3Jlc3MKKyAgICAvLyB1bnRpbCBpdCBpcyBjYW5jZWxsZWQuCisgICAgQmxvY2tpbmdGaWxlRG93bmxvYWRlciBibG9ja2luZ0ZpbGVEb3dubG9hZGVyID0gbmV3IEJsb2NraW5nRmlsZURvd25sb2FkZXIoQ09OVFJPTF9FWEVDVVRPUik7CisgICAgbW9iaWxlRGF0YURvd25sb2FkID0gZ2V0TW9iaWxlRGF0YURvd25sb2FkKCgpIC0+IGJsb2NraW5nRmlsZURvd25sb2FkZXIpOworCisgICAgU2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCBkb3dubG9hZFJlcXVlc3QgPQorICAgICAgICBTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERlc3RpbmF0aW9uRmlsZVVyaShkZXN0aW5hdGlvbkZpbGVVcmkpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChGSUxFX1VSTCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPSBtb2JpbGVEYXRhRG93bmxvYWQuZG93bmxvYWRGaWxlKGRvd25sb2FkUmVxdWVzdCk7CisKKyAgICAvLyBOb3RlOiB3ZSBjb3VsZCBoYXZlIGEgcmFjZSBjb25kaXRpb24gaGVyZSBiZXR3ZWVuIHdoZW4gdGhlIEZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoKQorICAgIC8vIGlzIGNhbGxlZCBhbmQgd2hlbiB3ZSBjYW5jZWwgb3VyIGRvd25sb2FkIHdpdGggRnV0dXJlLmNhbmNlbCgpLiBUbyBwcmV2ZW50IHRoaXMsIHdlIGZpcnN0CisgICAgLy8gd2FpdCB1bnRpbCB3ZSBoYXZlIHN0YXJ0ZWQgZG93bmxvYWRpbmcgdG8gZW5zdXJlIHRoYXQgaXQgaXMgaW4gcHJvZ3Jlc3MgYmVmb3JlIHdlIGNhbmNlbC4KKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLndhaXRGb3JEb3dubG9hZFN0YXJ0ZWQoKTsKKworICAgIC8vIENhbmNlbCB0aGUgZG93bmxvYWQKKyAgICBkb3dubG9hZEZ1dHVyZS5jYW5jZWwoLyogbWF5SW50ZXJydXB0SWZSdW5uaW5nPSAqLyB0cnVlKTsKKworICAgIGFzc2VydFRocm93cyhDYW5jZWxsYXRpb25FeGNlcHRpb24uY2xhc3MsIGRvd25sb2FkRnV0dXJlOjpnZXQpOworCisgICAgLy8gQ2xlYW51cAorICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIucmVzZXRTdGF0ZSgpOworICB9CisKKyAgcHJpdmF0ZSBNb2JpbGVEYXRhRG93bmxvYWQgZ2V0TW9iaWxlRGF0YURvd25sb2FkKAorICAgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGZpbGVEb3dubG9hZGVyU3VwcGxpZXIpIHsKKyAgICByZXR1cm4gTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlci5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldENvbnRleHQoY29udGV4dCkKKyAgICAgICAgLnNldENvbnRyb2xFeGVjdXRvcihDT05UUk9MX0VYRUNVVE9SKQorICAgICAgICAuc2V0RmlsZURvd25sb2FkZXJTdXBwbGllcihmaWxlRG93bmxvYWRlclN1cHBsaWVyKQorICAgICAgICAuc2V0RmlsZVN0b3JhZ2UoZmlsZVN0b3JhZ2UpCisgICAgICAgIC5zZXREb3dubG9hZE1vbml0b3JPcHRpb25hbChPcHRpb25hbC5vZihkb3dubG9hZFByb2dyZXNzTW9uaXRvcikpCisgICAgICAgIC5zZXROZXR3b3JrVXNhZ2VNb25pdG9yKG1vY2tOZXR3b3JrVXNhZ2VNb25pdG9yKQorICAgICAgICAuc2V0RmxhZ3NPcHRpb25hbChPcHRpb25hbC5vZihmbGFncykpCisgICAgICAgIC5idWlsZCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvRG93bmxvYWRGaWxlVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkRmlsZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYThlZDQwCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL0Rvd25sb2FkRmlsZVRlc3QuamF2YQpAQCAtMCwwICsxLDY0NCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb24uRG93bmxvYWRSZXN1bHRDb2RlLkFORFJPSURfRE9XTkxPQURFUl9VTktOT1dOOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by50aW1lczsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ud2hlbjsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5BbmRyb2lkRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuRG93bmxvYWRQcm9ncmVzc01vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubW9uaXRvci5OZXR3b3JrVXNhZ2VNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRlc3RpbmcuQmxvY2tpbmdGaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLkZha2VUaW1lU291cmNlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRlc3RpbmcuVGVzdEZsYWdzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5TdXBwbGllcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24ubGFicy5jb25jdXJyZW50LkxhYnNGdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBvcmcuanVuaXQuQWZ0ZXI7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm1vY2tpdG8uQXJndW1lbnRDYXB0b3I7CitpbXBvcnQgb3JnLm1vY2tpdG8uQ2FwdG9yOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLnNoYWRvd3MuU2hhZG93TG9nOworCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgRG93bmxvYWRGaWxlVGVzdCB7CisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgLy8gMU1CIGZpbGUuCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX1VSTCA9CisgICAgICAiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vaWNpbmcvaWRkL3NhbXBsZV9ncm91cC9zYW1wbGVfZmlsZV8zXzE1MTkyNDA3MDEiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVcmkgREVTVElOQVRJT05fRklMRV9VUkkgPQorICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICJhbmRyb2lkOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8xIik7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29udGV4dCBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKworICBwcml2YXRlIGZpbmFsIFRlc3RGbGFncyBmbGFncyA9IG5ldyBUZXN0RmxhZ3MoKTsKKyAgcHJpdmF0ZSBmaW5hbCBGYWtlVGltZVNvdXJjZSBjbG9jayA9IG5ldyBGYWtlVGltZVNvdXJjZSgpOworCisgIHByaXZhdGUgRG93bmxvYWRQcm9ncmVzc01vbml0b3IgZG93bmxvYWRQcm9ncmVzc01vbml0b3I7CisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKworICBATW9jayBwcml2YXRlIFNpbmdsZUZpbGVEb3dubG9hZExpc3RlbmVyIG1vY2tEb3dubG9hZExpc3RlbmVyOworICBATW9jayBwcml2YXRlIE5ldHdvcmtVc2FnZU1vbml0b3IgbW9ja05ldHdvcmtVc2FnZU1vbml0b3I7CisgIEBNb2NrIHByaXZhdGUgRmlsZURvd25sb2FkZXIgbW9ja0ZpbGVEb3dubG9hZGVyOworICBATW9jayBwcml2YXRlIERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIG1vY2tEb3dubG9hZE1vbml0b3I7CisKKyAgcHJpdmF0ZSBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIGJsb2NraW5nRmlsZURvd25sb2FkZXI7CisgIHByaXZhdGUgU2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCBzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0OworICBwcml2YXRlIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQ7CisKKyAgQENhcHRvciBBcmd1bWVudENhcHRvcjxEb3dubG9hZExpc3RlbmVyPiBkb3dubG9hZExpc3RlbmVyQ2FwdG9yOworCisgIEBDYXB0b3IKKyAgQXJndW1lbnRDYXB0b3I8Y29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubGl0ZS5Eb3dubG9hZExpc3RlbmVyPgorICAgICAgbGl0ZURvd25sb2FkTGlzdGVuZXJDYXB0b3I7CisKKyAgQENhcHRvciBBcmd1bWVudENhcHRvcjxEb3dubG9hZFJlcXVlc3Q+IHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3RDYXB0b3I7CisKKyAgTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlIGNvbnRyb2xFeGVjdXRvciA9CisgICAgICBNb3JlRXhlY3V0b3JzLmxpc3RlbmluZ0RlY29yYXRvcihFeGVjdXRvcnMubmV3Q2FjaGVkVGhyZWFkUG9vbCgpKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgIFNoYWRvd0xvZy5zZXRMb2dnYWJsZShMb2dVdGlsLlRBRywgTG9nLkRFQlVHKTsKKworICAgIGRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yID0gbmV3IERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKGNsb2NrLCBjb250cm9sRXhlY3V0b3IpOworCisgICAgZmlsZVN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIC8qIGJhY2tlbmRzPSAqLyBJbW11dGFibGVMaXN0Lm9mKEFuZHJvaWRGaWxlQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLmJ1aWxkKCkpLAorICAgICAgICAgICAgLyogdHJhbnNmb3Jtcz0gKi8gSW1tdXRhYmxlTGlzdC5vZigpLAorICAgICAgICAgICAgLyogbW9uaXRvcnM9ICovIEltbXV0YWJsZUxpc3Qub2YoZG93bmxvYWRQcm9ncmVzc01vbml0b3IpKTsKKworICAgIHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QgPQorICAgICAgICBTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERlc3RpbmF0aW9uRmlsZVVyaShERVNUSU5BVElPTl9GSUxFX1VSSSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCkKKyAgICAgICAgICAgIC5zZXROb3RpZmljYXRpb25Db250ZW50VGl0bGUoIkZpbGUgdXJsOiAiICsgRklMRV9VUkwpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIgPSBuZXcgQmxvY2tpbmdGaWxlRG93bmxvYWRlcihjb250cm9sRXhlY3V0b3IpOworCisgICAgd2hlbihtb2NrRG93bmxvYWRMaXN0ZW5lci5vbkNvbXBsZXRlKCkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworICAgIHdoZW4obW9ja0ZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdENhcHRvci5jYXB0dXJlKCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKSk7CisgIH0KKworICBAQWZ0ZXIKKyAgcHVibGljIHZvaWQgdGVhckRvd24oKSB7CisgICAgLy8gUmVzZXQgc3RhdGUgb2YgYmxvY2tpbmdGaWxlRG93bmxvYWRlciB0byBwcmV2ZW50IGRlYWRsb2NrcworICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIucmVzZXRTdGF0ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlX3doZW5SZXF1ZXN0QWxyZWFkeU1hZGVfZGVkdXBzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVXNlIEJsb2NraW5nRmlsZURvd25sb2FkZXIgdG8gZW5zdXJlIGZpcnN0IGRvd25sb2FkIGlzIGluIHByb2dyZXNzLgorICAgIG1vYmlsZURhdGFEb3dubG9hZCA9IGdldE1vYmlsZURhdGFEb3dubG9hZCgoKSAtPiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUxID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmRvd25sb2FkRmlsZShzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0KTsKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlMiA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGUoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCk7CisKKyAgICAvLyBBbGxvdyBibG9ja2luZyBkb3dubG9hZCB0byBmaW5pc2gKKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLmZpbmlzaERvd25sb2FkaW5nKCk7CisKKyAgICAvLyBGaW5pc2ggZnV0dXJlIDIgYW5kIGFzc2VydCB0aGF0IGZ1dHVyZSAxIGhhcyBjb21wbGV0ZWQgYXMgd2VsbAorICAgIGRvd25sb2FkRnV0dXJlMi5nZXQoKTsKKworICAgIGF3YWl0QWxsRXhlY3V0b3JzSWRsZSgpOworCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZEZ1dHVyZTEuaXNEb25lKCkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlX3doZW5SZXF1ZXN0QWxyZWFkeU1hZGVVc2luZ0ZvcmVncm91bmRTZXJ2aWNlX2RlZHVwcygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFVzZSBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIHRvIGVuc3VyZSBmaXJzdCBkb3dubG9hZCBpcyBpbiBwcm9ncmVzcy4KKyAgICBtb2JpbGVEYXRhRG93bmxvYWQgPSBnZXRNb2JpbGVEYXRhRG93bmxvYWQoKCkgLT4gYmxvY2tpbmdGaWxlRG93bmxvYWRlcik7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlMSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGVXaXRoRm9yZWdyb3VuZFNlcnZpY2Uoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCk7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZTIgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuZG93bmxvYWRGaWxlKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QpOworCisgICAgLy8gQWxsb3cgYmxvY2tpbmcgZG93bmxvYWQgdG8gZmluaXNoCisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci5maW5pc2hEb3dubG9hZGluZygpOworCisgICAgLy8gRmluaXNoIGZ1dHVyZSAyIGFuZCBhc3NlcnQgdGhhdCBmdXR1cmUgMSBoYXMgY29tcGxldGVkIGFzIHdlbGwKKyAgICBkb3dubG9hZEZ1dHVyZTIuZ2V0KCk7CisKKyAgICBhd2FpdEFsbEV4ZWN1dG9yc0lkbGUoKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkRnV0dXJlMS5pc0RvbmUoKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZEZpbGVfYmVnaW5zRG93bmxvYWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBnZXRNb2JpbGVEYXRhRG93bmxvYWQoCisgICAgICAgICAgICAoKSAtPiBtb2NrRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICAvKiBmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvcikpOworCisgICAgc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGVzdGluYXRpb25GaWxlVXJpKERFU1RJTkFUSU9OX0ZJTEVfVVJJKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKQorICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTGlzdGVuZXIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmRvd25sb2FkRmlsZShzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0KTsKKyAgICBkb3dubG9hZEZ1dHVyZS5nZXQoKTsKKworICAgIGF3YWl0QWxsRXhlY3V0b3JzSWRsZSgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgY29ycmVjdCBEb3dubG9hZFJlcXVlc3QgaXMgc2VudCB0byB1bmRlcmx5aW5nIEZpbGVEb3dubG9hZGVyCisgICAgRG93bmxvYWRSZXF1ZXN0IGFjdHVhbERvd25sb2FkUmVxdWVzdCA9IHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3RDYXB0b3IuZ2V0VmFsdWUoKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbERvd25sb2FkUmVxdWVzdC5maWxlVXJpKCkpLmlzRXF1YWxUbyhERVNUSU5BVElPTl9GSUxFX1VSSSk7CisgICAgYXNzZXJ0VGhhdChhY3R1YWxEb3dubG9hZFJlcXVlc3QudXJsVG9Eb3dubG9hZCgpKS5pc0VxdWFsVG8oRklMRV9VUkwpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LmRvd25sb2FkQ29uc3RyYWludHMoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IGRvd25sb2FkTW9uaXRvciBhZGRzIHRoZSBsaXN0ZW5lcgorICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5hZGREb3dubG9hZExpc3RlbmVyKGFueSgpLCBsaXRlRG93bmxvYWRMaXN0ZW5lckNhcHRvci5jYXB0dXJlKCkpOworICAgIHZlcmlmeShtb2NrRmlsZURvd25sb2FkZXIpLnN0YXJ0RG93bmxvYWRpbmcoYW55KCkpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZE1vbml0b3IpLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoREVTVElOQVRJT05fRklMRV9VUkkpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcikub25Db21wbGV0ZSgpOworCisgICAgLy8gRW5zdXJlIHRoYXQgZ2l2ZW4gZG93bmxvYWQgbGlzdGVuZXIgaXMgdGhlIHNhbWUgb25lIHBhc3NlZCB0byBkb3dubG9hZCBtb25pdG9yCisgICAgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubGl0ZS5Eb3dubG9hZExpc3RlbmVyIGNhcHR1cmVkRG93bmxvYWRMaXN0ZW5lciA9CisgICAgICAgIGxpdGVEb3dubG9hZExpc3RlbmVyQ2FwdG9yLmdldFZhbHVlKCk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gdGVzdEV4Y2VwdGlvbiA9CisgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKS5zZXREb3dubG9hZFJlc3VsdENvZGUoQU5EUk9JRF9ET1dOTE9BREVSX1VOS05PV04pLmJ1aWxkKCk7CisKKyAgICBjYXB0dXJlZERvd25sb2FkTGlzdGVuZXIub25Qcm9ncmVzcygxMCk7CisgICAgY2FwdHVyZWREb3dubG9hZExpc3RlbmVyLm9uRmFpbHVyZSh0ZXN0RXhjZXB0aW9uKTsKKyAgICBjYXB0dXJlZERvd25sb2FkTGlzdGVuZXIub25QYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcikub25Qcm9ncmVzcygxMCk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyKS5vbkZhaWx1cmUodGVzdEV4Y2VwdGlvbik7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyKS5vblBhdXNlZEZvckNvbm5lY3Rpdml0eSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRfd2hlbkxpc3RlbmVyUHJvdmlkZWRfaGFuZGxlc09uQ29tcGxldGVGYWlsZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFeGNlcHRpb24gZmFpbHVyZUV4Y2VwdGlvbiA9IG5ldyBFeGNlcHRpb24oInRlc3QgZmFpbHVyZSIpOworICAgIHdoZW4obW9ja0Rvd25sb2FkTGlzdGVuZXIub25Db21wbGV0ZSgpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZShmYWlsdXJlRXhjZXB0aW9uKSk7CisgICAgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkKAorICAgICAgICAgICAgY3JlYXRlU3VjY2Vzc2Z1bEZpbGVEb3dubG9hZGVyU3VwcGxpZXIoKSwKKyAgICAgICAgICAgIC8qIGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBPcHRpb25hbC5vZihkb3dubG9hZFByb2dyZXNzTW9uaXRvcikpOworCisgICAgc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGVzdGluYXRpb25GaWxlVXJpKERFU1RJTkFUSU9OX0ZJTEVfVVJJKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKQorICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTGlzdGVuZXIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuZG93bmxvYWRGaWxlKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QpLmdldCgpOworCisgICAgYXdhaXRBbGxFeGVjdXRvcnNJZGxlKCk7CisKKyAgICAvLyBWZXJpZnkgdGhlIERvd25sb2FkTGlzdGVuZXJzIG9uQ29tcGxldGUgd2FzIGludm9rZWQKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIpLm9uQ29tcGxldGUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkRmlsZV93aGVuRG93bmxvYWRGYWlsc19yZXBvcnRzRmFpbHVyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIERvd25sb2FkRXhjZXB0aW9uIGRvd25sb2FkRXhjZXB0aW9uID0KKyAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpLnNldERvd25sb2FkUmVzdWx0Q29kZShBTkRST0lEX0RPV05MT0FERVJfVU5LTk9XTikuYnVpbGQoKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIGdldE1vYmlsZURhdGFEb3dubG9hZCgKKyAgICAgICAgICAgIGNyZWF0ZUZhaWxpbmdGaWxlRG93bmxvYWRlclN1cHBsaWVyKGRvd25sb2FkRXhjZXB0aW9uKSwKKyAgICAgICAgICAgIC8qIGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBPcHRpb25hbC5vZihkb3dubG9hZFByb2dyZXNzTW9uaXRvcikpOworCisgICAgc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIFNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGVzdGluYXRpb25GaWxlVXJpKERFU1RJTkFUSU9OX0ZJTEVfVVJJKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKQorICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTGlzdGVuZXIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmRvd25sb2FkRmlsZShzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0KTsKKyAgICBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCBkb3dubG9hZEZ1dHVyZTo6Z2V0KTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBlID0gTGFic0Z1dHVyZXMuZ2V0RmFpbHVyZUNhdXNlQXMoZG93bmxvYWRGdXR1cmUsIERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBhc3NlcnRUaGF0KGUuZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpLmlzRXF1YWxUbyhBTkRST0lEX0RPV05MT0FERVJfVU5LTk9XTik7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBEb3dubG9hZExpc3RlbmVyLm9uRmFpbHVyZSB3YXMgaW52b2tlZCB3aXRoIGZhaWx1cmUKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIpLm9uRmFpbHVyZShkb3dubG9hZEV4Y2VwdGlvbik7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyLCB0aW1lcygwKSkub25Db21wbGV0ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlX3doZW5SZXR1cm5lZEZ1dHVyZUlzQ2FuY2VsZWRfY2FuY2Vsc0Rvd25sb2FkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV3JhcCBtb2NrIGFyb3VuZCBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIHRvIHNpbXVsYXRlIGxvbmcgZG93bmxvYWQKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQgPSBnZXRNb2JpbGVEYXRhRG93bmxvYWQoKCkgLT4gYmxvY2tpbmdGaWxlRG93bmxvYWRlcik7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmRvd25sb2FkRmlsZShzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0KTsKKworICAgIC8vIFdhaXQgZm9yIGRvd25sb2FkIHRvIHN0YXJ0IGFuZCBjb25maXJtIGRvd25sb2FkIGZ1dHVyZSBpcyBzdGlsbCBydW5uaW5nLgorICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIud2FpdEZvckRvd25sb2FkU3RhcnRlZCgpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRGdXR1cmUuaXNEb25lKCkpLmlzRmFsc2UoKTsKKworICAgIC8vIENhbmNlbCBkb3dubG9hZCBmdXR1cmUuCisgICAgZG93bmxvYWRGdXR1cmUuY2FuY2VsKHRydWUpOworCisgICAgLy8gQ2hlY2sgdGhhdCBmdXR1cmUgaXMgbm93IGNhbmNlbGxlZC4KKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkRnV0dXJlLmlzQ2FuY2VsbGVkKCkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlX3doZW5Nb25pdG9yTm90UHJvdmlkZWRfd2hlbkRvd25sb2FkRmFpbHNfcmVwb3J0c0ZhaWx1cmUoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRG93bmxvYWRFeGNlcHRpb24gZG93bmxvYWRFeGNlcHRpb24gPQorICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkuc2V0RG93bmxvYWRSZXN1bHRDb2RlKEFORFJPSURfRE9XTkxPQURFUl9VTktOT1dOKS5idWlsZCgpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkKGNyZWF0ZUZhaWxpbmdGaWxlRG93bmxvYWRlclN1cHBsaWVyKGRvd25sb2FkRXhjZXB0aW9uKSk7CisKKyAgICBzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0ID0KKyAgICAgICAgU2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREZXN0aW5hdGlvbkZpbGVVcmkoREVTVElOQVRJT05fRklMRV9VUkkpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChGSUxFX1VSTCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpCisgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbChPcHRpb25hbC5vZihtb2NrRG93bmxvYWRMaXN0ZW5lcikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuZG93bmxvYWRGaWxlKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QpOworICAgIGFzc2VydFRocm93cyhFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsIGRvd25sb2FkRnV0dXJlOjpnZXQpOworICAgIERvd25sb2FkRXhjZXB0aW9uIGUgPSBMYWJzRnV0dXJlcy5nZXRGYWlsdXJlQ2F1c2VBcyhkb3dubG9hZEZ1dHVyZSwgRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIGFzc2VydFRoYXQoZS5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkuaXNFcXVhbFRvKEFORFJPSURfRE9XTkxPQURFUl9VTktOT1dOKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IERvd25sb2FkTGlzdGVuZXIub25GYWlsdXJlIHdhcyBpbnZva2VkIHdpdGggZmFpbHVyZQorICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcikub25GYWlsdXJlKGRvd25sb2FkRXhjZXB0aW9uKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIsIHRpbWVzKDApKS5vbkNvbXBsZXRlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZEZpbGVXaXRoV2l0aEZvcmVncm91bmRTZXJ2aWNlX3JlcXVpcmVzRm9yZWdyb3VuZERvd25sb2FkU2VydmljZSgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgZG93bmxvYWRlciB3aXRob3V0IHByb3ZpZGluZyBmb3JlZ3JvdW5kIHNlcnZpY2UKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBnZXRNb2JpbGVEYXRhRG93bmxvYWQoCisgICAgICAgICAgICAoKSAtPiBtb2NrRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICAvKiBmb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlQ2xhc3NPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YoZG93bmxvYWRQcm9ncmVzc01vbml0b3IpKTsKKworICAgIC8vIFdpdGhvdXQgZm9yZWdyb3VuZCBzZXJ2aWNlLCBkb3dubG9hZCBjYWxsIHNob3VsZCBmYWlsIHdpdGggSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGVXaXRoRm9yZWdyb3VuZFNlcnZpY2Uoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCk7CisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGUgPSBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCBkb3dubG9hZEZ1dHVyZTo6Z2V0KTsKKyAgICBhc3NlcnRUaGF0KGUpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihJbGxlZ2FsU3RhdGVFeGNlcHRpb24uY2xhc3MpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgdW5kZXJseWluZyBkb3dubG9hZCBpcyBub3Qgc3RhcnRlZAorICAgIHZlcmlmeShtb2NrRmlsZURvd25sb2FkZXIsIHRpbWVzKDApKS5zdGFydERvd25sb2FkaW5nKGFueSgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkRmlsZVdpdGhGb3JlZ3JvdW5kU2VydmljZV9yZXF1aXJlc0Rvd25sb2FkTW9uaXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENyZWF0ZSBkb3dubG9hZGVyIHdpdGhvdXQgcHJvdmlkaW5nIERvd25sb2FkTW9uaXRvcgorICAgIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIGdldE1vYmlsZURhdGFEb3dubG9hZCgKKyAgICAgICAgICAgICgpIC0+IG1vY2tGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksCisgICAgICAgICAgICAvKiBkb3dubG9hZFByb2dyZXNzTW9uaXRvck9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCkpOworCisgICAgLy8gV2l0aG91dCBtb25pdG9yLCBkb3dubG9hZCBjYWxsIHNob3VsZCBmYWlsIHdpdGggSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGVXaXRoRm9yZWdyb3VuZFNlcnZpY2Uoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCk7CisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGUgPSBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCBkb3dubG9hZEZ1dHVyZTo6Z2V0KTsKKyAgICBhc3NlcnRUaGF0KGUpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihJbGxlZ2FsU3RhdGVFeGNlcHRpb24uY2xhc3MpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgdW5kZXJseWluZyBkb3dubG9hZCBpcyBub3Qgc3RhcnRlZAorICAgIHZlcmlmeShtb2NrRmlsZURvd25sb2FkZXIsIHRpbWVzKDApKS5zdGFydERvd25sb2FkaW5nKGFueSgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkRmlsZVdpdGhGb3JlZ3JvdW5kU2VydmljZV93aGVuUmVxdWVzdEFscmVhZHlNYWRlX2RlZHVwcygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFVzZSBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIHRvIGNvbnRyb2wgd2hlbiB0aGUgZG93bmxvYWQgd2lsbCBmaW5pc2guCisgICAgbW9iaWxlRGF0YURvd25sb2FkID0gZ2V0TW9iaWxlRGF0YURvd25sb2FkKCgpIC0+IGJsb2NraW5nRmlsZURvd25sb2FkZXIpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZTEgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuZG93bmxvYWRGaWxlV2l0aEZvcmVncm91bmRTZXJ2aWNlKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QpOworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUyID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmRvd25sb2FkRmlsZVdpdGhGb3JlZ3JvdW5kU2VydmljZShzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0KTsKKworICAgIC8vIE5vdyB3ZSBsZXQgdGhlIDIgZnV0dXJlcyBkb3dubG9hZEZ1dHVyZTEgZG93bmxvYWRGdXR1cmUyIHRvIHJ1biBieSBvcGVuaW5nIHRoZSBsYXRjaC4KKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLmZpbmlzaERvd25sb2FkaW5nKCk7CisKKyAgICAvLyBOb3cgZmluaXNoIGZ1dHVyZSAyLCBmdXR1cmUgMSBzaG91bGQgZmluaXNoIHRvbyBhbmQgdGhlIGNhY2hlIGNsZWFycyB0aGUgZnV0dXJlLgorICAgIGRvd25sb2FkRnV0dXJlMi5nZXQoKTsKKworICAgIGF3YWl0QWxsRXhlY3V0b3JzSWRsZSgpOworCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZEZ1dHVyZTEuaXNEb25lKCkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQKKyAgICAgIGRvd25sb2FkRmlsZVdpdGhGb3JlZ3JvdW5kU2VydmljZV93aGVuUmVxdWVzdEFscmVhZHlNYWRlV2l0aG91dEZvcmVncm91bmRTZXJ2aWNlX2RlZHVwcygpCisgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVXNlIEJsb2NraW5nRmlsZURvd25sb2FkZXIgdG8gY29udHJvbCB3aGVuIHRoZSBkb3dubG9hZCB3aWxsIGZpbmlzaC4KKyAgICBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBnZXRNb2JpbGVEYXRhRG93bmxvYWQoCisgICAgICAgICAgICAoKSAtPiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKGRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKSk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlMSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGUoc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdCk7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZTIgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuZG93bmxvYWRGaWxlV2l0aEZvcmVncm91bmRTZXJ2aWNlKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QpOworCisgICAgLy8gTm93IHdlIGxldCB0aGUgMiBmdXR1cmVzIGRvd25sb2FkRnV0dXJlMSBkb3dubG9hZEZ1dHVyZTIgdG8gcnVuIGJ5IG9wZW5pbmcgdGhlIGxhdGNoLgorICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIuZmluaXNoRG93bmxvYWRpbmcoKTsKKworICAgIC8vIE5vdyBmaW5pc2ggZnV0dXJlIDIsIGZ1dHVyZSAxIHNob3VsZCBmaW5pc2ggdG9vIGFuZCB0aGUgY2FjaGUgY2xlYXJzIHRoZSBmdXR1cmUuCisgICAgZG93bmxvYWRGdXR1cmUyLmdldCgpOworCisgICAgYXdhaXRBbGxFeGVjdXRvcnNJZGxlKCk7CisKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkRnV0dXJlMS5pc0RvbmUoKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZEZpbGVXaXRoRm9yZWdyb3VuZFNlcnZpY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKG1vY2tGaWxlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3RDYXB0b3IuY2FwdHVyZSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworICAgIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIGdldE1vYmlsZURhdGFEb3dubG9hZCgKKyAgICAgICAgICAgICgpIC0+IG1vY2tGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrRG93bmxvYWRNb25pdG9yKSk7CisKKyAgICBzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0ID0KKyAgICAgICAgU2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREZXN0aW5hdGlvbkZpbGVVcmkoREVTVElOQVRJT05fRklMRV9VUkkpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChGSUxFX1VSTCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpCisgICAgICAgICAgICAuc2V0Tm90aWZpY2F0aW9uQ29udGVudFRpdGxlKCJGaWxlIHVybDogIiArIEZJTEVfVVJMKQorICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTGlzdGVuZXIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmRvd25sb2FkRmlsZVdpdGhGb3JlZ3JvdW5kU2VydmljZShzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0KTsKKyAgICBkb3dubG9hZEZ1dHVyZS5nZXQoKTsKKworICAgIGF3YWl0QWxsRXhlY3V0b3JzSWRsZSgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGNvcnJlY3QgRG93bmxvYWRSZXF1ZXN0IGlzIHNlbnQgdG8gdW5kZXJkZXJseWluZyBGaWxlRG93bmxvYWRlci4KKyAgICBEb3dubG9hZFJlcXVlc3QgYWN0dWFsRG93bmxvYWRSZXF1ZXN0ID0gc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdENhcHRvci5nZXRWYWx1ZSgpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LmZpbGVVcmkoKSkuaXNFcXVhbFRvKERFU1RJTkFUSU9OX0ZJTEVfVVJJKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbERvd25sb2FkUmVxdWVzdC51cmxUb0Rvd25sb2FkKCkpLmlzRXF1YWxUbyhGSUxFX1VSTCk7CisgICAgYXNzZXJ0VGhhdChhY3R1YWxEb3dubG9hZFJlcXVlc3QuZG93bmxvYWRDb25zdHJhaW50cygpKQorICAgICAgICAuaXNFcXVhbFRvKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgZG93bmxvYWRNb25pdG9yIHdpbGwgYWRkIGEgRG93bmxvYWRMaXN0ZW5lci4KKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTW9uaXRvcikuYWRkRG93bmxvYWRMaXN0ZW5lcihhbnkoKSwgbGl0ZURvd25sb2FkTGlzdGVuZXJDYXB0b3IuY2FwdHVyZSgpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVEb3dubG9hZGVyKS5zdGFydERvd25sb2FkaW5nKGFueSgpKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKERFU1RJTkFUSU9OX0ZJTEVfVVJJKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcikub25Db21wbGV0ZSgpOworCisgICAgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubGl0ZS5Eb3dubG9hZExpc3RlbmVyIGNhcHR1cmVkTGlzdGVuZXIgPQorICAgICAgICBsaXRlRG93bmxvYWRMaXN0ZW5lckNhcHRvci5nZXRWYWx1ZSgpOworCisgICAgLy8gTm93IHNpbXVsYXRlIG90aGVyIERvd25sb2FkTGlzdGVuZXIncyBjYWxsYmFja3M6CisgICAgY2FwdHVyZWRMaXN0ZW5lci5vblByb2dyZXNzKDEwKTsKKyAgICBjYXB0dXJlZExpc3RlbmVyLm9uUGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gZG93bmxvYWRFeGNlcHRpb24gPQorICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkuc2V0RG93bmxvYWRSZXN1bHRDb2RlKEFORFJPSURfRE9XTkxPQURFUl9VTktOT1dOKS5idWlsZCgpOworICAgIGNhcHR1cmVkTGlzdGVuZXIub25GYWlsdXJlKGRvd25sb2FkRXhjZXB0aW9uKTsKKworICAgIGF3YWl0QWxsRXhlY3V0b3JzSWRsZSgpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyKS5vblByb2dyZXNzKDEwKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIpLm9uUGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyKS5vbkZhaWx1cmUoZG93bmxvYWRFeGNlcHRpb24pOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlV2l0aEZvcmVncm91bmRTZXJ2aWNlX2NsaWVudE9uQ29tcGxldGVGYWlsZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFeGNlcHRpb24gZmFpbHVyZUV4Y2VwdGlvbiA9IG5ldyBFeGNlcHRpb24oInRlc3QgZmFpbHVyZSIpOworCisgICAgd2hlbihtb2NrRmlsZURvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZyhzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0Q2FwdG9yLmNhcHR1cmUoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBnZXRNb2JpbGVEYXRhRG93bmxvYWQoCisgICAgICAgICAgICAoKSAtPiBtb2NrRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YoZG93bmxvYWRQcm9ncmVzc01vbml0b3IpKTsKKworICAgIC8vIENsaWVudCdzIHByb3ZpZGVkIERvd25sb2FkTGlzdGVuZXIub25Db21wbGV0ZSBmYWlsZWQuCisgICAgd2hlbihtb2NrRG93bmxvYWRMaXN0ZW5lci5vbkNvbXBsZXRlKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGZhaWx1cmVFeGNlcHRpb24pKTsKKworICAgIHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QgPQorICAgICAgICBTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERlc3RpbmF0aW9uRmlsZVVyaShERVNUSU5BVElPTl9GSUxFX1VSSSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCkKKyAgICAgICAgICAgIC5zZXROb3RpZmljYXRpb25Db250ZW50VGl0bGUoIkZpbGUgdXJsOiAiICsgRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbChPcHRpb25hbC5vZihtb2NrRG93bmxvYWRMaXN0ZW5lcikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuZG93bmxvYWRGaWxlV2l0aEZvcmVncm91bmRTZXJ2aWNlKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QpOworICAgIGRvd25sb2FkRnV0dXJlLmdldCgpOworCisgICAgYXdhaXRBbGxFeGVjdXRvcnNJZGxlKCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgY29ycmVjdCBEb3dubG9hZFJlcXVlc3QgaXMgc2VudCB0byB1bmRlcmRlcmx5aW5nIEZpbGVEb3dubG9hZGVyLgorICAgIERvd25sb2FkUmVxdWVzdCBhY3R1YWxEb3dubG9hZFJlcXVlc3QgPSBzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0Q2FwdG9yLmdldFZhbHVlKCk7CisgICAgYXNzZXJ0VGhhdChhY3R1YWxEb3dubG9hZFJlcXVlc3QuZmlsZVVyaSgpKS5pc0VxdWFsVG8oREVTVElOQVRJT05fRklMRV9VUkkpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LnVybFRvRG93bmxvYWQoKSkuaXNFcXVhbFRvKEZJTEVfVVJMKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbERvd25sb2FkUmVxdWVzdC5kb3dubG9hZENvbnN0cmFpbnRzKCkpCisgICAgICAgIC5pc0VxdWFsVG8oRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVEb3dubG9hZGVyKS5zdGFydERvd25sb2FkaW5nKGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIpLm9uQ29tcGxldGUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkRmlsZVdpdGhGb3JlZ3JvdW5kU2VydmljZV9mYWlsdXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRG93bmxvYWRFeGNlcHRpb24gZG93bmxvYWRFeGNlcHRpb24gPQorICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkuc2V0RG93bmxvYWRSZXN1bHRDb2RlKEFORFJPSURfRE9XTkxPQURFUl9VTktOT1dOKS5idWlsZCgpOworCisgICAgd2hlbihtb2NrRmlsZURvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZyhzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0Q2FwdG9yLmNhcHR1cmUoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGRvd25sb2FkRXhjZXB0aW9uKSk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBnZXRNb2JpbGVEYXRhRG93bmxvYWQoCisgICAgICAgICAgICAoKSAtPiBtb2NrRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YoZG93bmxvYWRQcm9ncmVzc01vbml0b3IpKTsKKworICAgIHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QgPQorICAgICAgICBTaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERlc3RpbmF0aW9uRmlsZVVyaShERVNUSU5BVElPTl9GSUxFX1VSSSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCkKKyAgICAgICAgICAgIC5zZXROb3RpZmljYXRpb25Db250ZW50VGl0bGUoIkZpbGUgdXJsOiAiICsgRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbChPcHRpb25hbC5vZihtb2NrRG93bmxvYWRMaXN0ZW5lcikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuZG93bmxvYWRGaWxlV2l0aEZvcmVncm91bmRTZXJ2aWNlKHNpbmdsZUZpbGVEb3dubG9hZFJlcXVlc3QpOworICAgIGFzc2VydFRocm93cyhFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsIGRvd25sb2FkRnV0dXJlOjpnZXQpOworICAgIERvd25sb2FkRXhjZXB0aW9uIGUgPSBMYWJzRnV0dXJlcy5nZXRGYWlsdXJlQ2F1c2VBcyhkb3dubG9hZEZ1dHVyZSwgRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIGFzc2VydFRoYXQoZS5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkuaXNFcXVhbFRvKEFORFJPSURfRE9XTkxPQURFUl9VTktOT1dOKTsKKworICAgIGF3YWl0QWxsRXhlY3V0b3JzSWRsZSgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGNvcnJlY3QgRG93bmxvYWRSZXF1ZXN0IGlzIHNlbnQgdG8gdW5kZXJkZXJseWluZyBGaWxlRG93bmxvYWRlci4KKyAgICBEb3dubG9hZFJlcXVlc3QgYWN0dWFsRG93bmxvYWRSZXF1ZXN0ID0gc2luZ2xlRmlsZURvd25sb2FkUmVxdWVzdENhcHRvci5nZXRWYWx1ZSgpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LmZpbGVVcmkoKSkuaXNFcXVhbFRvKERFU1RJTkFUSU9OX0ZJTEVfVVJJKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbERvd25sb2FkUmVxdWVzdC51cmxUb0Rvd25sb2FkKCkpLmlzRXF1YWxUbyhGSUxFX1VSTCk7CisgICAgYXNzZXJ0VGhhdChhY3R1YWxEb3dubG9hZFJlcXVlc3QuZG93bmxvYWRDb25zdHJhaW50cygpKQorICAgICAgICAuaXNFcXVhbFRvKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpOworCisgICAgLy8gU2luY2UgdGhlIGRvd25sb2FkIGZhaWxlZCwgb25Db21wbGV0ZSB3aWxsIG5vdCBiZSBjYWxsZWQgYnV0IG9uRmFpbHVyZS4KKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIsIHRpbWVzKDApKS5vbkNvbXBsZXRlKCk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyKS5vbkZhaWx1cmUoZG93bmxvYWRFeGNlcHRpb24pOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY2FuY2VsRG93bmxvYWRGaWxlV2l0aEZvcmVncm91bmRTZXJ2aWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVXNlIEJsb2NraW5nRmlsZURvd25sb2FkZXIgdG8gY29udHJvbCB3aGVuIHRoZSBkb3dubG9hZCB3aWxsIGZpbmlzaC4KKyAgICBtb2JpbGVEYXRhRG93bmxvYWQgPSBnZXRNb2JpbGVEYXRhRG93bmxvYWQoKCkgLT4gYmxvY2tpbmdGaWxlRG93bmxvYWRlcik7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmRvd25sb2FkRmlsZVdpdGhGb3JlZ3JvdW5kU2VydmljZShzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0KTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZC5jYW5jZWxGb3JlZ3JvdW5kRG93bmxvYWQoREVTVElOQVRJT05fRklMRV9VUkkudG9TdHJpbmcoKSk7CisKKyAgICBhd2FpdEFsbEV4ZWN1dG9yc0lkbGUoKTsKKworICAgIGFzc2VydFRydWUoZG93bmxvYWRGdXR1cmUuaXNDYW5jZWxsZWQoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjYW5jZWxMaXN0ZW5hYmxlRnV0dXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVXNlIEJsb2NraW5nRmlsZURvd25sb2FkZXIgdG8gY29udHJvbCB3aGVuIHRoZSBkb3dubG9hZCB3aWxsIGZpbmlzaC4KKyAgICBtb2JpbGVEYXRhRG93bmxvYWQgPSBnZXRNb2JpbGVEYXRhRG93bmxvYWQoKCkgLT4gYmxvY2tpbmdGaWxlRG93bmxvYWRlcik7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmRvd25sb2FkRmlsZVdpdGhGb3JlZ3JvdW5kU2VydmljZShzaW5nbGVGaWxlRG93bmxvYWRSZXF1ZXN0KTsKKworICAgIC8vIFdhaXQgZm9yIGRvd25sb2FkIHRvIHN0YXJ0IGFuZCBjb25maXJtIGRvd25sb2FkIGZ1dHVyZSBpcyBzdGlsbCBydW5uaW5nLgorICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIud2FpdEZvckRvd25sb2FkU3RhcnRlZCgpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRGdXR1cmUuaXNEb25lKCkpLmlzRmFsc2UoKTsKKworICAgIC8vIENhbmNlbCBkb3dubG9hZCBmdXR1cmUuCisgICAgZG93bmxvYWRGdXR1cmUuY2FuY2VsKHRydWUpOworCisgICAgLy8gQ2hlY2sgdGhhdCBmdXR1cmUgaXMgbm93IGNhbmNlbGxlZC4KKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkRnV0dXJlLmlzQ2FuY2VsbGVkKCkpLmlzVHJ1ZSgpOworICB9CisKKyAgcHJpdmF0ZSBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gY3JlYXRlRmFpbGluZ0ZpbGVEb3dubG9hZGVyU3VwcGxpZXIoVGhyb3dhYmxlIHRocm93YWJsZSkgeworICAgIHJldHVybiBTdXBwbGllcnMub2ZJbnN0YW5jZSgKKyAgICAgICAgbmV3IEZpbGVEb3dubG9hZGVyKCkgeworICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHN0YXJ0RG93bmxvYWRpbmcoRG93bmxvYWRSZXF1ZXN0IHJlcXVlc3QpIHsKKyAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSh0aHJvd2FibGUpOworICAgICAgICAgIH0KKyAgICAgICAgfSk7CisgIH0KKworICBwcml2YXRlIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBjcmVhdGVTdWNjZXNzZnVsRmlsZURvd25sb2FkZXJTdXBwbGllcigpIHsKKyAgICByZXR1cm4gU3VwcGxpZXJzLm9mSW5zdGFuY2UoCisgICAgICAgIG5ldyBGaWxlRG93bmxvYWRlcigpIHsKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBzdGFydERvd25sb2FkaW5nKERvd25sb2FkUmVxdWVzdCByZXF1ZXN0KSB7CisgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgfQorICAgICAgICB9KTsKKyAgfQorCisgIHByaXZhdGUgTW9iaWxlRGF0YURvd25sb2FkIGdldE1vYmlsZURhdGFEb3dubG9hZCgKKyAgICAgIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyKSB7CisgICAgcmV0dXJuIGdldE1vYmlsZURhdGFEb3dubG9hZCgKKyAgICAgICAgZmlsZURvd25sb2FkZXJTdXBwbGllciwgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgT3B0aW9uYWwub2YoZG93bmxvYWRQcm9ncmVzc01vbml0b3IpKTsKKyAgfQorCisgIHByaXZhdGUgTW9iaWxlRGF0YURvd25sb2FkIGdldE1vYmlsZURhdGFEb3dubG9hZCgKKyAgICAgIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyLAorICAgICAgT3B0aW9uYWw8Q2xhc3M8Pz4+IGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsLAorICAgICAgT3B0aW9uYWw8RG93bmxvYWRQcm9ncmVzc01vbml0b3I+IGRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yT3B0aW9uYWwpIHsKKyAgICByZXR1cm4gTW9iaWxlRGF0YURvd25sb2FkQnVpbGRlci5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldENvbnRleHQoY29udGV4dCkKKyAgICAgICAgLnNldENvbnRyb2xFeGVjdXRvcihjb250cm9sRXhlY3V0b3IpCisgICAgICAgIC5zZXRGaWxlRG93bmxvYWRlclN1cHBsaWVyKGZpbGVEb3dubG9hZGVyU3VwcGxpZXIpCisgICAgICAgIC5zZXRGaWxlU3RvcmFnZShmaWxlU3RvcmFnZSkKKyAgICAgICAgLnNldERvd25sb2FkTW9uaXRvck9wdGlvbmFsKGRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yT3B0aW9uYWwpCisgICAgICAgIC5zZXROZXR3b3JrVXNhZ2VNb25pdG9yKG1vY2tOZXR3b3JrVXNhZ2VNb25pdG9yKQorICAgICAgICAuc2V0Rm9yZWdyb3VuZERvd25sb2FkU2VydmljZU9wdGlvbmFsKGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsKQorICAgICAgICAuc2V0RmxhZ3NPcHRpb25hbChPcHRpb25hbC5vZihmbGFncykpCisgICAgICAgIC5idWlsZCgpOworICB9CisKKyAgLyoqIFdhaXRzIGxvbmcgZW5vdWdoIGZvciBhc3luYyBvcGVyYXRpb25zIHRvIGZpbmlzaCBydW5uaW5nLiAqLworICAvLyBUT0RPKGIvMjE3NTUxODczKTogaW52ZXN0aWdhdGUgd2F5cyB0byBtYWtlIHRoaXMgbW9yZSByb2J1c3QKKyAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBhd2FpdEFsbEV4ZWN1dG9yc0lkbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUaHJlYWQuc2xlZXAoLyogbWlsbGlzPSAqLyAxMDApOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvSW1wb3J0RmlsZXNJbnRlZ3JhdGlvblRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9JbXBvcnRGaWxlc0ludGVncmF0aW9uVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjNWYxZWEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvSW1wb3J0RmlsZXNJbnRlZ3JhdGlvblRlc3QuamF2YQpAQCAtMCwwICsxLDg0NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQ7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGVzdEZpbGVHcm91cFBvcHVsYXRvci5GSUxFX0NIRUNLU1VNOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UZXN0RmlsZUdyb3VwUG9wdWxhdG9yLkZJTEVfR1JPVVBfTkFNRTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGVzdEZpbGVHcm91cFBvcHVsYXRvci5GSUxFX0lEOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UZXN0RmlsZUdyb3VwUG9wdWxhdG9yLkZJTEVfU0laRTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGVzdEZpbGVHcm91cFBvcHVsYXRvci5GSUxFX1VSTDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLm9zLkVudmlyb25tZW50OworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmV4dC5qdW5pdC5ydW5uZXJzLkFuZHJvaWRKVW5pdDQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb24uRG93bmxvYWRSZXN1bHRDb2RlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5NdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuaW5saW5lLklubGluZUZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZC5kYWdnZXIuZG93bmxvYWRlcjIuQmFzZUZpbGVEb3dubG9hZGVyTW9kdWxlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkZpbGVVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5KYXZhRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5GYWtlRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5GYWtlRmlsZUJhY2tlbmQuT3BlcmF0aW9uVHlwZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmludGVncmF0aW9uLmRvd25sb2FkZXIuU2hhcmVkUHJlZmVyZW5jZXNEb3dubG9hZE1ldGFkYXRhOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWFkU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5Db21wcmVzc1RyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuTmV0d29ya1VzYWdlTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLkJsb2NraW5nRmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5UZXN0RmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZU1hcDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5Db3JyZXNwb25kZW5jZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlQ2FsbGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5DbGllbnRDb25maWdQcm90by5DbGllbnRGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkNsaWVudENvbmZpZ1Byb3RvLkNsaWVudEZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5DbGllbnRDb25maWdQcm90by5DbGllbnRGaWxlR3JvdXAuU3RhdHVzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZUdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZzsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TY2hlZHVsZWRFeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0ludGVnZXI7CitpbXBvcnQgb3JnLmp1bml0LkFmdGVyOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworCitAUnVuV2l0aChBbmRyb2lkSlVuaXQ0LmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIEltcG9ydEZpbGVzSW50ZWdyYXRpb25UZXN0IHsKKworICBAUnVsZSBwdWJsaWMgZmluYWwgTW9ja2l0b1J1bGUgbW9ja3MgPSBNb2NraXRvSlVuaXQucnVsZSgpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiSW1wb3J0RmlsZXNJbnRlZ3JhdGlvblRlc3QiOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBURVNUX0RBVEFfQUJTT0xVVEVfUEFUSCA9CisgICAgICBFbnZpcm9ubWVudC5nZXRFeHRlcm5hbFN0b3JhZ2VEaXJlY3RvcnkoKQorICAgICAgICAgICsgIi9nb29nbGV0ZXN0L3Rlc3RfcnVuZmlsZXMvZ29vZ2xlMy90aGlyZF9wYXJ0eS9qYXZhX3NyYy9hbmRyb2lkX2xpYnMvbW9iaWxlZGF0YWRvd25sb2FkL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0ZGF0YS8iOworCisgIC8vIE5vdGU6IENvbnRyb2wgRXhlY3V0b3IgbXVzdCBub3QgYmUgYSBzaW5nbGUgdGhyZWFkIGV4ZWN1dG9yLgorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2UgQ09OVFJPTF9FWEVDVVRPUiA9CisgICAgICBNb3JlRXhlY3V0b3JzLmxpc3RlbmluZ0RlY29yYXRvcihFeGVjdXRvcnMubmV3Q2FjaGVkVGhyZWFkUG9vbCgpKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIERPV05MT0FEX0VYRUNVVE9SID0KKyAgICAgIEV4ZWN1dG9ycy5uZXdTY2hlZHVsZWRUaHJlYWRQb29sKDIpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0lEXzEgPSAidGVzdC1maWxlLTEiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVcmkgRklMRV9VUklfMSA9CisgICAgICBVcmkucGFyc2UoCisgICAgICAgICAgRmlsZVVyaS5idWlsZGVyKCkuc2V0UGF0aChURVNUX0RBVEFfQUJTT0xVVEVfUEFUSCArICJvZHdzMV9lbXB0eSIpLmJ1aWxkKCkudG9TdHJpbmcoKSk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0NIRUNLU1VNXzEgPSAiYTFjYmE5ZDg3YjE0NDBmNDFjZTllN2RhMzhjNDNlMWY2YmQ3ZDVkZiI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX1VSTF8xID0gImlubGluZWZpbGU6c2hhMToiICsgRklMRV9DSEVDS1NVTV8xOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRklMRV9TSVpFXzEgPSA1NTQ7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIERhdGFGaWxlIElOTElORV9EQVRBX0ZJTEVfMSA9CisgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAuc2V0RmlsZUlkKEZJTEVfSURfMSkKKyAgICAgICAgICAuc2V0Qnl0ZVNpemUoRklMRV9TSVpFXzEpCisgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoRklMRV9VUkxfMSkKKyAgICAgICAgICAuc2V0Q2hlY2tzdW0oRklMRV9DSEVDS1NVTV8xKQorICAgICAgICAgIC5idWlsZCgpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0lEXzIgPSAidGVzdC1maWxlLTIiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVcmkgRklMRV9VUklfMiA9CisgICAgICBVcmkucGFyc2UoCisgICAgICAgICAgRmlsZVVyaS5idWlsZGVyKCkKKyAgICAgICAgICAgICAgLnNldFBhdGgoVEVTVF9EQVRBX0FCU09MVVRFX1BBVEggKyAiemlwX3Rlc3RfZm9sZGVyLnppcCIpCisgICAgICAgICAgICAgIC5idWlsZCgpCisgICAgICAgICAgICAgIC50b1N0cmluZygpKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfQ0hFQ0tTVU1fMiA9ICI3MDI0YjZiY2RkZjJiMjg5NzY1NmU5MzUzZjdmYzcxNWRmNWVhOTg2IjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfVVJMXzIgPSAiaW5saW5lZmlsZTpzaGEyOiIgKyBGSUxFX0NIRUNLU1VNXzI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGSUxFX1NJWkVfMiA9IDM3MzsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRGF0YUZpbGUgSU5MSU5FX0RBVEFfRklMRV8yID0KKyAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgIC5zZXRGaWxlSWQoRklMRV9JRF8yKQorICAgICAgICAgIC5zZXRCeXRlU2l6ZShGSUxFX1NJWkVfMikKKyAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChGSUxFX1VSTF8yKQorICAgICAgICAgIC5zZXRDaGVja3N1bShGSUxFX0NIRUNLU1VNXzIpCisgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29udGV4dCBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKworICBATW9jayBwcml2YXRlIFRhc2tTY2hlZHVsZXIgbW9ja1Rhc2tTY2hlZHVsZXI7CisgIEBNb2NrIHByaXZhdGUgTmV0d29ya1VzYWdlTW9uaXRvciBtb2NrTmV0d29ya1VzYWdlTW9uaXRvcjsKKyAgQE1vY2sgcHJpdmF0ZSBEb3dubG9hZFByb2dyZXNzTW9uaXRvciBtb2NrRG93bmxvYWRQcm9ncmVzc01vbml0b3I7CisKKyAgcHJpdmF0ZSBGYWtlRmlsZUJhY2tlbmQgZmFrZUZpbGVCYWNrZW5kOworICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2U7CisgIHByaXZhdGUgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IG11bHRpU2NoZW1lRmlsZURvd25sb2FkZXJTdXBwbGllcjsKKyAgcHJpdmF0ZSBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkOworCisgIHByaXZhdGUgRmlsZVNvdXJjZSBpbmxpbmVGaWxlU291cmNlMTsKKyAgcHJpdmF0ZSBGaWxlU291cmNlIGlubGluZUZpbGVTb3VyY2UyOworCisgIHByaXZhdGUgZmluYWwgVGVzdEZsYWdzIGZsYWdzID0gbmV3IFRlc3RGbGFncygpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgIGZha2VGaWxlQmFja2VuZCA9IG5ldyBGYWtlRmlsZUJhY2tlbmQoQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuYnVpbGQoKSk7CisgICAgZmlsZVN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIC8qIGJhY2tlbmRzPSAqLyBJbW11dGFibGVMaXN0Lm9mKGZha2VGaWxlQmFja2VuZCwgbmV3IEphdmFGaWxlQmFja2VuZCgpKSwKKyAgICAgICAgICAgIC8qIHRyYW5zZm9ybXM9ICovIEltbXV0YWJsZUxpc3Qub2YobmV3IENvbXByZXNzVHJhbnNmb3JtKCkpLAorICAgICAgICAgICAgLyogbW9uaXRvcnM9ICovIEltbXV0YWJsZUxpc3Qub2YobW9ja05ldHdvcmtVc2FnZU1vbml0b3IsIG1vY2tEb3dubG9hZFByb2dyZXNzTW9uaXRvcikpOworCisgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGZpbGVEb3dubG9hZGVyU3VwcGxpZXIgPQorICAgICAgICAoKSAtPgorICAgICAgICAgICAgQmFzZUZpbGVEb3dubG9hZGVyTW9kdWxlLmNyZWF0ZU9mZnJvYWQyRmlsZURvd25sb2FkZXIoCisgICAgICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgICAgICBET1dOTE9BRF9FWEVDVVRPUiwKKyAgICAgICAgICAgICAgICBDT05UUk9MX0VYRUNVVE9SLAorICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgICAgIG5ldyBTaGFyZWRQcmVmZXJlbmNlc0Rvd25sb2FkTWV0YWRhdGEoCisgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoImRvd25sb2FkbWV0YWRhdGEiLCAwKSwgQ09OVFJPTF9FWEVDVVRPUiksCisgICAgICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKSwKKyAgICAgICAgICAgICAgICAvKiB1cmxFbmdpbmVPcHRpb25hbD0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgLyogZXhjZXB0aW9uSGFuZGxlck9wdGlvbmFsPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgICAvKiBhdXRoVG9rZW5Qcm92aWRlck9wdGlvbmFsPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgICAvKiB0cmFmZmljVGFnPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgICBmbGFncyk7CisKKyAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gaW5saW5lRmlsZURvd25sb2FkZXJTdXBwbGllciA9CisgICAgICAgICgpIC0+IG5ldyBJbmxpbmVGaWxlRG93bmxvYWRlcihmaWxlU3RvcmFnZSwgRE9XTkxPQURfRVhFQ1VUT1IpOworICAgIG11bHRpU2NoZW1lRmlsZURvd25sb2FkZXJTdXBwbGllciA9CisgICAgICAgICgpIC0+CisgICAgICAgICAgICBNdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5hZGRTY2hlbWUoImh0dHBzIiwgZmlsZURvd25sb2FkZXJTdXBwbGllci5nZXQoKSkKKyAgICAgICAgICAgICAgICAuYWRkU2NoZW1lKCJpbmxpbmVmaWxlIiwgaW5saW5lRmlsZURvd25sb2FkZXJTdXBwbGllci5nZXQoKSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIFNldCB1cCBpbmxpbmUgZmlsZSBzb3VyY2VzCisgICAgdHJ5IChJbnB1dFN0cmVhbSBmaWxlU3RyZWFtMSA9IGZpbGVTdG9yYWdlLm9wZW4oRklMRV9VUklfMSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSk7CisgICAgICAgIElucHV0U3RyZWFtIGZpbGVTdHJlYW0yID0gZmlsZVN0b3JhZ2Uub3BlbihGSUxFX1VSSV8yLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgaW5saW5lRmlsZVNvdXJjZTEgPSBGaWxlU291cmNlLm9mQnl0ZVN0cmluZyhCeXRlU3RyaW5nLnJlYWRGcm9tKGZpbGVTdHJlYW0xKSk7CisgICAgICBpbmxpbmVGaWxlU291cmNlMiA9IEZpbGVTb3VyY2Uub2ZCeXRlU3RyaW5nKEJ5dGVTdHJpbmcucmVhZEZyb20oZmlsZVN0cmVhbTIpKTsKKyAgICB9CisgIH0KKworICBAQWZ0ZXIKKyAgcHVibGljIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDbGVhciBmaWxlIGdyb3VwIHRvIGVuc3VyZSB0aGVyZSBpcyBub3QgY3Jvc3MtdGVzdCBwb2xsaW5hdGlvbgorICAgIG1vYmlsZURhdGFEb3dubG9hZC5jbGVhcigpLmdldCgpOworICAgIC8vIFJlc2V0IGZha2UgZmlsZSBiYWNrZW5kCisgICAgZmFrZUZpbGVCYWNrZW5kLmNsZWFyRmFpbHVyZShPcGVyYXRpb25UeXBlLkFMTCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbXBvcnRGaWxlc19wZXJmb3Jtc0ltcG9ydCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGNyZWF0ZU1vYmlsZURhdGFEb3dubG9hZChtdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyU3VwcGxpZXIpOworCisgICAgRGF0YUZpbGVHcm91cCBmaWxlR3JvdXBXaXRoSW5saW5lRmlsZSA9CisgICAgICAgIERhdGFGaWxlR3JvdXAubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkKKyAgICAgICAgICAgIC5hZGRGaWxlKElOTElORV9EQVRBX0ZJTEVfMSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gRW5zdXJlIHRoYXQgd2UgYWRkIHRoZSBmaWxlIGdyb3VwIHN1Y2Nlc3NmdWxseQorICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgICAgICAuYWRkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgLnNldERhdGFGaWxlR3JvdXAoZmlsZUdyb3VwV2l0aElubGluZUZpbGUpCisgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKworICAgIC8vIFBlcmZvcm0gdGhlIGltcG9ydAorICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAuaW1wb3J0RmlsZXMoCisgICAgICAgICAgICBJbXBvcnRGaWxlc1JlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAgICAgLnNldEJ1aWxkSWQoZmlsZUdyb3VwV2l0aElubGluZUZpbGUuZ2V0QnVpbGRJZCgpKQorICAgICAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoZmlsZUdyb3VwV2l0aElubGluZUZpbGUuZ2V0VmFyaWFudElkKCkpCisgICAgICAgICAgICAgICAgLnNldElubGluZUZpbGVNYXAoSW1tdXRhYmxlTWFwLm9mKEZJTEVfSURfMSwgaW5saW5lRmlsZVNvdXJjZTEpKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuZ2V0KCk7CisKKyAgICAvLyBBc3NlcnQgdGhhdCB0aGUgcmVzdWx0aW5nIGdyb3VwIGlzIGRvd25sb2FkZWQgYW5kIGNvbnRhaW5zIGEgcmVmZXJlbmNlIHRvIG9uIGRldmljZSBmaWxlCisgICAgQ2xpZW50RmlsZUdyb3VwIGltcG9ydFJlc3VsdCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cChHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChpbXBvcnRSZXN1bHQpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0LmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FKTsKKyAgICBhc3NlcnRUaGF0KGltcG9ydFJlc3VsdC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0LmdldFN0YXR1cygpKS5pc0VxdWFsVG8oU3RhdHVzLkRPV05MT0FERUQpOworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0LmdldEZpbGUoMCkuZ2V0RmlsZVVyaSgpKS5pc05vdEVtcHR5KCk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhVcmkucGFyc2UoaW1wb3J0UmVzdWx0LmdldEZpbGUoMCkuZ2V0RmlsZVVyaSgpKSkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW1wb3J0RmlsZXNfd2hlbkltcG9ydGluZ011bHRpcGxlRmlsZXNfcGVyZm9ybXNJbXBvcnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjcmVhdGVNb2JpbGVEYXRhRG93bmxvYWQobXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlclN1cHBsaWVyKTsKKworICAgIERhdGFGaWxlR3JvdXAgZmlsZUdyb3VwV2l0aElubGluZUZpbGUgPQorICAgICAgICBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAuYWRkRmlsZShJTkxJTkVfREFUQV9GSUxFXzEpCisgICAgICAgICAgICAuYWRkRmlsZShJTkxJTkVfREFUQV9GSUxFXzIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIEVuc3VyZSB0aGF0IHdlIGFkZCB0aGUgZmlsZSBncm91cCBzdWNjZXNzZnVsbHkKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREYXRhRmlsZUdyb3VwKGZpbGVHcm91cFdpdGhJbmxpbmVGaWxlKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisKKyAgICAvLyBQZXJmb3JtIHRoZSBpbXBvcnQKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmltcG9ydEZpbGVzKAorICAgICAgICAgICAgSW1wb3J0RmlsZXNSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FKQorICAgICAgICAgICAgICAgIC5zZXRCdWlsZElkKGZpbGVHcm91cFdpdGhJbmxpbmVGaWxlLmdldEJ1aWxkSWQoKSkKKyAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkKGZpbGVHcm91cFdpdGhJbmxpbmVGaWxlLmdldFZhcmlhbnRJZCgpKQorICAgICAgICAgICAgICAgIC5zZXRJbmxpbmVGaWxlTWFwKAorICAgICAgICAgICAgICAgICAgICBJbW11dGFibGVNYXAub2YoRklMRV9JRF8xLCBpbmxpbmVGaWxlU291cmNlMSwgRklMRV9JRF8yLCBpbmxpbmVGaWxlU291cmNlMikpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIEFzc2VydCB0aGF0IHRoZSByZXN1bHRpbmcgZ3JvdXAgaXMgZG93bmxvYWRlZCBhbmQgY29udGFpbnMgYSByZWZlcmVuY2UgdG8gb24gZGV2aWNlIGZpbGUKKyAgICBDbGllbnRGaWxlR3JvdXAgaW1wb3J0UmVzdWx0ID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KGltcG9ydFJlc3VsdCkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChpbXBvcnRSZXN1bHQuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUUpOworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0LmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMik7CisgICAgYXNzZXJ0VGhhdChpbXBvcnRSZXN1bHQuZ2V0U3RhdHVzKCkpLmlzRXF1YWxUbyhTdGF0dXMuRE9XTkxPQURFRCk7CisgICAgYXNzZXJ0VGhhdChpbXBvcnRSZXN1bHQuZ2V0RmlsZSgwKS5nZXRGaWxlVXJpKCkpLmlzTm90RW1wdHkoKTsKKyAgICBhc3NlcnRUaGF0KGltcG9ydFJlc3VsdC5nZXRGaWxlKDEpLmdldEZpbGVVcmkoKSkuaXNOb3RFbXB0eSgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMoVXJpLnBhcnNlKGltcG9ydFJlc3VsdC5nZXRGaWxlKDApLmdldEZpbGVVcmkoKSkpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhVcmkucGFyc2UoaW1wb3J0UmVzdWx0LmdldEZpbGUoMSkuZ2V0RmlsZVVyaSgpKSkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW1wb3J0RmlsZXNfc3VwcG9ydHNNdWx0aXBsZUNhbGxzQ29uY3VycmVudGx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVXNlIEJsb2NraW5nRmlsZURvd25sb2FkZXIgdG8gZW5zdXJlIGJvdGggaW1wb3J0cyBzdGFydCBhcm91bmQgdGhlIHNhbWUgdGltZS4KKyAgICBBdG9taWNJbnRlZ2VyIGZpbGVEb3dubG9hZGVySW52b2NhdGlvbkNvdW50ID0gbmV3IEF0b21pY0ludGVnZXIoMCk7CisgICAgQmxvY2tpbmdGaWxlRG93bmxvYWRlciBibG9ja2luZ0ZpbGVEb3dubG9hZGVyID0KKyAgICAgICAgbmV3IEJsb2NraW5nRmlsZURvd25sb2FkZXIoCisgICAgICAgICAgICBNb3JlRXhlY3V0b3JzLmxpc3RlbmluZ0RlY29yYXRvcihET1dOTE9BRF9FWEVDVVRPUiksCisgICAgICAgICAgICBuZXcgRmlsZURvd25sb2FkZXIoKSB7CisgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBzdGFydERvd25sb2FkaW5nKERvd25sb2FkUmVxdWVzdCByZXF1ZXN0KSB7CisgICAgICAgICAgICAgICAgZmlsZURvd25sb2FkZXJJbnZvY2F0aW9uQ291bnQuYWRkQW5kR2V0KDEpOworICAgICAgICAgICAgICAgIHJldHVybiBtdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyU3VwcGxpZXIuZ2V0KCkuc3RhcnREb3dubG9hZGluZyhyZXF1ZXN0KTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSk7CisgICAgY3JlYXRlTW9iaWxlRGF0YURvd25sb2FkKCgpIC0+IGJsb2NraW5nRmlsZURvd25sb2FkZXIpOworCisgICAgRGF0YUZpbGVHcm91cCBmaWxlR3JvdXAxV2l0aElubGluZUZpbGUgPQorICAgICAgICBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAuYWRkRmlsZShJTkxJTkVfREFUQV9GSUxFXzEpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlR3JvdXAgZmlsZUdyb3VwMldpdGhJbmxpbmVGaWxlID0KKyAgICAgICAgRGF0YUZpbGVHcm91cC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FICsgIjIiKQorICAgICAgICAgICAgLmFkZEZpbGUoSU5MSU5FX0RBVEFfRklMRV8yKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBFbnN1cmUgdGhhdCB3ZSBhZGQgdGhlIGZpbGUgZ3JvdXBzIHN1Y2Nlc3NmdWxseQorICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgICAgICAuYWRkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgLnNldERhdGFGaWxlR3JvdXAoZmlsZUdyb3VwMVdpdGhJbmxpbmVGaWxlKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RGF0YUZpbGVHcm91cChmaWxlR3JvdXAyV2l0aElubGluZUZpbGUpCisgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKworICAgIC8vIFBlcmZvcm0gdGhlIGltcG9ydHMKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGltcG9ydEZ1dHVyZTEgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuaW1wb3J0RmlsZXMoCisgICAgICAgICAgICBJbXBvcnRGaWxlc1JlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAgICAgLnNldEJ1aWxkSWQoZmlsZUdyb3VwMVdpdGhJbmxpbmVGaWxlLmdldEJ1aWxkSWQoKSkKKyAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkKGZpbGVHcm91cDFXaXRoSW5saW5lRmlsZS5nZXRWYXJpYW50SWQoKSkKKyAgICAgICAgICAgICAgICAuc2V0SW5saW5lRmlsZU1hcChJbW11dGFibGVNYXAub2YoRklMRV9JRF8xLCBpbmxpbmVGaWxlU291cmNlMSkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBpbXBvcnRGdXR1cmUyID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmltcG9ydEZpbGVzKAorICAgICAgICAgICAgSW1wb3J0RmlsZXNSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FICsgIjIiKQorICAgICAgICAgICAgICAgIC5zZXRCdWlsZElkKGZpbGVHcm91cDJXaXRoSW5saW5lRmlsZS5nZXRCdWlsZElkKCkpCisgICAgICAgICAgICAgICAgLnNldFZhcmlhbnRJZChmaWxlR3JvdXAyV2l0aElubGluZUZpbGUuZ2V0VmFyaWFudElkKCkpCisgICAgICAgICAgICAgICAgLnNldElubGluZUZpbGVNYXAoSW1tdXRhYmxlTWFwLm9mKEZJTEVfSURfMiwgaW5saW5lRmlsZVNvdXJjZTIpKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKworICAgIC8vIGJsb2NraW5nIGZpbGUgZG93bmxvYWRlciBzaG91bGQgYmUgd2FpdGluZyBvbiB0aGUgaW1wb3J0cywgYmxvY2sgdGhlIHRlc3QgdG8gZW5zdXJlIGJvdGgKKyAgICAvLyBpbXBvcnRzIGhhdmUgc3RhcnRlZC4KKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLndhaXRGb3JEb3dubG9hZFN0YXJ0ZWQoKTsKKworICAgIC8vIHVuYmxvY2sgdGhlIGltcG9ydHMgc28gYm90aCBoYXBwZW4gY29uY3VycmVudGx5LgorICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIuZmluaXNoRG93bmxvYWRpbmcoKTsKKworICAgIC8vIFdhaXQgZm9yIGJvdGggZnV0dXJlcyB0byBjb21wbGV0ZQorICAgIEZ1dHVyZXMud2hlbkFsbFN1Y2NlZWQoaW1wb3J0RnV0dXJlMSwgaW1wb3J0RnV0dXJlMikuY2FsbCgoKSAtPiBudWxsLCBDT05UUk9MX0VYRUNVVE9SKS5nZXQoKTsKKworICAgIC8vIEFzc2VydCB0aGF0IHRoZSByZXN1bHRpbmcgZ3JvdXAgaXMgZG93bmxvYWRlZCBhbmQgY29udGFpbnMgYSByZWZlcmVuY2UgdG8gb24gZGV2aWNlIGZpbGUKKyAgICBDbGllbnRGaWxlR3JvdXAgaW1wb3J0UmVzdWx0MSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cChHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworICAgIENsaWVudEZpbGVHcm91cCBpbXBvcnRSZXN1bHQyID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKAorICAgICAgICAgICAgICAgIEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUgKyAiMiIpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KGltcG9ydFJlc3VsdDEpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0MS5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0MS5nZXRTdGF0dXMoKSkuaXNFcXVhbFRvKFN0YXR1cy5ET1dOTE9BREVEKTsKKyAgICBhc3NlcnRUaGF0KGltcG9ydFJlc3VsdDEuZ2V0RmlsZSgwKS5nZXRGaWxlVXJpKCkpLmlzTm90RW1wdHkoKTsKKworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0MikuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChpbXBvcnRSZXN1bHQyLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisgICAgYXNzZXJ0VGhhdChpbXBvcnRSZXN1bHQyLmdldFN0YXR1cygpKS5pc0VxdWFsVG8oU3RhdHVzLkRPV05MT0FERUQpOworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0Mi5nZXRGaWxlKDApLmdldEZpbGVVcmkoKSkuaXNOb3RFbXB0eSgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMoVXJpLnBhcnNlKGltcG9ydFJlc3VsdDEuZ2V0RmlsZSgwKS5nZXRGaWxlVXJpKCkpKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMoVXJpLnBhcnNlKGltcG9ydFJlc3VsdDIuZ2V0RmlsZSgwKS5nZXRGaWxlVXJpKCkpKSkuaXNUcnVlKCk7CisKKyAgICAvLyBhc3NlcnQgdGhhdCBmaWxlIGRvd25sb2FkZXIgd2FzIGNhbGxlZCAyIHRpbWVzLCAxIGZvciBlYWNoIGltcG9ydC4KKyAgICBhc3NlcnRUaGF0KGZpbGVEb3dubG9hZGVySW52b2NhdGlvbkNvdW50LmdldCgpKS5pc0VxdWFsVG8oMik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbXBvcnRGaWxlc193aGVuTmV3SW5saW5lRmlsZVNwZWNpZmllZF9pbXBvcnRzQW5kU3RvcmVzRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGNyZWF0ZU1vYmlsZURhdGFEb3dubG9hZChtdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyU3VwcGxpZXIpOworCisgICAgRGF0YUZpbGVHcm91cCBmaWxlR3JvdXBXaXRoT25lSW5saW5lRmlsZSA9CisgICAgICAgIERhdGFGaWxlR3JvdXAubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkKKyAgICAgICAgICAgIC5hZGRGaWxlKElOTElORV9EQVRBX0ZJTEVfMSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEltbXV0YWJsZUxpc3Q8RGF0YUZpbGU+IHVwZGF0ZWREYXRhRmlsZUxpc3QgPSBJbW11dGFibGVMaXN0Lm9mKElOTElORV9EQVRBX0ZJTEVfMik7CisKKyAgICAvLyBFbnN1cmUgdGhhdCB3ZSBhZGQgdGhlIGZpbGUgZ3JvdXAgc3VjY2Vzc2Z1bGx5CisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RGF0YUZpbGVHcm91cChmaWxlR3JvdXBXaXRoT25lSW5saW5lRmlsZSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmlzVHJ1ZSgpOworCisgICAgLy8gUGVyZm9ybSB0aGUgaW1wb3J0CisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5pbXBvcnRGaWxlcygKKyAgICAgICAgICAgIEltcG9ydEZpbGVzUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkKKyAgICAgICAgICAgICAgICAuc2V0QnVpbGRJZChmaWxlR3JvdXBXaXRoT25lSW5saW5lRmlsZS5nZXRCdWlsZElkKCkpCisgICAgICAgICAgICAgICAgLnNldFZhcmlhbnRJZChmaWxlR3JvdXBXaXRoT25lSW5saW5lRmlsZS5nZXRWYXJpYW50SWQoKSkKKyAgICAgICAgICAgICAgICAuc2V0VXBkYXRlZERhdGFGaWxlTGlzdCh1cGRhdGVkRGF0YUZpbGVMaXN0KQorICAgICAgICAgICAgICAgIC5zZXRJbmxpbmVGaWxlTWFwKAorICAgICAgICAgICAgICAgICAgICBJbW11dGFibGVNYXAub2YoRklMRV9JRF8xLCBpbmxpbmVGaWxlU291cmNlMSwgRklMRV9JRF8yLCBpbmxpbmVGaWxlU291cmNlMikpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIEFzc2VydCB0aGF0IHRoZSByZXN1bHRpbmcgZ3JvdXAgaXMgZG93bmxvYWRlZCBhbmQgY29udGFpbnMgYm90aCBmaWxlcworICAgIENsaWVudEZpbGVHcm91cCBpbXBvcnRSZXN1bHQgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgIC5nZXRGaWxlR3JvdXAoR2V0RmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0LmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FKTsKKyAgICBhc3NlcnRUaGF0KGltcG9ydFJlc3VsdC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDIpOworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0LmdldFN0YXR1cygpKS5pc0VxdWFsVG8oU3RhdHVzLkRPV05MT0FERUQpOworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0LmdldEZpbGVMaXN0KCkpCisgICAgICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKENvcnJlc3BvbmRlbmNlLnRyYW5zZm9ybWluZyhDbGllbnRGaWxlOjpnZXRGaWxlSWQsICJ1c2luZyBmaWxlIGlkIikpCisgICAgICAgIC5jb250YWluc0V4YWN0bHkoRklMRV9JRF8xLCBGSUxFX0lEXzIpOworICAgIGFzc2VydFRoYXQoaW1wb3J0UmVzdWx0LmdldEZpbGUoMCkuZ2V0RmlsZVVyaSgpKS5pc05vdEVtcHR5KCk7CisgICAgYXNzZXJ0VGhhdChpbXBvcnRSZXN1bHQuZ2V0RmlsZSgxKS5nZXRGaWxlVXJpKCkpLmlzTm90RW1wdHkoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGltcG9ydEZpbGVzX3doZW5OZXdJbmxpbmVGaWxlQWRkZWRUb1BlbmRpbmdHcm91cF9pbXBvcnRzQW5kU3RvcmVzRmlsZSgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjcmVhdGVNb2JpbGVEYXRhRG93bmxvYWQobXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlclN1cHBsaWVyKTsKKworICAgIERhdGFGaWxlR3JvdXAgZmlsZUdyb3VwV2l0aFN0YW5kYXJkRmlsZSA9CisgICAgICAgIERhdGFGaWxlR3JvdXAubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkKKyAgICAgICAgICAgIC5hZGRGaWxlKAorICAgICAgICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKEZJTEVfSUQpCisgICAgICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oRklMRV9DSEVDS1NVTSkKKyAgICAgICAgICAgICAgICAgICAgLnNldEJ5dGVTaXplKEZJTEVfU0laRSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBJbW11dGFibGVMaXN0PERhdGFGaWxlPiB1cGRhdGVkRGF0YUZpbGVMaXN0ID0gSW1tdXRhYmxlTGlzdC5vZihJTkxJTkVfREFUQV9GSUxFXzIpOworCisgICAgLy8gRW5zdXJlIHRoYXQgd2UgYWRkIHRoZSBmaWxlIGdyb3VwIHN1Y2Nlc3NmdWxseQorICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgICAgICAuYWRkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgLnNldERhdGFGaWxlR3JvdXAoZmlsZUdyb3VwV2l0aFN0YW5kYXJkRmlsZSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmlzVHJ1ZSgpOworCisgICAgLy8gUGVyZm9ybSB0aGUgaW1wb3J0CisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5pbXBvcnRGaWxlcygKKyAgICAgICAgICAgIEltcG9ydEZpbGVzUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkKKyAgICAgICAgICAgICAgICAuc2V0QnVpbGRJZChmaWxlR3JvdXBXaXRoU3RhbmRhcmRGaWxlLmdldEJ1aWxkSWQoKSkKKyAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkKGZpbGVHcm91cFdpdGhTdGFuZGFyZEZpbGUuZ2V0VmFyaWFudElkKCkpCisgICAgICAgICAgICAgICAgLnNldFVwZGF0ZWREYXRhRmlsZUxpc3QodXBkYXRlZERhdGFGaWxlTGlzdCkKKyAgICAgICAgICAgICAgICAuc2V0SW5saW5lRmlsZU1hcChJbW11dGFibGVNYXAub2YoRklMRV9JRF8yLCBpbmxpbmVGaWxlU291cmNlMikpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIEFzc2VydCB0aGF0IHRoZSBmaWxlIGlzIHBlbmRpbmcgKGRvZXMgbm90IHJldHVybiBmcm9tIGdldEZpbGVHcm91cCkKKyAgICBDbGllbnRGaWxlR3JvdXAgZ2V0RmlsZUdyb3VwUmVzdWx0ID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChnZXRGaWxlR3JvdXBSZXN1bHQpLmlzTnVsbCgpOworCisgICAgLy8gVXNlIGdldEZpbGVHcm91cHNCeUZpbHRlciB0byBnZXQgdGhlIGZpbGUgZ3JvdXAKKyAgICBJbW11dGFibGVMaXN0PENsaWVudEZpbGVHcm91cD4gYWxsRmlsZUdyb3VwcyA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cHNCeUZpbHRlcigKKyAgICAgICAgICAgICAgICBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lT3B0aW9uYWwoT3B0aW9uYWwub2YoRklMRV9HUk9VUF9OQU1FKSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisKKyAgICAvLyBHZXRGaWxlR3JvdXBzQnlGaWx0ZXIgcmV0dXJucyBib3RoIGRvd25sb2FkZWQgYW5kIHBlbmRpbmcsIHNvIGZpbmQgdGhlIHBlbmRpbmcgZ3JvdXAuCisgICAgQ2xpZW50RmlsZUdyb3VwIHBlbmRpbmdJbmxpbmVHcm91cCA9IG51bGw7CisgICAgZm9yIChDbGllbnRGaWxlR3JvdXAgZ3JvdXAgOiBhbGxGaWxlR3JvdXBzKSB7CisgICAgICBpZiAoZ3JvdXAuZ2V0U3RhdHVzKCkuZXF1YWxzKFN0YXR1cy5QRU5ESU5HKSkgeworICAgICAgICBwZW5kaW5nSW5saW5lR3JvdXAgPSBncm91cDsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorCisgICAgLy8gQXNzZXJ0IHRoYXQgdGhlIHJlc3VsdGluZyBncm91cCBpcyBwZW5kaW5nIGFuZCBidXQgY29udGFpbnMgaW1wb3J0ZWQgZmlsZQorICAgIGFzc2VydFRoYXQocGVuZGluZ0lubGluZUdyb3VwKS5pc05vdE51bGwoKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdJbmxpbmVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRSk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nSW5saW5lR3JvdXAuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygyKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdJbmxpbmVHcm91cC5nZXRTdGF0dXMoKSkuaXNFcXVhbFRvKFN0YXR1cy5QRU5ESU5HKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdJbmxpbmVHcm91cC5nZXRGaWxlTGlzdCgpKQorICAgICAgICAuY29tcGFyaW5nRWxlbWVudHNVc2luZyhDb3JyZXNwb25kZW5jZS50cmFuc2Zvcm1pbmcoQ2xpZW50RmlsZTo6Z2V0RmlsZUlkLCAidXNpbmcgZmlsZSBpZCIpKQorICAgICAgICAuY29udGFpbnNFeGFjdGx5KEZJTEVfSUQsIEZJTEVfSURfMik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbXBvcnRGaWxlc190b05vbkV4aXN0ZW50RGF0YUZpbGVHcm91cF9mYWlscygpIHRocm93cyBFeGNlcHRpb24geworICAgIGNyZWF0ZU1vYmlsZURhdGFEb3dubG9hZChtdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyU3VwcGxpZXIpOworCisgICAgRmlsZVNvdXJjZSBpbmxpbmVGaWxlU291cmNlID0gRmlsZVNvdXJjZS5vZkJ5dGVTdHJpbmcoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoIlRFU1RfQ09OVEVOVCIpKTsKKworICAgIC8vIFBlcmZvcm0gdGhlIGltcG9ydAorICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgICAgIC5pbXBvcnRGaWxlcygKKyAgICAgICAgICAgICAgICAgICAgICAgIEltcG9ydEZpbGVzUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0QnVpbGRJZCgwKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoIiIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldElubGluZUZpbGVNYXAoSW1tdXRhYmxlTWFwLm9mKEZJTEVfSURfMSwgaW5saW5lRmlsZVNvdXJjZSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoKSk7CisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkZXggPSAoRG93bmxvYWRFeGNlcHRpb24pIGV4LmdldENhdXNlKCk7CisgICAgYXNzZXJ0VGhhdChkZXguZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuR1JPVVBfTk9UX0ZPVU5EX0VSUk9SKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGltcG9ydEZpbGVzX3doZW5NaXNtYXRjaGVkVmVyc2lvbl9mYWlsVG9JbXBvcnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjcmVhdGVNb2JpbGVEYXRhRG93bmxvYWQobXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlclN1cHBsaWVyKTsKKworICAgIERhdGFGaWxlR3JvdXAgZmlsZUdyb3VwV2l0aElubGluZUZpbGUgPQorICAgICAgICBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAuYWRkRmlsZShJTkxJTkVfREFUQV9GSUxFXzEpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIEVuc3VyZSB0aGF0IHdlIGFkZCB0aGUgZmlsZSBncm91cCBzdWNjZXNzZnVsbHkKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREYXRhRmlsZUdyb3VwKGZpbGVHcm91cFdpdGhJbmxpbmVGaWxlKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisKKyAgICAvLyBQZXJmb3JtIHRoZSBpbXBvcnQKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgICAgICAuaW1wb3J0RmlsZXMoCisgICAgICAgICAgICAgICAgICAgICAgICBJbXBvcnRGaWxlc1JlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldEJ1aWxkSWQoMTApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFZhcmlhbnRJZCgiIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0SW5saW5lRmlsZU1hcChJbW11dGFibGVNYXAub2YoRklMRV9JRF8xLCBpbmxpbmVGaWxlU291cmNlMSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoKSk7CisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkZXggPSAoRG93bmxvYWRFeGNlcHRpb24pIGV4LmdldENhdXNlKCk7CisgICAgYXNzZXJ0VGhhdChkZXguZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuR1JPVVBfTk9UX0ZPVU5EX0VSUk9SKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGltcG9ydEZpbGVzX3doZW5JbXBvcnRGYWlsc19kb2VzTm90V3JpdGVVcGRhdGVkTWV0YWRhdGEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjcmVhdGVNb2JpbGVEYXRhRG93bmxvYWQobXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlclN1cHBsaWVyKTsKKworICAgIC8vIENyZWF0ZSBpbml0aWFsIGZpbGUgZ3JvdXAgdG8gaW1wb3J0CisgICAgRGF0YUZpbGVHcm91cCBpbml0aWFsRmlsZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FKQorICAgICAgICAgICAgLmFkZEZpbGUoSU5MSU5FX0RBVEFfRklMRV8xKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBFbnN1cmUgdGhhdCB3ZSBhZGQgdGhlIGZpbGUgZ3JvdXAgc3VjY2Vzc2Z1bGx5CisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldERhdGFGaWxlR3JvdXAoaW5pdGlhbEZpbGVHcm91cCkuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKworICAgIC8vIFBlcmZvcm0gdGhlIGluaXRpYWwgaW1wb3J0CisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5pbXBvcnRGaWxlcygKKyAgICAgICAgICAgIEltcG9ydEZpbGVzUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkKKyAgICAgICAgICAgICAgICAuc2V0QnVpbGRJZChpbml0aWFsRmlsZUdyb3VwLmdldEJ1aWxkSWQoKSkKKyAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkKGluaXRpYWxGaWxlR3JvdXAuZ2V0VmFyaWFudElkKCkpCisgICAgICAgICAgICAgICAgLnNldElubGluZUZpbGVNYXAoSW1tdXRhYmxlTWFwLm9mKEZJTEVfSURfMSwgaW5saW5lRmlsZVNvdXJjZTEpKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuZ2V0KCk7CisKKyAgICAvLyBBc3NlcnQgdGhhdCB0aGUgcmVzdWx0aW5nIGdyb3VwIGlzIGRvd25sb2FkZWQgYW5kIGNvbnRhaW5zIGEgcmVmZXJlbmNlIHRvIG9uIGRldmljZSBmaWxlCisgICAgQ2xpZW50RmlsZUdyb3VwIGN1cnJlbnRGaWxlR3JvdXAgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgIC5nZXRGaWxlR3JvdXAoR2V0RmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIGFzc2VydFRoYXQoY3VycmVudEZpbGVHcm91cCkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChjdXJyZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FKTsKKyAgICBhc3NlcnRUaGF0KGN1cnJlbnRGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygxKTsKKyAgICBhc3NlcnRUaGF0KGN1cnJlbnRGaWxlR3JvdXAuZ2V0U3RhdHVzKCkpLmlzRXF1YWxUbyhTdGF0dXMuRE9XTkxPQURFRCk7CisgICAgYXNzZXJ0VGhhdChjdXJyZW50RmlsZUdyb3VwLmdldEZpbGUoMCkuZ2V0RmlsZVVyaSgpKS5pc05vdEVtcHR5KCk7CisKKyAgICAvLyBVc2UgZmFrZSBmaWxlIGJhY2tlbmQgdG8gaW52b2tlIGEgZmFpbHVyZSB3aGVuIGltcG9ydGluZyBhbm90aGVyIGZpbGUKKyAgICBmYWtlRmlsZUJhY2tlbmQuc2V0RmFpbHVyZShPcGVyYXRpb25UeXBlLldSSVRFX1NUUkVBTSwgbmV3IElPRXhjZXB0aW9uKCJ0ZXN0IGZhaWx1cmUiKSk7CisKKyAgICAvLyBBc3NlcnQgdGhhdCBpbXBvcnRGaWxlcyBmYWlscyBkdWUgdG8gZmFpbHVyZSBpbXBvcnRpbmcgZmlsZQorICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgICAgIC5pbXBvcnRGaWxlcygKKyAgICAgICAgICAgICAgICAgICAgICAgIEltcG9ydEZpbGVzUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0QnVpbGRJZChpbml0aWFsRmlsZUdyb3VwLmdldEJ1aWxkSWQoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkKGluaXRpYWxGaWxlR3JvdXAuZ2V0VmFyaWFudElkKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFVwZGF0ZWREYXRhRmlsZUxpc3QoSW1tdXRhYmxlTGlzdC5vZihJTkxJTkVfREFUQV9GSUxFXzIpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRJbmxpbmVGaWxlTWFwKEltbXV0YWJsZU1hcC5vZihGSUxFX0lEXzIsIGlubGluZUZpbGVTb3VyY2UyKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAgICAgLmdldCgpKTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoQWdncmVnYXRlRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBBZ2dyZWdhdGVFeGNlcHRpb24gYWV4ID0gKEFnZ3JlZ2F0ZUV4Y2VwdGlvbikgZXguZ2V0Q2F1c2UoKTsKKyAgICBhc3NlcnRUaGF0KGFleC5nZXRGYWlsdXJlcygpKS5oYXNTaXplKDEpOworICAgIGFzc2VydFRoYXQoYWV4LmdldEZhaWx1cmVzKCkuZ2V0KDApKS5pc0luc3RhbmNlT2YoRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIERvd25sb2FkRXhjZXB0aW9uIGRleCA9IChEb3dubG9hZEV4Y2VwdGlvbikgYWV4LmdldEZhaWx1cmVzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoZGV4LmdldERvd25sb2FkUmVzdWx0Q29kZSgpKS5pc0VxdWFsVG8oRG93bmxvYWRSZXN1bHRDb2RlLklOTElORV9GSUxFX0lPX0VSUk9SKTsKKworICAgIC8vIEdldCB0aGUgZmlsZSBncm91cCBhZ2FpbiBhZnRlciB0aGUgc2Vjb25kIGltcG9ydCBmYWlscworICAgIGN1cnJlbnRGaWxlR3JvdXAgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgIC5nZXRGaWxlR3JvdXAoR2V0RmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIC8vIEFzc2VydCB0aGF0IGZpbGUgZ3JvdXAgcmVtYWlucyB1bmNoYW5nZWQgKG5vIG1ldGFkYXRhIGNoYW5nZSkKKyAgICBhc3NlcnRUaGF0KGN1cnJlbnRGaWxlR3JvdXApLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoY3VycmVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRSk7CisgICAgYXNzZXJ0VGhhdChjdXJyZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisgICAgYXNzZXJ0VGhhdChjdXJyZW50RmlsZUdyb3VwLmdldFN0YXR1cygpKS5pc0VxdWFsVG8oU3RhdHVzLkRPV05MT0FERUQpOworICAgIGFzc2VydFRoYXQoY3VycmVudEZpbGVHcm91cC5nZXRGaWxlKDApLmdldEZpbGVVcmkoKSkuaXNOb3RFbXB0eSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW1wb3J0RmlsZXNfc3VwcG9ydHNEZWR1cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFVzZSBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIHRvIGJsb2NrIHRoZSBpbXBvcnQgb2YgYSBmaWxlIGluZGVmaW5pdGVseS4gVGhpcyBpcyB1c2VkIHRvIGVuc3VyZQorICAgIC8vIGEgZmlsZSBpbXBvcnQgaXMgaW4tcHJvZ3Jlc3MgYmVmb3JlIHN0YXJ0aW5nIGFub3RoZXIgaW1wb3J0CisgICAgQXRvbWljSW50ZWdlciBmaWxlRG93bmxvYWRlckludm9jYXRpb25Db3VudCA9IG5ldyBBdG9taWNJbnRlZ2VyKDApOworICAgIEJsb2NraW5nRmlsZURvd25sb2FkZXIgYmxvY2tpbmdGaWxlRG93bmxvYWRlciA9CisgICAgICAgIG5ldyBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgTW9yZUV4ZWN1dG9ycy5saXN0ZW5pbmdEZWNvcmF0b3IoRE9XTkxPQURfRVhFQ1VUT1IpLAorICAgICAgICAgICAgbmV3IEZpbGVEb3dubG9hZGVyKCkgeworICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gc3RhcnREb3dubG9hZGluZyhEb3dubG9hZFJlcXVlc3QgcmVxdWVzdCkgeworICAgICAgICAgICAgICAgIGZpbGVEb3dubG9hZGVySW52b2NhdGlvbkNvdW50LmFkZEFuZEdldCgxKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlclN1cHBsaWVyLmdldCgpLnN0YXJ0RG93bmxvYWRpbmcocmVxdWVzdCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworCisgICAgY3JlYXRlTW9iaWxlRGF0YURvd25sb2FkKCgpIC0+IGJsb2NraW5nRmlsZURvd25sb2FkZXIpOworCisgICAgRGF0YUZpbGVHcm91cCBmaWxlR3JvdXAxV2l0aElubGluZUZpbGUgPQorICAgICAgICBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAuYWRkRmlsZShJTkxJTkVfREFUQV9GSUxFXzEpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlR3JvdXAgZmlsZUdyb3VwMldpdGhJbmxpbmVGaWxlID0KKyAgICAgICAgRGF0YUZpbGVHcm91cC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FICsgIjIiKQorICAgICAgICAgICAgLmFkZEZpbGUoSU5MSU5FX0RBVEFfRklMRV8xKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBFbnN1cmUgdGhhdCB3ZSBhZGQgdGhlIGZpbGUgZ3JvdXBzIHN1Y2Nlc3NmdWxseQorICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgICAgICAuYWRkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgLnNldERhdGFGaWxlR3JvdXAoZmlsZUdyb3VwMVdpdGhJbmxpbmVGaWxlKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RGF0YUZpbGVHcm91cChmaWxlR3JvdXAyV2l0aElubGluZUZpbGUpCisgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKworICAgIC8vIFN0YXJ0IHRoZSBmaXJzdCBpbXBvcnQgYW5kIGtlZXAgaXQgaW4gcHJvZ3Jlc3MKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGltcG9ydEZpbGVzRnV0dXJlMSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5pbXBvcnRGaWxlcygKKyAgICAgICAgICAgIEltcG9ydEZpbGVzUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkKKyAgICAgICAgICAgICAgICAuc2V0QnVpbGRJZChmaWxlR3JvdXAxV2l0aElubGluZUZpbGUuZ2V0QnVpbGRJZCgpKQorICAgICAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoZmlsZUdyb3VwMVdpdGhJbmxpbmVGaWxlLmdldFZhcmlhbnRJZCgpKQorICAgICAgICAgICAgICAgIC5zZXRJbmxpbmVGaWxlTWFwKEltbXV0YWJsZU1hcC5vZihGSUxFX0lEXzEsIGlubGluZUZpbGVTb3VyY2UxKSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLndhaXRGb3JEb3dubG9hZFN0YXJ0ZWQoKTsKKworICAgIC8vIFN0YXJ0IHRoZSBzZWNvbmQgaW1wb3J0IGFmdGVyIHRoZSBmaXJzdCBpcyBhbHJlYWR5IGluLXByb2dyZXNzCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBpbXBvcnRGaWxlc0Z1dHVyZTIgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuaW1wb3J0RmlsZXMoCisgICAgICAgICAgICBJbXBvcnRGaWxlc1JlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUgKyAiMiIpCisgICAgICAgICAgICAgICAgLnNldEJ1aWxkSWQoZmlsZUdyb3VwMldpdGhJbmxpbmVGaWxlLmdldEJ1aWxkSWQoKSkKKyAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkKGZpbGVHcm91cDJXaXRoSW5saW5lRmlsZS5nZXRWYXJpYW50SWQoKSkKKyAgICAgICAgICAgICAgICAuc2V0SW5saW5lRmlsZU1hcChJbW11dGFibGVNYXAub2YoRklMRV9JRF8xLCBpbmxpbmVGaWxlU291cmNlMSkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworCisgICAgLy8gQWxsb3cgdGhlIGRvd25sb2FkIHRvIGNvbnRpbnVlIGFuZCB0cmlnZ2VyIG91ciBkZWxlZ2F0ZSBGaWxlRG93bmxvYWRlci4gSWYgdGhlIGZ1dHVyZSBpc24ndAorICAgIC8vIGNhbmNlbGxlZCwgdGhlIG9uU3VjY2VzcyBjYWxsYmFjayBzaG91bGQgZmFpbCB0aGUgdGVzdC4KKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLmZpbmlzaERvd25sb2FkaW5nKCk7CisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci53YWl0Rm9yRG93bmxvYWRDb21wbGV0ZWQoKTsKKworICAgIC8vIHdhaXQgZm9yIGltcG9ydEZpbGVzRnV0dXJlMiB0byBjb21wbGV0ZSwgY2hlY2sgdGhhdCBpbXBvcnRGaWxlczEgaXMgYWxzbyBjb21wbGV0ZQorICAgIGltcG9ydEZpbGVzRnV0dXJlMi5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGltcG9ydEZpbGVzRnV0dXJlMS5pc0RvbmUoKSkuaXNUcnVlKCk7CisKKyAgICAvLyBFbnN1cmUgdGhhdCBmaWxlIGRvd25sb2FkZXIgd2FzIG9ubHkgaW52b2tlZCBvbmNlCisgICAgYXNzZXJ0VGhhdChmaWxlRG93bmxvYWRlckludm9jYXRpb25Db3VudC5nZXQoKSkuaXNFcXVhbFRvKDEpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkLmNsZWFyKCkuZ2V0KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbXBvcnRGaWxlc19zdXBwb3J0c0NhbmNlbGxhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFVzZSBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIHRvIGJsb2NrIHRoZSBpbXBvcnQgb2YgYSBmaWxlIGluZGVmaW5pdGVseS4gQ2hlY2sgdGhhdCB0aGUgZnV0dXJlCisgICAgLy8gcmV0dXJuZWQgYnkgaW1wb3J0RmlsZXMgZmFpbHMgd2l0aCBhIGNhbmNlbGxhdGlvbiBleGNlcHRpb24KKyAgICBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIGJsb2NraW5nRmlsZURvd25sb2FkZXIgPQorICAgICAgICBuZXcgQmxvY2tpbmdGaWxlRG93bmxvYWRlcigKKyAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKERPV05MT0FEX0VYRUNVVE9SKSwKKyAgICAgICAgICAgIG5ldyBGaWxlRG93bmxvYWRlcigpIHsKKyAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHN0YXJ0RG93bmxvYWRpbmcoRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCkgeworICAgICAgICAgICAgICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gaW1wb3J0VGFza0Z1dHVyZSA9IEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICAgIEZ1dHVyZXMuYWRkQ2FsbGJhY2soCisgICAgICAgICAgICAgICAgICAgIGltcG9ydFRhc2tGdXR1cmUsCisgICAgICAgICAgICAgICAgICAgIG5ldyBGdXR1cmVDYWxsYmFjazxWb2lkPigpIHsKKyAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoVm9pZCByZXN1bHQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNob3VsZCBub3QgZ2V0IGhlcmUgc2luY2Ugd2Ugd2lsbCBjYW5jZWwgdGhlIGZ1dHVyZS4KKyAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoKTsKKyAgICAgICAgICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkZhaWx1cmUoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV2ZW4gdGhvdWdoIGltcG9ydFRhc2tGdXR1cmUgd2FzIGp1c3QgY3JlYXRlZCwgdGhpcyBtZXRob2Qgc2hvdWxkIGJlCisgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnZva2VkIGluIHRoZSBmdXR1cmUgY2hhaW4gdGhhdCBnZXRzIGNhbmNlbGxlZCAtLSBFbnN1cmUgdGhhdCB0aGUKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbmNlbGxhdGlvbiBwcm9wYWdhdGVzIHRvIHRoaXMgZnV0dXJlLgorICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VGhhdChpbXBvcnRUYXNrRnV0dXJlLmlzQ2FuY2VsbGVkKCkpLmlzVHJ1ZSgpOworICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSwKKyAgICAgICAgICAgICAgICAgICAgRE9XTkxPQURfRVhFQ1VUT1IpOworICAgICAgICAgICAgICAgIHJldHVybiBpbXBvcnRUYXNrRnV0dXJlOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKworICAgIGNyZWF0ZU1vYmlsZURhdGFEb3dubG9hZCgoKSAtPiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyKTsKKworICAgIERhdGFGaWxlR3JvdXAgZmlsZUdyb3VwV2l0aElubGluZUZpbGUgPQorICAgICAgICBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAuYWRkRmlsZShJTkxJTkVfREFUQV9GSUxFXzEpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIEVuc3VyZSB0aGF0IHdlIGFkZCB0aGUgZmlsZSBncm91cCBzdWNjZXNzZnVsbHkKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXREYXRhRmlsZUdyb3VwKGZpbGVHcm91cFdpdGhJbmxpbmVGaWxlKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisKKyAgICAvLyBQZXJmb3JtIHRoZSBpbXBvcnQKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGltcG9ydEZpbGVzRnV0dXJlID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmltcG9ydEZpbGVzKAorICAgICAgICAgICAgSW1wb3J0RmlsZXNSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FKQorICAgICAgICAgICAgICAgIC5zZXRCdWlsZElkKGZpbGVHcm91cFdpdGhJbmxpbmVGaWxlLmdldEJ1aWxkSWQoKSkKKyAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkKGZpbGVHcm91cFdpdGhJbmxpbmVGaWxlLmdldFZhcmlhbnRJZCgpKQorICAgICAgICAgICAgICAgIC5zZXRJbmxpbmVGaWxlTWFwKEltbXV0YWJsZU1hcC5vZihGSUxFX0lEXzEsIGlubGluZUZpbGVTb3VyY2UxKSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICAvLyBOb3RlOiBXZSBjb3VsZCBoYXZlIGEgcmFjZSBjb25kaXRpb24gd2hlbiB3ZSBjYWxsIGNhbmNlbCgpIG9uIHRoZSBmdXR1cmUsIHNpbmNlIHRoZQorICAgIC8vIEZpbGVEb3dubG9hZGVyJ3Mgc3RhcnREb3dubG9hZGluZygpIG1heSBub3QgaGF2ZSBiZWVuIGludm9rZWQgeWV0LiBUbyBwcmV2ZW50IHRoaXMsIHdlIGZpcnN0CisgICAgLy8gd2FpdCBmb3IgdGhlIGZpbGUgZG93bmxvYWRlciB0byBiZSBpbnZva2VkIGJlZm9yZSBwZXJmb3JtaW5nIHRoZSBjYW5jZWwuCisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci53YWl0Rm9yRG93bmxvYWRTdGFydGVkKCk7CisKKyAgICBpbXBvcnRGaWxlc0Z1dHVyZS5jYW5jZWwoLyogbWF5SW50ZXJydXB0SWZSdW5uaW5nID0gKi8gdHJ1ZSk7CisKKyAgICAvLyBBbGxvdyB0aGUgZG93bmxvYWQgdG8gY29udGludWUgYW5kIHRyaWdnZXIgb3VyIGRlbGVnYXRlIEZpbGVEb3dubG9hZGVyLiBJZiB0aGUgZnV0dXJlIGlzbid0CisgICAgLy8gY2FuY2VsbGVkLCB0aGUgb25TdWNjZXNzIGNhbGxiYWNrIHNob3VsZCBmYWlsIHRoZSB0ZXN0LgorICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIuZmluaXNoRG93bmxvYWRpbmcoKTsKKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLndhaXRGb3JEb3dubG9hZENvbXBsZXRlZCgpOworCisgICAgYXNzZXJ0VGhhdChpbXBvcnRGaWxlc0Z1dHVyZS5pc0NhbmNlbGxlZCgpKS5pc1RydWUoKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZC5jbGVhcigpLmdldCgpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGNyZWF0ZU1vYmlsZURhdGFEb3dubG9hZChTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllcikgeworICAgIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0Q29udGV4dChjb250ZXh0KQorICAgICAgICAgICAgLnNldENvbnRyb2xFeGVjdXRvcihDT05UUk9MX0VYRUNVVE9SKQorICAgICAgICAgICAgLnNldEZpbGVEb3dubG9hZGVyU3VwcGxpZXIoZmlsZURvd25sb2FkZXJTdXBwbGllcikKKyAgICAgICAgICAgIC5zZXRUYXNrU2NoZWR1bGVyKE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSkKKyAgICAgICAgICAgIC5zZXREZWx0YURlY29kZXJPcHRpb25hbChPcHRpb25hbC5hYnNlbnQoKSkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RvcmFnZShmaWxlU3RvcmFnZSkKKyAgICAgICAgICAgIC5zZXROZXR3b3JrVXNhZ2VNb25pdG9yKG1vY2tOZXR3b3JrVXNhZ2VNb25pdG9yKQorICAgICAgICAgICAgLnNldERvd25sb2FkTW9uaXRvck9wdGlvbmFsKE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZFByb2dyZXNzTW9uaXRvcikpCisgICAgICAgICAgICAuc2V0RmxhZ3NPcHRpb25hbChPcHRpb25hbC5vZihmbGFncykpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL01kZEdhcmJhZ2VDb2xsZWN0aW9uV2l0aEFuZHJvaWRTaGFyaW5nSW50ZWdyYXRpb25UZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvTWRkR2FyYmFnZUNvbGxlY3Rpb25XaXRoQW5kcm9pZFNoYXJpbmdJbnRlZ3JhdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDczZTA0Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL01kZEdhcmJhZ2VDb2xsZWN0aW9uV2l0aEFuZHJvaWRTaGFyaW5nSW50ZWdyYXRpb25UZXN0LmphdmEKQEAgLTAsMCArMSwzNjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0LkRBWVM7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0LlNFQ09ORFM7CisKK2ltcG9ydCBhbmRyb2lkLmFwcC5ibG9iLkJsb2JTdG9yZU1hbmFnZXI7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudXRpbC5Mb2c7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuZXh0Lmp1bml0LnJ1bm5lcnMuQW5kcm9pZEpVbml0NDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkJsb2JTdG9yZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5CbG9iVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuSmF2YUZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5Db21wcmVzc1RyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZGRUZXN0VXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuTmV0d29ya1VzYWdlTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLlRlc3RGaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLlRlc3RGbGFnczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuU3VwcGxpZXI7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuQ2xpZW50Q29uZmlnUHJvdG8uQ2xpZW50RmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5DbGllbnRDb25maWdQcm90by5DbGllbnRGaWxlR3JvdXA7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZUdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRG93bmxvYWRDb25kaXRpb25zLkRldmljZU5ldHdvcmtQb2xpY3k7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBvcmcuanVuaXQuQWZ0ZXI7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm1vY2tpdG8uTW9jazsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvSlVuaXQ7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b1J1bGU7CisKK0BSdW5XaXRoKEFuZHJvaWRKVW5pdDQuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgTWRkR2FyYmFnZUNvbGxlY3Rpb25XaXRoQW5kcm9pZFNoYXJpbmdJbnRlZ3JhdGlvblRlc3QgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIk1kZEdhcmJhZ2VDb2xsZWN0aW9uV2l0aEFuZHJvaWRTaGFyaW5nSW50ZWdyYXRpb25UZXN0IjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9ET1dOTE9BRF9GSUxFX0dST1VQX1dBSVRfVElNRV9TRUNTID0gMzAwOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBURVNUX0RBVEFfUkVMQVRJVkVfUEFUSCA9CisgICAgICAidGhpcmRfcGFydHkvamF2YV9zcmMvYW5kcm9pZF9saWJzL21vYmlsZWRhdGFkb3dubG9hZC9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGEvIjsKKworICAvLyBOb3RlOiBDb250cm9sIEV4ZWN1dG9yIG11c3Qgbm90IGJlIGEgc2luZ2xlIHRocmVhZCBleGVjdXRvci4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlIENPTlRST0xfRVhFQ1VUT1IgPQorICAgICAgTW9yZUV4ZWN1dG9ycy5saXN0ZW5pbmdEZWNvcmF0b3IoRXhlY3V0b3JzLm5ld0NhY2hlZFRocmVhZFBvb2woKSk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSBET1dOTE9BRF9FWEVDVVRPUiA9CisgICAgICBFeGVjdXRvcnMubmV3U2NoZWR1bGVkVGhyZWFkUG9vbCgyKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9HUk9VUF9UT19TSEFSRV8xID0gInRlc3QtZ3JvdXAtMSI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0lEXzEgPSAidGVzdC1maWxlLXRvLXNoYXJlLTEiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9DSEVDS1NVTV8xID0gImZjYzk2YjI3MjYzM2NkZjZjNGJiZDJkNzc1MTJjY2E1MWJmYjFkYmQiOyAvLyBTSEFfMQorICBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfQU5EUk9JRF9TSEFSSU5HX0NIRUNLU1VNXzEgPQorICAgICAgIjIyNTAxN2I1ZDVlYzM1NzMyOTQwYWY4MTNiMWFiN2JlNTE5MWU0YzUyNjU5OTUzZTc1YTFhMzZhMTM5OGM0OGQiOyAvLyBTSEFfMjU2CisgIHN0YXRpYyBmaW5hbCBpbnQgRklMRV9TSVpFXzEgPSA1NzsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX1VSTF8xID0gImh0dHBzOi8vd3d3LmdzdGF0aWMuY29tL2ljaW5nL2lkZC9zYW1wbGVfZ3JvdXAvc3RlcDEudHh0IjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb250ZXh0IGNvbnRleHQgPSBBcHBsaWNhdGlvblByb3ZpZGVyLmdldEFwcGxpY2F0aW9uQ29udGV4dCgpOworCisgIEBNb2NrIHByaXZhdGUgVGFza1NjaGVkdWxlciBtb2NrVGFza1NjaGVkdWxlcjsKKyAgQE1vY2sgcHJpdmF0ZSBOZXR3b3JrVXNhZ2VNb25pdG9yIG1vY2tOZXR3b3JrVXNhZ2VNb25pdG9yOworICBATW9jayBwcml2YXRlIERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIG1vY2tEb3dubG9hZFByb2dyZXNzTW9uaXRvcjsKKyAgQE1vY2sgcHJpdmF0ZSBMb2dnZXIgbW9ja0xvZ2dlcjsKKworICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2U7CisgIHByaXZhdGUgQmxvYlN0b3JlTWFuYWdlciBibG9iU3RvcmVNYW5hZ2VyOworICBwcml2YXRlIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQ7CisKKyAgcHJpdmF0ZSBmaW5hbCBUZXN0RmxhZ3MgZmxhZ3MgPSBuZXcgVGVzdEZsYWdzKCk7CisKKyAgQFJ1bGUgcHVibGljIGZpbmFsIE1vY2tpdG9SdWxlIG1vY2tzID0gTW9ja2l0b0pVbml0LnJ1bGUoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmxhZ3MubWRkQW5kcm9pZFNoYXJpbmdTYW1wbGVJbnRlcnZhbCA9IE9wdGlvbmFsLm9mKDEpOworICAgIGZsYWdzLm1kZERlZmF1bHRTYW1wbGVJbnRlcnZhbCA9IE9wdGlvbmFsLm9mKDEpOworICAgIEJsb2JTdG9yZUJhY2tlbmQgYmxvYlN0b3JlQmFja2VuZCA9IG5ldyBCbG9iU3RvcmVCYWNrZW5kKGNvbnRleHQpOworICAgIGJsb2JTdG9yZU1hbmFnZXIgPSAoQmxvYlN0b3JlTWFuYWdlcikgY29udGV4dC5nZXRTeXN0ZW1TZXJ2aWNlKENvbnRleHQuQkxPQl9TVE9SRV9TRVJWSUNFKTsKKworICAgIGZpbGVTdG9yYWdlID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICAvKiBiYWNrZW5kcz0gKi8gSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgICAgICBBbmRyb2lkRmlsZUJhY2tlbmQuYnVpbGRlcihjb250ZXh0KS5idWlsZCgpLAorICAgICAgICAgICAgICAgIGJsb2JTdG9yZUJhY2tlbmQsCisgICAgICAgICAgICAgICAgbmV3IEphdmFGaWxlQmFja2VuZCgpKSwKKyAgICAgICAgICAgIC8qIHRyYW5zZm9ybXM9ICovIEltbXV0YWJsZUxpc3Qub2YobmV3IENvbXByZXNzVHJhbnNmb3JtKCkpLAorICAgICAgICAgICAgLyogbW9uaXRvcnM9ICovIEltbXV0YWJsZUxpc3Qub2YobW9ja05ldHdvcmtVc2FnZU1vbml0b3IsIG1vY2tEb3dubG9hZFByb2dyZXNzTW9uaXRvcikpOworICAgIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyID0KKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIG5ldyBUZXN0RmlsZURvd25sb2FkZXIoCisgICAgICAgICAgICAgICAgVEVTVF9EQVRBX1JFTEFUSVZFX1BBVEgsCisgICAgICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAgICAgTW9yZUV4ZWN1dG9ycy5saXN0ZW5pbmdEZWNvcmF0b3IoRE9XTkxPQURfRVhFQ1VUT1IpKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0Q29udGV4dChjb250ZXh0KQorICAgICAgICAgICAgLnNldENvbnRyb2xFeGVjdXRvcihDT05UUk9MX0VYRUNVVE9SKQorICAgICAgICAgICAgLnNldEZpbGVEb3dubG9hZGVyU3VwcGxpZXIoZmlsZURvd25sb2FkZXJTdXBwbGllcikKKyAgICAgICAgICAgIC5zZXRUYXNrU2NoZWR1bGVyKE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSkKKyAgICAgICAgICAgIC5zZXREZWx0YURlY29kZXJPcHRpb25hbChPcHRpb25hbC5hYnNlbnQoKSkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RvcmFnZShmaWxlU3RvcmFnZSkKKyAgICAgICAgICAgIC5zZXROZXR3b3JrVXNhZ2VNb25pdG9yKG1vY2tOZXR3b3JrVXNhZ2VNb25pdG9yKQorICAgICAgICAgICAgLnNldERvd25sb2FkTW9uaXRvck9wdGlvbmFsKE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZFByb2dyZXNzTW9uaXRvcikpCisgICAgICAgICAgICAuc2V0TG9nZ2VyT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0xvZ2dlcikpCisgICAgICAgICAgICAuc2V0RmxhZ3NPcHRpb25hbChPcHRpb25hbC5vZihmbGFncykpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgfQorCisgIEBBZnRlcgorICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgIG1vYmlsZURhdGFEb3dubG9hZC5jbGVhcigpLmdldCgpOworICAgIC8vIENvbW1hbmRzIHRvIGNsZWFuIHVwIHRoZSBibG9iIHN0b3JhZ2UuCisgICAgTWRkVGVzdFV0aWwucnVuU2hlbGxDbWQoImNtZCBibG9iX3N0b3JlIGNsZWFyLWFsbC1zZXNzaW9ucyIpOworICAgIE1kZFRlc3RVdGlsLnJ1blNoZWxsQ21kKCJjbWQgYmxvYl9zdG9yZSBjbGVhci1hbGwtYmxvYnMiKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBkb3dubG9hZEZpbGVHcm91cChEYXRhRmlsZUdyb3VwIGZpbGVHcm91cCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0RGF0YUZpbGVHcm91cChmaWxlR3JvdXApLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKGZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkKKyAgICAgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbCgKKyAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwub2YoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRG93bmxvYWRMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uUHJvZ3Jlc3MobG9uZyBjdXJyZW50U2l6ZSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5pKFRBRywgIm9uUHJvZ3Jlc3MgIiArIGN1cnJlbnRTaXplKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkNvbXBsZXRlKENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuaShUQUcsICJvbkNvbXBsZXRlICIgKyBjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9KSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmdldChNQVhfRE9XTkxPQURfRklMRV9HUk9VUF9XQUlUX1RJTUVfU0VDUywgU0VDT05EUyk7CisgIH0KKworICBwcml2YXRlIENsaWVudEZpbGVHcm91cCB2ZXJpZnlEb3dubG9hZGVkR3JvdXBJc0Rvd25sb2FkZWQoRGF0YUZpbGVHcm91cCBmaWxlR3JvdXAsIGludCBmaWxlQ291bnQpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKAorICAgICAgICAgICAgICAgIEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cCkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhmaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oZmlsZUNvdW50KTsKKyAgICByZXR1cm4gY2xpZW50RmlsZUdyb3VwOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZGVsZXRlc1N0YWxlR3JvdXBzX3N0YWxlTGlmZXRpbWVaZXJvKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGFuZHJvaWRVcmkgPQorICAgICAgICBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0QmxvYlBhcmFtZXRlcnMoRklMRV9BTkRST0lEX1NIQVJJTkdfQ0hFQ0tTVU1fMSkuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhhbmRyb2lkVXJpKSkuaXNGYWxzZSgpOworCisgICAgLy8gRG93bmxvYWQgZmlsZSBncm91cCB3aXRoIHN0YWxlIGxpZmV0aW1lIDAuCisgICAgRGF0YUZpbGVHcm91cCBmaWxlR3JvdXAgPQorICAgICAgICBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICBGSUxFX0dST1VQX1RPX1NIQVJFXzEsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9BTkRST0lEX1NIQVJJTkdfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSyk7CisKKyAgICBkb3dubG9hZEZpbGVHcm91cChmaWxlR3JvdXApOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9IHZlcmlmeURvd25sb2FkZWRHcm91cElzRG93bmxvYWRlZChmaWxlR3JvdXAsIDEpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSURfMSk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZShjbGllbnRGaWxlLmdldEZpbGVVcmkoKSk7CisKKyAgICAvLyBUaGUgZmlsZSBpcyBub3cgYXZhaWxhYmxlIGluIHRoZSBhbmRyb2lkIHNoYXJlZCBzdG9yYWdlLgorICAgIGFzc2VydFRoYXQodXJpKS5pc0VxdWFsVG8oYW5kcm9pZFVyaSk7CisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHModXJpKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkpLmhhc1NpemUoMSk7CisKKyAgICAvLyBTZW5kIGFuIGVtcHR5IGdyb3VwIHNvIHRoYXQgdGhlIG9sZCBncm91cCBpcyBub3cgc3RhbGUuCisgICAgRGF0YUZpbGVHcm91cCBlbXB0eUZpbGVHcm91cCA9CisgICAgICAgIFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfVE9fU0hBUkVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7fSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7fSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7fSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7fSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7fSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05fQU5ZX05FVFdPUkspOworCisgICAgZG93bmxvYWRGaWxlR3JvdXAoZW1wdHlGaWxlR3JvdXApOworCisgICAgLy8gUnVuIG1haW50ZW5hbmNlIHRha3MuCisgICAgbW9iaWxlRGF0YURvd25sb2FkLm1haW50ZW5hbmNlKCkuZ2V0KE1BWF9ET1dOTE9BRF9GSUxFX0dST1VQX1dBSVRfVElNRV9TRUNTLCBTRUNPTkRTKTsKKworICAgIHZlcmlmeURvd25sb2FkZWRHcm91cElzRG93bmxvYWRlZChlbXB0eUZpbGVHcm91cCwgMCk7CisKKyAgICAvLyBPbGQgc3RhbGUgZmlsZSBoYXMgYmVlbiByZWxlYXNlZAorICAgIGFzc2VydFRoYXQoYmxvYlN0b3JlTWFuYWdlci5nZXRMZWFzZWRCbG9icygpKS5pc0VtcHR5KCk7CisKKyAgICAvLyBWZXJpZnkgbG9nZ2luZyBldmVudHMuCisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVzU3RhbGVHcm91cHNfc3RhbGVMaWZldGltZVR3b0RheXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgYW5kcm9pZFVyaSA9CisgICAgICAgIEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRCbG9iUGFyYW1ldGVycyhGSUxFX0FORFJPSURfU0hBUklOR19DSEVDS1NVTV8xKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKGFuZHJvaWRVcmkpKS5pc0ZhbHNlKCk7CisKKyAgICAvLyBEb3dubG9hZCBmaWxlIGdyb3VwIHdpdGggc3RhbGUgbGlmZXRpbWUgKzIgZGF5cy4KKyAgICBEYXRhRmlsZUdyb3VwIGZpbGVHcm91cCA9CisgICAgICAgIFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfVE9fU0hBUkVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0FORFJPSURfU0hBUklOR19DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKTsKKyAgICBmaWxlR3JvdXAgPSBmaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0U3RhbGVMaWZldGltZVNlY3MoREFZUy50b1NlY29uZHMoMikpLmJ1aWxkKCk7CisKKyAgICBkb3dubG9hZEZpbGVHcm91cChmaWxlR3JvdXApOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9IHZlcmlmeURvd25sb2FkZWRHcm91cElzRG93bmxvYWRlZChmaWxlR3JvdXAsIDEpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSURfMSk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZShjbGllbnRGaWxlLmdldEZpbGVVcmkoKSk7CisKKyAgICAvLyBUaGUgZmlsZSBpcyBub3cgYXZhaWxhYmxlIGluIHRoZSBhbmRyb2lkIHNoYXJlZCBzdG9yYWdlLgorICAgIGFzc2VydFRoYXQodXJpKS5pc0VxdWFsVG8oYW5kcm9pZFVyaSk7CisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHModXJpKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkpLmhhc1NpemUoMSk7CisKKyAgICAvLyBTZW5kIGFuIGVtcHR5IGdyb3VwIHNvIHRoYXQgdGhlIG9sZCBncm91cCBpcyBub3cgc3RhbGUuCisgICAgRGF0YUZpbGVHcm91cCBlbXB0eUZpbGVHcm91cCA9CisgICAgICAgIFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfVE9fU0hBUkVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7fSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7fSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7fSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7fSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7fSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05fQU5ZX05FVFdPUkspOworICAgIGRvd25sb2FkRmlsZUdyb3VwKGVtcHR5RmlsZUdyb3VwKTsKKworICAgIC8vIFJ1biBtYWludGVuYW5jZSB0YWtzLgorICAgIG1vYmlsZURhdGFEb3dubG9hZC5tYWludGVuYW5jZSgpLmdldChNQVhfRE9XTkxPQURfRklMRV9HUk9VUF9XQUlUX1RJTUVfU0VDUywgU0VDT05EUyk7CisKKyAgICB2ZXJpZnlEb3dubG9hZGVkR3JvdXBJc0Rvd25sb2FkZWQoZW1wdHlGaWxlR3JvdXAsIDApOworCisgICAgLy8gT2xkIHN0YWxlIGZpbGUgaGFzbid0IGJlZW4gcmVsZWFzZWQgeWV0CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkpLmhhc1NpemUoMSk7CisKKyAgICAvLyBBZHZhbmNlIHRpbWUgYnkgMiBkYXlzLCBhbmQgdmVyaWZ5IHRoYXQgdGhlIGxlYXNlIG9uIHRoZSBzaGFyZWQgZmlsZSBoYXMgYmVlbgorICAgIC8vIHJlbGVhc2VkLgorICAgIE1kZFRlc3RVdGlsLnRpbWVUcmF2ZWwoY29udGV4dCwgREFZUy50b01pbGxpcygyKSk7CisgICAgbW9iaWxlRGF0YURvd25sb2FkLm1haW50ZW5hbmNlKCkuZ2V0KE1BWF9ET1dOTE9BRF9GSUxFX0dST1VQX1dBSVRfVElNRV9TRUNTLCBTRUNPTkRTKTsKKworICAgIHZlcmlmeURvd25sb2FkZWRHcm91cElzRG93bmxvYWRlZChlbXB0eUZpbGVHcm91cCwgMCk7CisKKyAgICBhc3NlcnRUaGF0KGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKSkuaXNFbXB0eSgpOworCisgICAgLy8gVmVyaWZ5IGxvZ2dpbmcgZXZlbnRzLgorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZGVsZXRlc0V4cGlyZWRHcm91cHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgYW5kcm9pZFVyaSA9CisgICAgICAgIEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRCbG9iUGFyYW1ldGVycyhGSUxFX0FORFJPSURfU0hBUklOR19DSEVDS1NVTV8xKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKGFuZHJvaWRVcmkpKS5pc0ZhbHNlKCk7CisKKyAgICAvLyBEb3dubG9hZCBmaWxlIGdyb3VwIHdpdGggc3RhbGUgbGlmZXRpbWUgKzIgZGF5cy4KKyAgICBEYXRhRmlsZUdyb3VwIGZpbGVHcm91cCA9CisgICAgICAgIFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfVE9fU0hBUkVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0FORFJPSURfU0hBUklOR19DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKTsKKworICAgIC8vIEl0IGV4cGlyZXMgaW4gdHdvIGRheXMuCisgICAgZmlsZUdyb3VwID0gZmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldEV4cGlyYXRpb25EYXRlKE1kZFRlc3RVdGlsLmRheXNGcm9tTm93KDIpKS5idWlsZCgpOworCisgICAgZG93bmxvYWRGaWxlR3JvdXAoZmlsZUdyb3VwKTsKKworICAgIENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXAgPSB2ZXJpZnlEb3dubG9hZGVkR3JvdXBJc0Rvd25sb2FkZWQoZmlsZUdyb3VwLCAxKTsKKworICAgIENsaWVudEZpbGUgY2xpZW50RmlsZSA9IGNsaWVudEZpbGVHcm91cC5nZXRGaWxlTGlzdCgpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RmlsZUlkKCkpLmlzRXF1YWxUbyhGSUxFX0lEXzEpOworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoY2xpZW50RmlsZS5nZXRGaWxlVXJpKCkpOworCisgICAgLy8gVGhlIGZpbGUgaXMgbm93IGF2YWlsYWJsZSBpbiB0aGUgYW5kcm9pZCBzaGFyZWQgc3RvcmFnZS4KKyAgICBhc3NlcnRUaGF0KHVyaSkuaXNFcXVhbFRvKGFuZHJvaWRVcmkpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKHVyaSkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoYmxvYlN0b3JlTWFuYWdlci5nZXRMZWFzZWRCbG9icygpKS5oYXNTaXplKDEpOworCisgICAgLy8gUnVuIG1haW50ZW5hbmNlIHRhc2tzIGFuZCB2ZXJpZnkgdGhhdCB3ZSBzdGlsbCBvd24gdGhlIGxlYXNlIG9tIHRoZSBzaGFyZWQgZmlsZS4KKyAgICBtb2JpbGVEYXRhRG93bmxvYWQubWFpbnRlbmFuY2UoKS5nZXQoTUFYX0RPV05MT0FEX0ZJTEVfR1JPVVBfV0FJVF9USU1FX1NFQ1MsIFNFQ09ORFMpOworCisgICAgdmVyaWZ5RG93bmxvYWRlZEdyb3VwSXNEb3dubG9hZGVkKGZpbGVHcm91cCwgMSk7CisKKyAgICBhc3NlcnRUaGF0KGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKSkuaGFzU2l6ZSgxKTsKKworICAgIC8vIEFkdmFuY2UgdGltZSBieSAzIGRheXMsIGFuZCB2ZXJpZnkgdGhhdCB0aGUgZ3JvdXAgYW5kIGZpbGVzIGNhbiBubyBsb25nZXIgYmUgcmVhZAorICAgIC8vIGJlY2F1c2UgdGhleSBleHBpcmVkLgorICAgIE1kZFRlc3RVdGlsLnRpbWVUcmF2ZWwoY29udGV4dCwgREFZUy50b01pbGxpcygzKSk7CisgICAgbW9iaWxlRGF0YURvd25sb2FkLm1haW50ZW5hbmNlKCkuZ2V0KE1BWF9ET1dOTE9BRF9GSUxFX0dST1VQX1dBSVRfVElNRV9TRUNTLCBTRUNPTkRTKTsKKyAgICBjbGllbnRGaWxlR3JvdXAgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgIC5nZXRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgR2V0RmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfVE9fU0hBUkVfMSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cCkuaXNOdWxsKCk7CisKKyAgICBhc3NlcnRUaGF0KGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKSkuaXNFbXB0eSgpOworCisgICAgLy8gVmVyaWZ5IGxvZ2dpbmcgZXZlbnRzLgorCisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Nb2JpbGVEYXRhRG93bmxvYWRJbnRlZ3JhdGlvblRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Nb2JpbGVEYXRhRG93bmxvYWRJbnRlZ3JhdGlvblRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jOTQ1MzJlCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL01vYmlsZURhdGFEb3dubG9hZEludGVncmF0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsODg3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZDsKKworaW1wb3J0IHN0YXRpYyBhbmRyb2lkLnN5c3RlbS5Pcy5yZWFkbGluazsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGVzdEZpbGVHcm91cFBvcHVsYXRvci5GSUxFX0NIRUNLU1VNOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UZXN0RmlsZUdyb3VwUG9wdWxhdG9yLkZJTEVfR1JPVVBfTkFNRTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGVzdEZpbGVHcm91cFBvcHVsYXRvci5GSUxFX0lEOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UZXN0RmlsZUdyb3VwUG9wdWxhdG9yLkZJTEVfU0laRTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuVGVzdEZpbGVHcm91cFBvcHVsYXRvci5GSUxFX1VSTDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudHJhY2luZy5UcmFjZVByb3BhZ2F0aW9uLnByb3BhZ2F0ZUNhbGxhYmxlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdC5TRUNPTkRTOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOworCitpbXBvcnQgYW5kcm9pZC5hY2NvdW50cy5BY2NvdW50OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LnJ1bm5lci5BbmRyb2lkSlVuaXQ0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmFjY291bnQuQWNjb3VudFV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5BbmRyb2lkRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5BbmRyb2lkVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuQW5kcm9pZFVyaUFkYXB0ZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5KYXZhRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLlJlYWRTdHJpbmdPcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLldyaXRlU3RyaW5nT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuRGlyZWN0b3J5VXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLk5ldHdvcmtVc2FnZU1vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5CbG9ja2luZ0ZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRlc3RpbmcuRmFrZVRpbWVTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5UZXN0RmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5UZXN0RmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkNsaWVudENvbmZpZ1Byb3RvLkNsaWVudEZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuQ2xpZW50Q29uZmlnUHJvdG8uQ2xpZW50RmlsZUdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZS5DaGVja3N1bVR5cGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZUdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRG93bmxvYWRDb25kaXRpb25zOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRG93bmxvYWRDb25kaXRpb25zLkRldmljZU5ldHdvcmtQb2xpY3k7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5DYW5jZWxsYXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TY2hlZHVsZWRFeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZW91dEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Nb2NrOworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9KVW5pdDsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvUnVsZTsKKworQFJ1bldpdGgoQW5kcm9pZEpVbml0NC5jbGFzcykKK3B1YmxpYyBjbGFzcyBNb2JpbGVEYXRhRG93bmxvYWRJbnRlZ3JhdGlvblRlc3QgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiTW9iaWxlRGF0YURvd25sb2FkSW50ZWdyYXRpb25UZXN0IjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IE1BWF9IQU5ETEVfVEFTS19XQUlUX1RJTUVfU0VDUyA9IDMwMDsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVTVF9EQVRBX1JFTEFUSVZFX1BBVEggPQorICAgICAgInRoaXJkX3BhcnR5L2phdmFfc3JjL2FuZHJvaWRfbGlicy9tb2JpbGVkYXRhZG93bmxvYWQvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhLyI7CisKKyAgLy8gTm90ZTogQ29udHJvbCBFeGVjdXRvciBtdXN0IG5vdCBiZSBhIHNpbmdsZSB0aHJlYWQgZXhlY3V0b3IuCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSBDT05UUk9MX0VYRUNVVE9SID0KKyAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKEV4ZWN1dG9ycy5uZXdDYWNoZWRUaHJlYWRQb29sKCkpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UgRE9XTkxPQURfRVhFQ1VUT1IgPQorICAgICAgRXhlY3V0b3JzLm5ld1NjaGVkdWxlZFRocmVhZFBvb2woMik7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29udGV4dCBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKyAgcHJpdmF0ZSBmaW5hbCBOZXR3b3JrVXNhZ2VNb25pdG9yIG5ldHdvcmtVc2FnZU1vbml0b3IgPQorICAgICAgbmV3IE5ldHdvcmtVc2FnZU1vbml0b3IoY29udGV4dCwgbmV3IEZha2VUaW1lU291cmNlKCkpOworCisgIHByaXZhdGUgZmluYWwgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZSA9CisgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEFuZHJvaWRGaWxlQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLmJ1aWxkKCksIG5ldyBKYXZhRmlsZUJhY2tlbmQoKSksCisgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpLAorICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV0d29ya1VzYWdlTW9uaXRvcikpOworCisgIHByaXZhdGUgZmluYWwgVGVzdEZsYWdzIGZsYWdzID0gbmV3IFRlc3RGbGFncygpOworCisgIEBNb2NrIHByaXZhdGUgTG9nZ2VyIG1vY2tMb2dnZXI7CisgIEBNb2NrIHByaXZhdGUgVGFza1NjaGVkdWxlciBtb2NrVGFza1NjaGVkdWxlcjsKKworICBAUnVsZSBwdWJsaWMgZmluYWwgTW9ja2l0b1J1bGUgbW9ja3MgPSBNb2NraXRvSlVuaXQucnVsZSgpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmbGFncy5lbmFibGVaaXBGb2xkZXIgPSBPcHRpb25hbC5vZih0cnVlKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkX3N1Y2Nlc3NfZmlsZUdyb3VwRG93bmxvYWRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBnZXRNb2JpbGVEYXRhRG93bmxvYWRBZnRlckRvd25sb2FkKAorICAgICAgICAgICAgKCkgLT4KKyAgICAgICAgICAgICAgICBuZXcgVGVzdEZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgICAgICAgICBURVNUX0RBVEFfUkVMQVRJVkVfUEFUSCwKKyAgICAgICAgICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKERPV05MT0FEX0VYRUNVVE9SKSksCisgICAgICAgICAgICBuZXcgVGVzdEZpbGVHcm91cFBvcHVsYXRvcihjb250ZXh0KSk7CisKKyAgICAvLyBUaGlzIHdpbGwgdHJpZ2dlciByZWZyZXNoaW5nIG9mIEZpbGVHcm91cFBvcHVsYXRvcnMgYW5kIGRvd25sb2FkaW5nLgorICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLkNFTExVTEFSX0NIQVJHSU5HX1BFUklPRElDX1RBU0spCisgICAgICAgIC5nZXQoTUFYX0hBTkRMRV9UQVNLX1dBSVRfVElNRV9TRUNTLCBTRUNPTkRTKTsKKworICAgIFN0cmluZyBkZWJ1Z1N0cmluZyA9IG1vYmlsZURhdGFEb3dubG9hZC5nZXREZWJ1Z0luZm9Bc1N0cmluZygpOworICAgIExvZy5pKFRBRywgIk1ERCBMaWIgZHVtcDoiKTsKKyAgICBmb3IgKFN0cmluZyBsaW5lIDogZGVidWdTdHJpbmcuc3BsaXQoIlxuIiwgLTEpKSB7CisgICAgICBMb2cuaShUQUcsIGxpbmUpOworICAgIH0KKworICAgIENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXAgPQorICAgICAgICBnZXRBbmRWZXJpZnlDbGllbnRGaWxlR3JvdXAobW9iaWxlRGF0YURvd25sb2FkLCBGSUxFX0dST1VQX05BTUUsIDEpOworICAgIHZlcmlmeUNsaWVudEZpbGUoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApLCBGSUxFX0lELCBGSUxFX1NJWkUpOworICAgIG1vYmlsZURhdGFEb3dubG9hZC5jbGVhcigpLmdldCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRfd2l0aEN1c3RvbVZhbGlkYXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIEN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciB2YWxpZGF0b3IgPQorICAgICAgICBmaWxlR3JvdXAgLT4geworICAgICAgICAgIGlmICghZmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpLmVxdWFscyhGSUxFX0dST1VQX05BTUUpKSB7CisgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSk7CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBNb3JlRXhlY3V0b3JzLmxpc3RlbmluZ0RlY29yYXRvcihET1dOTE9BRF9FWEVDVVRPUikKKyAgICAgICAgICAgICAgLnN1Ym1pdCgKKyAgICAgICAgICAgICAgICAgIHByb3BhZ2F0ZUNhbGxhYmxlKAorICAgICAgICAgICAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuYnVpbGQoKSkpOworICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChDbGllbnRGaWxlIGZpbGUgOiBmaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN0b3JhZ2UuZXhpc3RzKFVyaS5wYXJzZShmaWxlLmdldEZpbGVVcmkoKSkpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgICB9KSk7CisgICAgICAgIH07CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkQnVpbGRlcigKKyAgICAgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgICAgICBuZXcgVGVzdEZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgICAgICAgICAgICAgVEVTVF9EQVRBX1JFTEFUSVZFX1BBVEgsCisgICAgICAgICAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKERPV05MT0FEX0VYRUNVVE9SKSksCisgICAgICAgICAgICAgICAgbmV3IFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IoY29udGV4dCkpCisgICAgICAgICAgICAuc2V0Q3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yT3B0aW9uYWwoT3B0aW9uYWwub2YodmFsaWRhdG9yKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gVGhpcyB3aWxsIHRyaWdnZXIgcmVmcmVzaGluZyBvZiBGaWxlR3JvdXBQb3B1bGF0b3JzIGFuZCBkb3dubG9hZGluZy4KKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmhhbmRsZVRhc2soVGFza1NjaGVkdWxlci5DRUxMVUxBUl9DSEFSR0lOR19QRVJJT0RJQ19UQVNLKQorICAgICAgICAuZ2V0KE1BWF9IQU5ETEVfVEFTS19XQUlUX1RJTUVfU0VDUywgU0VDT05EUyk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisgICAgdmVyaWZ5Q2xpZW50RmlsZShjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKS5nZXQoMCksIEZJTEVfSUQsIEZJTEVfU0laRSk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuY2xlYXIoKS5nZXQoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkX3N1Y2Nlc3NfbWFpbnRlbmFuY2VMb2dzTmV0d29ya1VzYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmxhZ3MubmV0d29ya1N0YXRzTG9nZ2luZ1NhbXBsZUludGVydmFsID0gT3B0aW9uYWwub2YoMSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkKAorICAgICAgICAgICAgKCkgLT4KKyAgICAgICAgICAgICAgICBuZXcgVGVzdEZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgICAgICAgICBURVNUX0RBVEFfUkVMQVRJVkVfUEFUSCwKKyAgICAgICAgICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKERPV05MT0FEX0VYRUNVVE9SKSksCisgICAgICAgICAgICBuZXcgVGVzdEZpbGVHcm91cFBvcHVsYXRvcihjb250ZXh0KSk7CisKKyAgICAvLyBUaGlzIHdpbGwgdHJpZ2dlciByZWZyZXNoaW5nIG9mIEZpbGVHcm91cFBvcHVsYXRvcnMgYW5kIGRvd25sb2FkaW5nLgorICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLkNFTExVTEFSX0NIQVJHSU5HX1BFUklPRElDX1RBU0spCisgICAgICAgIC5nZXQoTUFYX0hBTkRMRV9UQVNLX1dBSVRfVElNRV9TRUNTLCBTRUNPTkRTKTsKKworICAgIC8vIFRoaXMgc2hvdWxkIGZsdXNoIHRoZSBsb2dzIGZyb20gTmV0d29ya0xvZ2dlci4KKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmhhbmRsZVRhc2soVGFza1NjaGVkdWxlci5NQUlOVEVOQU5DRV9QRVJJT0RJQ19UQVNLKQorICAgICAgICAuZ2V0KE1BWF9IQU5ETEVfVEFTS19XQUlUX1RJTUVfU0VDUywgU0VDT05EUyk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgZ2V0QW5kVmVyaWZ5Q2xpZW50RmlsZUdyb3VwKG1vYmlsZURhdGFEb3dubG9hZCwgRklMRV9HUk9VUF9OQU1FLCAxKTsKKyAgICB2ZXJpZnlDbGllbnRGaWxlKGNsaWVudEZpbGVHcm91cC5nZXRGaWxlTGlzdCgpLmdldCgwKSwgRklMRV9JRCwgRklMRV9TSVpFKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZC5jbGVhcigpLmdldCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY29ycnVwdGVkX2ZpbGVzX2RldGVjdGVkRHVyaW5nTWFpbnRlbmFuY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmbGFncy5tZGREZWZhdWx0U2FtcGxlSW50ZXJ2YWwgPSBPcHRpb25hbC5vZigxKTsKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkQWZ0ZXJEb3dubG9hZCgKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgbmV3IFRlc3RGaWxlRG93bmxvYWRlcigKKyAgICAgICAgICAgICAgICAgICAgVEVTVF9EQVRBX1JFTEFUSVZFX1BBVEgsCisgICAgICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgICAgICAgICBNb3JlRXhlY3V0b3JzLmxpc3RlbmluZ0RlY29yYXRvcihET1dOTE9BRF9FWEVDVVRPUikpLAorICAgICAgICAgICAgbmV3IFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IoY29udGV4dCkpOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIGdldEFuZFZlcmlmeUNsaWVudEZpbGVHcm91cChtb2JpbGVEYXRhRG93bmxvYWQsIEZJTEVfR1JPVVBfTkFNRSwgMSk7CisgICAgZmlsZVN0b3JhZ2Uub3BlbigKKyAgICAgICAgVXJpLnBhcnNlKGNsaWVudEZpbGVHcm91cC5nZXRGaWxlKDApLmdldEZpbGVVcmkoKSksIFdyaXRlU3RyaW5nT3BlbmVyLmNyZWF0ZSgiYzBycnVwdDNkIikpOworCisgICAgLy8gQmFkIGZpbGUgaXMgZGV0ZWN0ZWQgZHVyaW5nIG1haW50ZW5hbmNlLgorICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLk1BSU5URU5BTkNFX1BFUklPRElDX1RBU0spCisgICAgICAgIC5nZXQoTUFYX0hBTkRMRV9UQVNLX1dBSVRfVElNRV9TRUNTLCBTRUNPTkRTKTsKKworICAgIC8vIEZpbGUgZ3JvdXAgaXMgcmUtZG93bmxvYWRlZC4KKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmhhbmRsZVRhc2soVGFza1NjaGVkdWxlci5DRUxMVUxBUl9DSEFSR0lOR19QRVJJT0RJQ19UQVNLKQorICAgICAgICAuZ2V0KE1BWF9IQU5ETEVfVEFTS19XQUlUX1RJTUVfU0VDUywgU0VDT05EUyk7CisKKyAgICAvLyBSZS1sb2FkIHRoZSBmaWxlIGdyb3VwIHNpbmNlIHRoZSBvbi1kaXNrIFVSSXMgd2lsbCBoYXZlIGNoYW5nZWQuCisgICAgY2xpZW50RmlsZUdyb3VwID0gZ2V0QW5kVmVyaWZ5Q2xpZW50RmlsZUdyb3VwKG1vYmlsZURhdGFEb3dubG9hZCwgRklMRV9HUk9VUF9OQU1FLCAxKTsKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgZmlsZVN0b3JhZ2Uub3BlbigKKyAgICAgICAgICAgICAgICBVcmkucGFyc2UoY2xpZW50RmlsZUdyb3VwLmdldEZpbGUoMCkuZ2V0RmlsZVVyaSgpKSwgUmVhZFN0cmluZ09wZW5lci5jcmVhdGUoKSkpCisgICAgICAgIC5pc05vdEVxdWFsVG8oImMwcnJ1cHQzZCIpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkLmNsZWFyKCkuZ2V0KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVfZmlsZXNfZGV0ZWN0ZWREdXJpbmdNYWludGVuYW5jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGZsYWdzLm1kZERlZmF1bHRTYW1wbGVJbnRlcnZhbCA9IE9wdGlvbmFsLm9mKDEpOworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBnZXRNb2JpbGVEYXRhRG93bmxvYWRBZnRlckRvd25sb2FkKAorICAgICAgICAgICAgKCkgLT4KKyAgICAgICAgICAgICAgICBuZXcgVGVzdEZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgICAgICAgICBURVNUX0RBVEFfUkVMQVRJVkVfUEFUSCwKKyAgICAgICAgICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKERPV05MT0FEX0VYRUNVVE9SKSksCisgICAgICAgICAgICBuZXcgVGVzdEZpbGVHcm91cFBvcHVsYXRvcihjb250ZXh0KSk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgZ2V0QW5kVmVyaWZ5Q2xpZW50RmlsZUdyb3VwKG1vYmlsZURhdGFEb3dubG9hZCwgRklMRV9HUk9VUF9OQU1FLCAxKTsKKyAgICBmaWxlU3RvcmFnZS5kZWxldGVGaWxlKFVyaS5wYXJzZShjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRGaWxlVXJpKCkpKTsKKworICAgIC8vIEJhZCBmaWxlIGlzIGRldGVjdGVkIGR1cmluZyBtYWludGVuYW5jZS4KKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmhhbmRsZVRhc2soVGFza1NjaGVkdWxlci5NQUlOVEVOQU5DRV9QRVJJT0RJQ19UQVNLKQorICAgICAgICAuZ2V0KE1BWF9IQU5ETEVfVEFTS19XQUlUX1RJTUVfU0VDUywgU0VDT05EUyk7CisKKyAgICAvLyBGaWxlIGdyb3VwIGlzIHJlLWRvd25sb2FkZWQuCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5oYW5kbGVUYXNrKFRhc2tTY2hlZHVsZXIuQ0VMTFVMQVJfQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSykKKyAgICAgICAgLmdldChNQVhfSEFORExFX1RBU0tfV0FJVF9USU1FX1NFQ1MsIFNFQ09ORFMpOworCisgICAgLy8gUmUtbG9hZCB0aGUgZmlsZSBncm91cCBzaW5jZSB0aGUgb24tZGlzayBVUklzIHdpbGwgaGF2ZSBjaGFuZ2VkLgorICAgIGNsaWVudEZpbGVHcm91cCA9IGdldEFuZFZlcmlmeUNsaWVudEZpbGVHcm91cChtb2JpbGVEYXRhRG93bmxvYWQsIEZJTEVfR1JPVVBfTkFNRSwgMSk7CisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMoVXJpLnBhcnNlKGNsaWVudEZpbGVHcm91cC5nZXRGaWxlKDApLmdldEZpbGVVcmkoKSkpKS5pc1RydWUoKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZC5jbGVhcigpLmdldCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlX3dpdGhBY2NvdW50X2ZpbGVHcm91cFJlbWFpbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllciA9CisgICAgICAgICgpIC0+CisgICAgICAgICAgICBuZXcgVGVzdEZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgICAgIFRFU1RfREFUQV9SRUxBVElWRV9QQVRILAorICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKERPV05MT0FEX0VYRUNVVE9SKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkQWZ0ZXJEb3dubG9hZCgKKyAgICAgICAgICAgIGZpbGVEb3dubG9hZGVyU3VwcGxpZXIsIG5ldyBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yKGNvbnRleHQpKTsKKworICAgIC8vIFRoaXMgd2lsbCB0cmlnZ2VyIHJlZnJlc2hpbmcgb2YgRmlsZUdyb3VwUG9wdWxhdG9ycyBhbmQgZG93bmxvYWRpbmcuCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5oYW5kbGVUYXNrKFRhc2tTY2hlZHVsZXIuQ0VMTFVMQVJfQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSykKKyAgICAgICAgLmdldChNQVhfSEFORExFX1RBU0tfV0FJVF9USU1FX1NFQ1MsIFNFQ09ORFMpOworCisgICAgLy8gUmVtb3ZlIHRoZSBmaWxlIGdyb3VwIHdpdGggYWNjb3VudCBkb2Vzbid0IGNoYW5nZSBhbnl0aGluZywgYmVjYXVzZSB0aGUgdGVzdCBncm91cCBpcyBub3QKKyAgICAvLyBhc3NvY2lhdGVkIHdpdGggYW55IGFjY291bnQuCisgICAgQWNjb3VudCBhY2NvdW50ID0gQWNjb3VudFV0aWwuY3JlYXRlKCJuYW1lIiwgImdvb2dsZSIpOworICAgIGFzc2VydFRoYXQoYWNjb3VudCkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5yZW1vdmVGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIFJlbW92ZUZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRBY2NvdW50T3B0aW9uYWwoT3B0aW9uYWwub2YoYWNjb3VudCkpCisgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKworICAgIENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXAgPQorICAgICAgICBnZXRBbmRWZXJpZnlDbGllbnRGaWxlR3JvdXAobW9iaWxlRGF0YURvd25sb2FkLCBGSUxFX0dST1VQX05BTUUsIDEpOworICAgIHZlcmlmeUNsaWVudEZpbGUoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApLCBGSUxFX0lELCBGSUxFX1NJWkUpOworICAgIG1vYmlsZURhdGFEb3dubG9hZC5jbGVhcigpLmdldCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlX3dpdGhvdXRBY2NvdW50X2ZpbGVHcm91cFJlbW92ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllciA9CisgICAgICAgICgpIC0+CisgICAgICAgICAgICBuZXcgVGVzdEZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgICAgIFRFU1RfREFUQV9SRUxBVElWRV9QQVRILAorICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKERPV05MT0FEX0VYRUNVVE9SKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkQWZ0ZXJEb3dubG9hZCgKKyAgICAgICAgICAgIGZpbGVEb3dubG9hZGVyU3VwcGxpZXIsIG5ldyBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yKGNvbnRleHQpKTsKKworICAgIC8vIFRoaXMgd2lsbCB0cmlnZ2VyIHJlZnJlc2hpbmcgb2YgRmlsZUdyb3VwUG9wdWxhdG9ycyBhbmQgZG93bmxvYWRpbmcuCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5oYW5kbGVUYXNrKFRhc2tTY2hlZHVsZXIuQ0VMTFVMQVJfQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSykKKyAgICAgICAgLmdldChNQVhfSEFORExFX1RBU0tfV0FJVF9USU1FX1NFQ1MsIFNFQ09ORFMpOworCisgICAgLy8gUmVtb3ZlIHRoZSBmaWxlIGdyb3VwIHdpbGwgbWFrZSB0aGUgZmlsZSBncm91cCBub3QgYWNjZXNzaWJsZSBmcm9tIGNsaWVudHMuCisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5yZW1vdmVGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIFJlbW92ZUZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXApLmlzTnVsbCgpOworICAgIG1vYmlsZURhdGFEb3dubG9hZC5jbGVhcigpLmdldCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQKKyAgICAgIHJlbW92ZUZpbGVHcm91cHNCeUZpbHRlcl93aGVuQWNjb3VudE5vdFNwZWNpZmllZF9yZW1vdmVzTWF0Y2hpbmdBY2NvdW50SW5kZXBlbmRlbnRHcm91cHMoKQorICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyID0KKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIG5ldyBUZXN0RmlsZURvd25sb2FkZXIoCisgICAgICAgICAgICAgICAgVEVTVF9EQVRBX1JFTEFUSVZFX1BBVEgsCisgICAgICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAgICAgTW9yZUV4ZWN1dG9ycy5saXN0ZW5pbmdEZWNvcmF0b3IoRE9XTkxPQURfRVhFQ1VUT1IpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBnZXRNb2JpbGVEYXRhRG93bmxvYWQoZmlsZURvd25sb2FkZXJTdXBwbGllciwgdW51c2VkIC0+IEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKworICAgIC8vIFJlbW92ZSBhbGwgZ3JvdXBzCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5yZW1vdmVGaWxlR3JvdXBzQnlGaWx0ZXIoUmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5uZXdCdWlsZGVyKCkuYnVpbGQoKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gU2V0dXAgYWNjb3VudAorICAgIEFjY291bnQgYWNjb3VudCA9IEFjY291bnRVdGlsLmNyZWF0ZSgibmFtZSIsICJnb29nbGUiKTsKKworICAgIC8vIFNldHVwIHR3byBncm91cHMsIDEgd2l0aCBhY2NvdW50IGFuZCAxIHdpdGhvdXQgYW4gYWNjb3VudAorICAgIERhdGFGaWxlR3JvdXAgZmlsZUdyb3VwV2l0aG91dEFjY291bnQgPQorICAgICAgICBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FLAorICAgICAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSUR9LAorICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFfSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU19LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkx9LAorICAgICAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05fQU5ZX05FVFdPUkspCisgICAgICAgICAgICAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXAgZmlsZUdyb3VwV2l0aEFjY291bnQgPQorICAgICAgICBmaWxlR3JvdXBXaXRob3V0QWNjb3VudC50b0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FICsgIl8yIikuYnVpbGQoKTsKKworICAgIC8vIEFkZCBib3RoIGdyb3VwcyB0byBNREQKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldERhdGFGaWxlR3JvdXAoZmlsZUdyb3VwV2l0aG91dEFjY291bnQpLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoKTsKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldERhdGFGaWxlR3JvdXAoZmlsZUdyb3VwV2l0aEFjY291bnQpCisgICAgICAgICAgICAgICAgLnNldEFjY291bnRPcHRpb25hbChPcHRpb25hbC5vZihhY2NvdW50KSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgYm90aCBncm91cHMgYXJlIHByZXNlbnQKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgLmdldEZpbGVHcm91cHNCeUZpbHRlcigKKyAgICAgICAgICAgICAgICAgICAgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0SW5jbHVkZUFsbEdyb3Vwcyh0cnVlKS5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmhhc1NpemUoMik7CisKKyAgICAvLyBSZW1vdmUgZmlsZSBncm91cHMgd2l0aCBnaXZlbiBzb3VyY2Ugb25seQorICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAucmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyKFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QubmV3QnVpbGRlcigpLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIENoZWNrIHRoYXQgb25seSBhY2NvdW50LWRlcGVuZGVudCBncm91cCByZW1haW5zCisgICAgSW1tdXRhYmxlTGlzdDxDbGllbnRGaWxlR3JvdXA+IHJlbWFpbmluZ0dyb3VwcyA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cHNCeUZpbHRlcigKKyAgICAgICAgICAgICAgICBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRJbmNsdWRlQWxsR3JvdXBzKHRydWUpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChyZW1haW5pbmdHcm91cHMpLmhhc1NpemUoMSk7CisgICAgYXNzZXJ0VGhhdChyZW1haW5pbmdHcm91cHMuZ2V0KDApLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FICsgIl8yIik7CisKKyAgICAvLyBUZWFyIGRvd246IHJlbW92ZSByZW1haW5pbmcgZ3JvdXAgdG8gcHJldmVudCBjcm9zcyB0ZXN0IGVycm9ycworICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAucmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyKAorICAgICAgICAgICAgUmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0QWNjb3VudE9wdGlvbmFsKE9wdGlvbmFsLm9mKGFjY291bnQpKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuZ2V0KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZF9mYWlsdXJlX3Rocm93c0Rvd25sb2FkRXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmxhZ3MubWRkRGVmYXVsdFNhbXBsZUludGVydmFsID0gT3B0aW9uYWwub2YoMSk7CisKKyAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllciA9CisgICAgICAgICgpIC0+CisgICAgICAgICAgICBuZXcgVGVzdEZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgICAgIFRFU1RfREFUQV9SRUxBVElWRV9QQVRILAorICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKERPV05MT0FEX0VYRUNVVE9SKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkKGZpbGVEb3dubG9hZGVyU3VwcGxpZXIsIG5ldyBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yKGNvbnRleHQpKTsKKworICAgIERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7Im9uZSIsICJ0d28ifSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7MTAwMCwgMjAwMH0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10geyJjaGVja3N1bTEiLCAiY2hlY2tzdW0yIn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAiaHR0cDovL3d3dy5nc3RhdGljLmNvbS8iLCAvLyBUaGlzIHVybCBpcyBub3Qgc2VjdXJlLgorICAgICAgICAgICAgICAiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vZG9lc19ub3RfZXhpc3QiIC8vIFRoaXMgdXJsIGRvZXMgbm90IGV4aXN0LgorICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05fQU5ZX05FVFdPUkspOworCisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldERhdGFGaWxlR3JvdXAoZGF0YUZpbGVHcm91cCkuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Q2xpZW50RmlsZUdyb3VwPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkuYnVpbGQoKSk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXhjZXB0aW9uID0gYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgZG93bmxvYWRGdXR1cmU6OmdldCk7CisgICAgYXNzZXJ0VGhhdChleGNlcHRpb24pLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihBZ2dyZWdhdGVFeGNlcHRpb24uY2xhc3MpOworICAgIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiBjYXVzZSA9IChBZ2dyZWdhdGVFeGNlcHRpb24pIGV4Y2VwdGlvbi5nZXRDYXVzZSgpOworICAgIGFzc2VydFRoYXQoY2F1c2UpLmlzTm90TnVsbCgpOworICAgIEltbXV0YWJsZUxpc3Q8VGhyb3dhYmxlPiBmYWlsdXJlcyA9IGNhdXNlLmdldEZhaWx1cmVzKCk7CisgICAgYXNzZXJ0VGhhdChmYWlsdXJlcykuaGFzU2l6ZSgyKTsKKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldCgwKSkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldCgxKSkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkX2ZhaWx1cmVfbG9nc0V2ZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmxhZ3MubWRkRGVmYXVsdFNhbXBsZUludGVydmFsID0gT3B0aW9uYWwub2YoMSk7CisKKyAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllciA9CisgICAgICAgICgpIC0+CisgICAgICAgICAgICBuZXcgVGVzdEZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgICAgIFRFU1RfREFUQV9SRUxBVElWRV9QQVRILAorICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKERPV05MT0FEX0VYRUNVVE9SKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkKGZpbGVEb3dubG9hZGVyU3VwcGxpZXIsIG5ldyBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yKGNvbnRleHQpKTsKKworICAgIERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IuY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7Im9uZSIsICJ0d28ifSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7MTAwMCwgMjAwMH0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10geyJjaGVja3N1bTEiLCAiY2hlY2tzdW0yIn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10geworICAgICAgICAgICAgICAiaHR0cDovL3d3dy5nc3RhdGljLmNvbS8iLCAvLyBUaGlzIHVybCBpcyBub3Qgc2VjdXJlLgorICAgICAgICAgICAgICAiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vZG9lc19ub3RfZXhpc3QiIC8vIFRoaXMgdXJsIGRvZXMgbm90IGV4aXN0LgorICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05fQU5ZX05FVFdPUkspOworCisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldERhdGFGaWxlR3JvdXAoZGF0YUZpbGVHcm91cCkuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Q2xpZW50RmlsZUdyb3VwPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkuYnVpbGQoKSk7CisKKyAgICBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCBkb3dubG9hZEZ1dHVyZTo6Z2V0KTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkX3ppcEZpbGVfdW56aXBwZWRBZnRlckRvd25sb2FkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGZpbGVEb3dubG9hZGVyU3VwcGxpZXIgPQorICAgICAgICAoKSAtPgorICAgICAgICAgICAgbmV3IFRlc3RGaWxlRG93bmxvYWRlcigKKyAgICAgICAgICAgICAgICBURVNUX0RBVEFfUkVMQVRJVkVfUEFUSCwKKyAgICAgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgICAgICBNb3JlRXhlY3V0b3JzLmxpc3RlbmluZ0RlY29yYXRvcihET1dOTE9BRF9FWEVDVVRPUikpOworCisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIGdldE1vYmlsZURhdGFEb3dubG9hZEFmdGVyRG93bmxvYWQoCisgICAgICAgICAgICBmaWxlRG93bmxvYWRlclN1cHBsaWVyLCBuZXcgWmlwRm9sZGVyRmlsZUdyb3VwUG9wdWxhdG9yKGNvbnRleHQpKTsKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgZ2V0QW5kVmVyaWZ5Q2xpZW50RmlsZUdyb3VwKAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLCBaaXBGb2xkZXJGaWxlR3JvdXBQb3B1bGF0b3IuRklMRV9HUk9VUF9OQU1FLCAzKTsKKworICAgIGZvciAoQ2xpZW50RmlsZSBjbGllbnRGaWxlIDogY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkpIHsKKyAgICAgIGlmICgiL3ppcDEudHh0Ii5lcXVhbHMoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkpIHsKKyAgICAgICAgdmVyaWZ5Q2xpZW50RmlsZShjbGllbnRGaWxlLCAiL3ppcDEudHh0IiwgMTEpOworICAgICAgfSBlbHNlIGlmICgiL3ppcDIudHh0Ii5lcXVhbHMoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkpIHsKKyAgICAgICAgdmVyaWZ5Q2xpZW50RmlsZShjbGllbnRGaWxlLCAiL3ppcDIudHh0IiwgMTEpOworICAgICAgfSBlbHNlIGlmICgiL3N1Yl9mb2xkZXIvemlwMy50eHQiLmVxdWFscyhjbGllbnRGaWxlLmdldEZpbGVJZCgpKSkgeworICAgICAgICB2ZXJpZnlDbGllbnRGaWxlKGNsaWVudEZpbGUsICIvc3ViX2ZvbGRlci96aXAzLnR4dCIsIDI1KTsKKyAgICAgIH0gZWxzZSB7CisgICAgICAgIGZhaWwoIlVuZXhwZWN0IGZpbGU6IiArIGNsaWVudEZpbGUuZ2V0RmlsZUlkKCkpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkX2NhbmNlbER1cmluZ0Rvd25sb2FkX2Rvd25sb2FkQ2FuY2VsbGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQmxvY2tpbmdGaWxlRG93bmxvYWRlciBibG9ja2luZ0ZpbGVEb3dubG9hZGVyID0gbmV3IEJsb2NraW5nRmlsZURvd25sb2FkZXIoQ09OVFJPTF9FWEVDVVRPUik7CisKKyAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmFrZUZpbGVEb3dubG9hZGVyU3VwcGxpZXIgPSAoKSAtPiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyOworCisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIGdldE1vYmlsZURhdGFEb3dubG9hZChmYWtlRmlsZURvd25sb2FkZXJTdXBwbGllciwgbmV3IFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IoY29udGV4dCkpOworCisgICAgLy8gUmVnaXN0ZXIgdGhlIGZpbGUgZ3JvdXAgYW5kIHRyaWdnZXIgZG93bmxvYWQuCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXREYXRhRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgICAgICBGSUxFX0dST1VQX05BTUUsCisgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSUR9LAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkV9LAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNfSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkx9LAorICAgICAgICAgICAgICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSykpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoKTsKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPENsaWVudEZpbGVHcm91cD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpLmJ1aWxkKCkpOworCisgICAgLy8gV2FpdCBmb3IgZG93bmxvYWQgdG8gYmUgc2NoZWR1bGVkLiBUaGUgZnV0dXJlIHNob3VsZG4ndCBiZSBkb25lIHlldC4KKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLndhaXRGb3JEb3dubG9hZFN0YXJ0ZWQoKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkRnV0dXJlLmlzRG9uZSgpKS5pc0ZhbHNlKCk7CisKKyAgICAvLyBOb3cgcmVtb3ZlIHRoZSBmaWxlIGdyb3VwIGZyb20gTURELCB3aGljaCB3b3VsZCBjYW5jZWwgYW55IG9uZ29pbmcgZG93bmxvYWQuCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5yZW1vdmVGaWxlR3JvdXAoUmVtb3ZlRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkuYnVpbGQoKSkKKyAgICAgICAgLmdldCgpOworICAgIC8vIE5vdyBsZXQgdGhlIGRvd25sb2FkIGZ1dHVyZSBmaW5pc2guCisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci5maW5pc2hEb3dubG9hZGluZygpOworCisgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGRvd25sb2FkIGhhcyBiZWVuIGNhbmNlbGVkIGFuZCBsZWFkcyB0byBjYW5jZWxsZWQgZnV0dXJlLgorICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleGNlcHRpb24gPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPiBkb3dubG9hZEZ1dHVyZS5nZXQoTUFYX0hBTkRMRV9UQVNLX1dBSVRfVElNRV9TRUNTLCBTRUNPTkRTKSk7CisgICAgYXNzZXJ0VGhhdChleGNlcHRpb24pLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihBZ2dyZWdhdGVFeGNlcHRpb24uY2xhc3MpOworICAgIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiBjYXVzZSA9IChBZ2dyZWdhdGVFeGNlcHRpb24pIGV4Y2VwdGlvbi5nZXRDYXVzZSgpOworICAgIGFzc2VydFRoYXQoY2F1c2UpLmlzTm90TnVsbCgpOworICAgIEltbXV0YWJsZUxpc3Q8VGhyb3dhYmxlPiBmYWlsdXJlcyA9IGNhdXNlLmdldEZhaWx1cmVzKCk7CisgICAgYXNzZXJ0VGhhdChmYWlsdXJlcykuaGFzU2l6ZSgxKTsKKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldCgwKSkuaXNJbnN0YW5jZU9mKENhbmNlbGxhdGlvbkV4Y2VwdGlvbi5jbGFzcyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZF90d29TdGVwRG93bmxvYWRfdGFyZ2V0RmlsZURvd25sb2FkZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllciA9CisgICAgICAgICgpIC0+CisgICAgICAgICAgICBuZXcgVGVzdEZpbGVEb3dubG9hZGVyKAorICAgICAgICAgICAgICAgIFRFU1RfREFUQV9SRUxBVElWRV9QQVRILAorICAgICAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKERPV05MT0FEX0VYRUNVVE9SKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkKGZpbGVEb3dubG9hZGVyU3VwcGxpZXIsIG5ldyBUd29TdGVwUG9wdWxhdG9yKGNvbnRleHQsIGZpbGVTdG9yYWdlKSk7CisKKyAgICAvLyBBZGQgc3RlcDEgZmlsZSBncm91cCB0byBNREQuCisgICAgRGF0YUZpbGVHcm91cCBzdGVwMUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICAic3RlcDEtZmlsZS1ncm91cCIsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICBuZXcgU3RyaW5nW10geyJzdGVwMV9pZCJ9LAorICAgICAgICAgICAgbmV3IGludFtdIHs1N30sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10geyIifSwKKyAgICAgICAgICAgIG5ldyBDaGVja3N1bVR5cGVbXSB7Q2hlY2tzdW1UeXBlLk5PTkV9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHsiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vaWNpbmcvaWRkL3NhbXBsZV9ncm91cC9zdGVwMS50eHQifSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05fQU5ZX05FVFdPUkspOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxCb29sZWFuPiB1bnVzZWQgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuYWRkRmlsZUdyb3VwKAorICAgICAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0RGF0YUZpbGVHcm91cChzdGVwMUZpbGVHcm91cCkuYnVpbGQoKSk7CisKKyAgICAvLyBUaGlzIHdpbGwgdHJpZ2dlciByZWZyZXNoaW5nIG9mIEZpbGVHcm91cFBvcHVsYXRvcnMgYW5kIGRvd25sb2FkaW5nLgorICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLkNFTExVTEFSX0NIQVJHSU5HX1BFUklPRElDX1RBU0spCisgICAgICAgIC5nZXQoTUFYX0hBTkRMRV9UQVNLX1dBSVRfVElNRV9TRUNTLCBTRUNPTkRTKTsKKworICAgIC8vIE5vdyB2ZXJpZnkgdGhhdCB0aGUgc3RlcDEtZmlsZS1ncm91cCBpcyBkb3dubG9hZGVkIGFuZCB0aGVuIFR3b1N0ZXBQb3B1bGF0b3Igd2lsbCBhZGQKKyAgICAvLyBzdGVwMi1maWxlLWdyb3VwIGFuZCBpdCB3YXMgZG93bmxvYWRlZCB0b28gaW4gb25lIGN5Y2xlIChvbmUgY2FsbCBvZiBoYW5kbGVUYXNrKS4KKworICAgIC8vIFZlcmlmeSBzdGVwMS1maWxlLWdyb3VwLgorICAgIENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXAgPQorICAgICAgICBnZXRBbmRWZXJpZnlDbGllbnRGaWxlR3JvdXAobW9iaWxlRGF0YURvd25sb2FkLCAic3RlcDEtZmlsZS1ncm91cCIsIDEpOworICAgIHZlcmlmeUNsaWVudEZpbGUoY2xpZW50RmlsZUdyb3VwLmdldEZpbGUoMCksICJzdGVwMV9pZCIsIDU3KTsKKworICAgIC8vIFZlcmlmeSBzdGVwMi1maWxlLWdyb3VwLgorICAgIGNsaWVudEZpbGVHcm91cCA9IGdldEFuZFZlcmlmeUNsaWVudEZpbGVHcm91cChtb2JpbGVEYXRhRG93bmxvYWQsICJzdGVwMi1maWxlLWdyb3VwIiwgMSk7CisgICAgdmVyaWZ5Q2xpZW50RmlsZShjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZSgwKSwgInN0ZXAyX2lkIiwgMTMpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkLmNsZWFyKCkuZ2V0KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZF9yZWxhdGl2ZUZpbGVQYXRoc19jcmVhdGVzU3ltbGlua3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBBbmRyb2lkVXJpQWRhcHRlciBhZGFwdGVyID0gQW5kcm9pZFVyaUFkYXB0ZXIuZm9yQ29udGV4dChjb250ZXh0KTsKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkKAorICAgICAgICAgICAgKCkgLT4gbmV3IFRlc3RGaWxlRG93bmxvYWRlcihURVNUX0RBVEFfUkVMQVRJVkVfUEFUSCwgZmlsZVN0b3JhZ2UsIENPTlRST0xfRVhFQ1VUT1IpLAorICAgICAgICAgICAgbmV3IFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IoY29udGV4dCkpOworCisgICAgRGF0YUZpbGVHcm91cCBmaWxlR3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXRQcmVzZXJ2ZUZpbGVuYW1lc0FuZElzb2xhdGVGaWxlcyh0cnVlKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoRklMRV9JRCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEJ5dGVTaXplKEZJTEVfU0laRSkKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtVHlwZShEYXRhRmlsZS5DaGVja3N1bVR5cGUuREVGQVVMVCkKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKEZJTEVfQ0hFQ0tTVU0pCisgICAgICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMKQorICAgICAgICAgICAgICAgICAgICAuc2V0UmVsYXRpdmVGaWxlUGF0aCgicmVsYXRpdmVfcGF0aCIpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmFkZEZpbGVHcm91cChBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXREYXRhRmlsZUdyb3VwKGZpbGVHcm91cCkuYnVpbGQoKSkKKyAgICAgICAgLmdldCgpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkuYnVpbGQoKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gdmVyaWZ5IHN5bWxpbmsgc3RydWN0dXJlCisgICAgVXJpIGV4cGVjdGVkRmlsZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0QmFzZURvd25sb2FkRGlyZWN0b3J5KGNvbnRleHQsIE9wdGlvbmFsLmFic2VudCgpKQorICAgICAgICAgICAgLmJ1aWxkVXBvbigpCisgICAgICAgICAgICAuYXBwZW5kUGF0aChEaXJlY3RvcnlVdGlsLk1ERF9TVE9SQUdFX1NZTUxJTktTKQorICAgICAgICAgICAgLmFwcGVuZFBhdGgoRGlyZWN0b3J5VXRpbC5NRERfU1RPUkFHRV9BTExfR09PR0xFX0FQUFMpCisgICAgICAgICAgICAuYXBwZW5kUGF0aChGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAuYXBwZW5kUGF0aCgicmVsYXRpdmVfcGF0aCIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAvLyB3ZSBjYW4ndCBnZXQgYWNjZXNzIHRvIHRoZSBmdWxsIGludGVybmFsIHRhcmdldCBmaWxlIHVyaSwgYnV0IHdlIGtub3cgdGhlIHN0YXJ0IG9mIGl0CisgICAgVXJpIGV4cGVjdGVkU3RhcnRUYXJnZXRVcmkgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldEJhc2VEb3dubG9hZERpcmVjdG9yeShjb250ZXh0LCBPcHRpb25hbC5hYnNlbnQoKSkKKyAgICAgICAgICAgIC5idWlsZFVwb24oKQorICAgICAgICAgICAgLmFwcGVuZFBhdGgoRGlyZWN0b3J5VXRpbC5NRERfU1RPUkFHRV9BTExfR09PR0xFX0FQUFMpCisgICAgICAgICAgICAuYXBwZW5kUGF0aCgiZGF0YWRvd25sb2FkZmlsZV8iKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisKKyAgICBVcmkgZmlsZVVyaSA9IFVyaS5wYXJzZShjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRGaWxlVXJpKCkpOworICAgIFVyaSB0YXJnZXRVcmkgPQorICAgICAgICBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkKKyAgICAgICAgICAgIC5mcm9tQWJzb2x1dGVQYXRoKHJlYWRsaW5rKGFkYXB0ZXIudG9GaWxlKGZpbGVVcmkpLmdldEFic29sdXRlUGF0aCgpKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlVXJpKS5pc0VxdWFsVG8oZXhwZWN0ZWRGaWxlVXJpKTsKKyAgICBhc3NlcnRUaGF0KHRhcmdldFVyaS50b1N0cmluZygpKS5jb250YWlucyhleHBlY3RlZFN0YXJ0VGFyZ2V0VXJpLnRvU3RyaW5nKCkpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKGZpbGVVcmkpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyh0YXJnZXRVcmkpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlbW92ZV9yZWxhdGl2ZUZpbGVQYXRoc19yZW1vdmVzU3ltbGlua3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgZ2V0TW9iaWxlRGF0YURvd25sb2FkKAorICAgICAgICAgICAgKCkgLT4gbmV3IFRlc3RGaWxlRG93bmxvYWRlcihURVNUX0RBVEFfUkVMQVRJVkVfUEFUSCwgZmlsZVN0b3JhZ2UsIENPTlRST0xfRVhFQ1VUT1IpLAorICAgICAgICAgICAgbmV3IFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IoY29udGV4dCkpOworCisgICAgRGF0YUZpbGVHcm91cCBmaWxlR3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXRQcmVzZXJ2ZUZpbGVuYW1lc0FuZElzb2xhdGVGaWxlcyh0cnVlKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoRklMRV9JRCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEJ5dGVTaXplKEZJTEVfU0laRSkKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtVHlwZShEYXRhRmlsZS5DaGVja3N1bVR5cGUuREVGQVVMVCkKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKEZJTEVfQ0hFQ0tTVU0pCisgICAgICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMKQorICAgICAgICAgICAgICAgICAgICAuc2V0UmVsYXRpdmVGaWxlUGF0aCgicmVsYXRpdmVfcGF0aCIpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmFkZEZpbGVHcm91cChBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXREYXRhRmlsZUdyb3VwKGZpbGVHcm91cCkuYnVpbGQoKSkKKyAgICAgICAgLmdldCgpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRSkuYnVpbGQoKSkKKyAgICAgICAgLmdldCgpOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cChHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworCisgICAgVXJpIGZpbGVVcmkgPSBVcmkucGFyc2UoY2xpZW50RmlsZUdyb3VwLmdldEZpbGUoMCkuZ2V0RmlsZVVyaSgpKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IGZpbGUgdXJpIGdldHMgY3JlYXRlZAorICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKGZpbGVVcmkpKS5pc1RydWUoKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAucmVtb3ZlRmlsZUdyb3VwKFJlbW92ZUZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUUpLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IGZpbGUgdXJpIHN0aWxsIGV4aXN0cyBldmVuIHRob3VnaCBmaWxlIGdyb3VwIGlzIHN0YWxlCisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMoZmlsZVVyaSkpLmlzVHJ1ZSgpOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkLm1haW50ZW5hbmNlKCkuZ2V0KCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBmaWxlIHVyaSBnZXRzIHJlbW92ZWQsIG9uY2UgbWFpbnRlbmFuY2UgcnVucworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKGZpbGVVcmkpKS5pc0ZhbHNlKCk7CisgIH0KKworICAvLyBUT0RPOiBJbXByb3ZlIHRoaXMgaGVscGVyIGJ5IGdldHRpbmcgcmlkIG9mIHRoZSBuZWVkIHRvIG5ldyBhcnJheXMgd2hlbiBpbnZva2luZworICAvLyBhbmQgdW5uYW1lZCBwYXJhbXMuIFNvbWV0aGluZyBhbG9uZyB0aGlzIGxpbmU6CisgIC8vIGNyZWF0ZURhdGFGaWxlR3JvdXAobmFtZSxwYWNrYWdlKS5hZGRGaWxlKC4uKS5hZGRGaWxlKCkuLi4KKyAgLy8gQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEgRGF0YUZpbGVncm91cC4KKyAgcHVibGljIHN0YXRpYyBEYXRhRmlsZUdyb3VwIGNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICBTdHJpbmcgZ3JvdXBOYW1lLAorICAgICAgU3RyaW5nIG93bmVyUGFja2FnZSwKKyAgICAgIFN0cmluZ1tdIGZpbGVJZCwKKyAgICAgIGludFtdIGJ5dGVTaXplLAorICAgICAgU3RyaW5nW10gY2hlY2tzdW0sCisgICAgICBDaGVja3N1bVR5cGVbXSBjaGVja3N1bVR5cGUsCisgICAgICBTdHJpbmdbXSB1cmwsCisgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5IGRldmljZU5ldHdvcmtQb2xpY3kpIHsKKyAgICBpZiAoZmlsZUlkLmxlbmd0aCAhPSBieXRlU2l6ZS5sZW5ndGgKKyAgICAgICAgfHwgZmlsZUlkLmxlbmd0aCAhPSBjaGVja3N1bS5sZW5ndGgKKyAgICAgICAgfHwgZmlsZUlkLmxlbmd0aCAhPSB1cmwubGVuZ3RoCisgICAgICAgIHx8IGNoZWNrc3VtVHlwZS5sZW5ndGggIT0gZmlsZUlkLmxlbmd0aCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIERhdGFGaWxlR3JvdXAuQnVpbGRlciBkYXRhRmlsZUdyb3VwQnVpbGRlciA9CisgICAgICAgIERhdGFGaWxlR3JvdXAubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKGdyb3VwTmFtZSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2Uob3duZXJQYWNrYWdlKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucygKKyAgICAgICAgICAgICAgICBEb3dubG9hZENvbmRpdGlvbnMubmV3QnVpbGRlcigpLnNldERldmljZU5ldHdvcmtQb2xpY3koZGV2aWNlTmV0d29ya1BvbGljeSkpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlSWQubGVuZ3RoOyArK2kpIHsKKyAgICAgIERhdGFGaWxlIGZpbGUgPQorICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAuc2V0RmlsZUlkKGZpbGVJZFtpXSkKKyAgICAgICAgICAgICAgLnNldEJ5dGVTaXplKGJ5dGVTaXplW2ldKQorICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oY2hlY2tzdW1baV0pCisgICAgICAgICAgICAgIC5zZXRDaGVja3N1bVR5cGUoY2hlY2tzdW1UeXBlW2ldKQorICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCh1cmxbaV0pCisgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgZGF0YUZpbGVHcm91cEJ1aWxkZXIuYWRkRmlsZShmaWxlKTsKKyAgICB9CisKKyAgICByZXR1cm4gZGF0YUZpbGVHcm91cEJ1aWxkZXIuYnVpbGQoKTsKKyAgfQorCisgIHByaXZhdGUgTW9iaWxlRGF0YURvd25sb2FkIGdldE1vYmlsZURhdGFEb3dubG9hZCgKKyAgICAgIFN1cHBsaWVyPEZpbGVEb3dubG9hZGVyPiBmaWxlRG93bmxvYWRlclN1cHBsaWVyLCBGaWxlR3JvdXBQb3B1bGF0b3IgZmlsZUdyb3VwUG9wdWxhdG9yKSB7CisgICAgcmV0dXJuIGdldE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIoZmlsZURvd25sb2FkZXJTdXBwbGllciwgZmlsZUdyb3VwUG9wdWxhdG9yKS5idWlsZCgpOworICB9CisKKyAgcHJpdmF0ZSBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyIGdldE1vYmlsZURhdGFEb3dubG9hZEJ1aWxkZXIoCisgICAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gZmlsZURvd25sb2FkZXJTdXBwbGllciwgRmlsZUdyb3VwUG9wdWxhdG9yIGZpbGVHcm91cFBvcHVsYXRvcikgeworICAgIHJldHVybiBNb2JpbGVEYXRhRG93bmxvYWRCdWlsZGVyLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0Q29udGV4dChjb250ZXh0KQorICAgICAgICAuc2V0Q29udHJvbEV4ZWN1dG9yKENPTlRST0xfRVhFQ1VUT1IpCisgICAgICAgIC5zZXRGaWxlRG93bmxvYWRlclN1cHBsaWVyKGZpbGVEb3dubG9hZGVyU3VwcGxpZXIpCisgICAgICAgIC5hZGRGaWxlR3JvdXBQb3B1bGF0b3IoZmlsZUdyb3VwUG9wdWxhdG9yKQorICAgICAgICAuc2V0VGFza1NjaGVkdWxlcihPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlcikpCisgICAgICAgIC5zZXRMb2dnZXJPcHRpb25hbChPcHRpb25hbC5vZihtb2NrTG9nZ2VyKSkKKyAgICAgICAgLnNldERlbHRhRGVjb2Rlck9wdGlvbmFsKE9wdGlvbmFsLmFic2VudCgpKQorICAgICAgICAuc2V0RmlsZVN0b3JhZ2UoZmlsZVN0b3JhZ2UpCisgICAgICAgIC5zZXROZXR3b3JrVXNhZ2VNb25pdG9yKG5ldHdvcmtVc2FnZU1vbml0b3IpCisgICAgICAgIC5zZXRGbGFnc09wdGlvbmFsKE9wdGlvbmFsLm9mKGZsYWdzKSk7CisgIH0KKworICAvKiogQ3JlYXRlcyBNREQgb2JqZWN0IGFuZCB0cmlnZ2VycyBoYW5kbGVUYXNrIHRvIHJlZnJlc2ggYW5kIGRvd25sb2FkIGZpbGUgZ3JvdXBzLiAqLworICBwcml2YXRlIE1vYmlsZURhdGFEb3dubG9hZCBnZXRNb2JpbGVEYXRhRG93bmxvYWRBZnRlckRvd25sb2FkKAorICAgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGZpbGVEb3dubG9hZGVyU3VwcGxpZXIsIEZpbGVHcm91cFBvcHVsYXRvciBmaWxlR3JvdXBQb3B1bGF0b3IpCisgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbiwgVGltZW91dEV4Y2VwdGlvbiB7CisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIGdldE1vYmlsZURhdGFEb3dubG9hZChmaWxlRG93bmxvYWRlclN1cHBsaWVyLCBmaWxlR3JvdXBQb3B1bGF0b3IpOworCisgICAgLy8gVGhpcyB3aWxsIHRyaWdnZXIgcmVmcmVzaGluZyBvZiBGaWxlR3JvdXBQb3B1bGF0b3JzIGFuZCBkb3dubG9hZGluZy4KKyAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgLmhhbmRsZVRhc2soVGFza1NjaGVkdWxlci5DRUxMVUxBUl9DSEFSR0lOR19QRVJJT0RJQ19UQVNLKQorICAgICAgICAuZ2V0KE1BWF9IQU5ETEVfVEFTS19XQUlUX1RJTUVfU0VDUywgU0VDT05EUyk7CisKKyAgICBTdHJpbmcgZGVidWdTdHJpbmcgPSBtb2JpbGVEYXRhRG93bmxvYWQuZ2V0RGVidWdJbmZvQXNTdHJpbmcoKTsKKyAgICBMb2cuaShUQUcsICJNREQgTGliIGR1bXA6Iik7CisgICAgZm9yIChTdHJpbmcgbGluZSA6IGRlYnVnU3RyaW5nLnNwbGl0KCJcbiIsIC0xKSkgeworICAgICAgTG9nLmkoVEFHLCBsaW5lKTsKKyAgICB9CisgICAgcmV0dXJuIG1vYmlsZURhdGFEb3dubG9hZDsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIENsaWVudEZpbGVHcm91cCBnZXRBbmRWZXJpZnlDbGllbnRGaWxlR3JvdXAoCisgICAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkLCBTdHJpbmcgZmlsZUdyb3VwTmFtZSwgaW50IGZpbGVDb3VudCkKKyAgICAgIHRocm93cyBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShmaWxlR3JvdXBOYW1lKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwKS5pc05vdE51bGwoKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKGZpbGVHcm91cE5hbWUpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oZmlsZUNvdW50KTsKKworICAgIHJldHVybiBjbGllbnRGaWxlR3JvdXA7CisgIH0KKworICBwcml2YXRlIHZvaWQgdmVyaWZ5Q2xpZW50RmlsZShDbGllbnRGaWxlIGNsaWVudEZpbGUsIFN0cmluZyBmaWxlSWQsIGludCBmaWxlU2l6ZSkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVJZCgpKS5pc0VxdWFsVG8oZmlsZUlkKTsKKyAgICBVcmkgYW5kcm9pZFVyaSA9IFVyaS5wYXJzZShjbGllbnRGaWxlLmdldEZpbGVVcmkoKSk7CisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5maWxlU2l6ZShhbmRyb2lkVXJpKSkuaXNFcXVhbFRvKGZpbGVTaXplKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL01vYmlsZURhdGFEb3dubG9hZFRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Nb2JpbGVEYXRhRG93bmxvYWRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjk4Y2QzNgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Nb2JpbGVEYXRhRG93bmxvYWRUZXN0LmphdmEKQEAgLTAsMCArMSwzNTQwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi5sYWJzLnRydXRoLkZ1dHVyZVN1YmplY3QuYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzLlVURl84OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE51bGw7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmZhaWw7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuYW55OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueUJvb2xlYW47CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuYW55TGlzdDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnlMb25nOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLmRvVGhyb3c7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8uZXE7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udGltZXM7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnZlcmlmeU5vSW50ZXJhY3Rpb25zOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnZlcmlmeU5vTW9yZUludGVyYWN0aW9uczsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by53aGVuOworCitpbXBvcnQgYW5kcm9pZC5hY2NvdW50cy5BY2NvdW50OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb24uRG93bmxvYWRSZXN1bHRDb2RlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlRhc2tTY2hlZHVsZXIuQ29uc3RyYWludE92ZXJyaWRlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5UYXNrU2NoZWR1bGVyLk5ldHdvcmtTdGF0ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5hY2NvdW50LkFjY291bnRVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuV3JpdGVTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkV2ZW50TG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuUHJvdG9Db252ZXJzaW9uVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlLkRvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubW9uaXRvci5Eb3dubG9hZFByb2dyZXNzTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZU1hcDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5sYWJzLmNvbmN1cnJlbnQuTGFic0Z1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZUNhbGxiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkNsaWVudENvbmZpZ1Byb3RvLkNsaWVudEZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuQ2xpZW50Q29uZmlnUHJvdG8uQ2xpZW50RmlsZUdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkNsaWVudENvbmZpZ1Byb3RvLkNsaWVudEZpbGVHcm91cC5TdGF0dXM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlR3JvdXA7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5Eb3dubG9hZENvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5Eb3dubG9hZENvbmRpdGlvbnMuRGV2aWNlTmV0d29ya1BvbGljeTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uR3JvdXBLZXk7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5Bbnk7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ291bnREb3duTGF0Y2g7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljQm9vbGVhbjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Bcmd1bWVudENhcHRvcjsKK2ltcG9ydCBvcmcubW9ja2l0by5DYXB0b3I7CitpbXBvcnQgb3JnLm1vY2tpdG8uTW9jazsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvSlVuaXQ7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b1J1bGU7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworLyoqIFRlc3RzIGZvciB7QGxpbmsgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuTW9iaWxlRGF0YURvd25sb2FkfS4gKi8KK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBNb2JpbGVEYXRhRG93bmxvYWRUZXN0IHsKKyAgLy8gTm90ZTogQ29udHJvbCBFeGVjdXRvciBtdXN0IG5vdCBiZSBhIHNpbmdsZSB0aHJlYWQgZXhlY3V0b3IuCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEV4ZWN1dG9yIEVYRUNVVE9SID0gRXhlY3V0b3JzLm5ld0NhY2hlZFRocmVhZFBvb2woKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBMQVRDSF9XQUlUX1RJTUVfTVMgPSAxMDAwTDsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9HUk9VUF9OQU1FXzEgPSAidGVzdC1ncm91cC0xIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfR1JPVVBfTkFNRV8yID0gInRlc3QtZ3JvdXAtMiI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0lEXzEgPSAidGVzdC1maWxlLTEiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9JRF8yID0gInRlc3QtZmlsZS0yIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfQ0hFQ0tTVU1fMSA9ICJjMWVmNzg2NGM3NmE5OWFlNzM4ZGRhZDMzODgyZWQ2NTk3MmM5OWNjIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfVVJMXzEgPSAiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vc3VnZ2VzdC1kZXYvb2R3czFfdGVzdF80LmphciI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGSUxFX1NJWkVfMSA9IDg1NzY5OworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0NIRUNLU1VNXzIgPSAiYTFjYmE5ZDg3YjE0NDBmNDFjZTllN2RhMzhjNDNlMWY2YmQ3ZDVkZiI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX1VSTF8yID0gImh0dHBzOi8vd3d3LmdzdGF0aWMuY29tL3N1Z2dlc3QtZGV2L29kd3MxX2VtcHR5LmphciI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBGSUxFX1NJWkVfMiA9IDU1NDsKKworICBwcml2YXRlIGZpbmFsIFVyaSBvbkRldmljZVVyaTEgPQorICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICJhbmRyb2lkOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8xIik7CisgIHByaXZhdGUgZmluYWwgVXJpIG9uRGV2aWNlRGlyVXJpID0KKyAgICAgIFVyaS5wYXJzZSgKKyAgICAgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkL2ZpbGVzL2RhdGFkb3dubG9hZC9zaGFyZWQvcHVibGljL2RpciIpOworICBwcml2YXRlIGZpbmFsIFVyaSBvbkRldmljZURpckZpbGVVcmkxID0KKyAgICAgIFVyaS5wYXJzZSgKKyAgICAgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkL2ZpbGVzL2RhdGFkb3dubG9hZC9zaGFyZWQvcHVibGljL2Rpci9maWxlXzEiKTsKKyAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgb25EZXZpY2VEaXJGaWxlMUNvbnRlbnQgPSAiVGVzdCBmaWxlIDEuIjsKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgb25EZXZpY2VEaXJGaWxlVXJpMiA9CisgICAgICBVcmkucGFyc2UoCisgICAgICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC9maWxlcy9kYXRhZG93bmxvYWQvc2hhcmVkL3B1YmxpYy9kaXIvZmlsZV8yIik7CisgIHByaXZhdGUgZmluYWwgU3RyaW5nIG9uRGV2aWNlRGlyRmlsZTJDb250ZW50ID0gIlRlc3QgZmlsZSAyLiI7CisgIHByaXZhdGUgZmluYWwgVXJpIG9uRGV2aWNlRGlyRmlsZVVyaTMgPQorICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICJhbmRyb2lkOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZGlyL3N1Yi9maWxlIik7CisgIHByaXZhdGUgZmluYWwgU3RyaW5nIG9uRGV2aWNlRGlyRmlsZTNDb250ZW50ID0gIlRlc3QgZmlsZSAzIGluIHN1Yi1kaXIuIjsKKworICBwcml2YXRlIGZpbmFsIEZsYWdzIGZsYWdzID0gbmV3IEZsYWdzKCkge307CisgIHByaXZhdGUgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2U7CisKKyAgQE1vY2sgRXZlbnRMb2dnZXIgbW9ja0V2ZW50TG9nZ2VyOworICBATW9jayBNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyOworICBATW9jayBUYXNrU2NoZWR1bGVyIG1vY2tUYXNrU2NoZWR1bGVyOworICBATW9jayBGaWxlR3JvdXBQb3B1bGF0b3IgbW9ja0ZpbGVHcm91cFBvcHVsYXRvcjsKKyAgQE1vY2sgRG93bmxvYWRQcm9ncmVzc01vbml0b3IgbW9ja0Rvd25sb2FkTW9uaXRvcjsKKyAgQE1vY2sgRG93bmxvYWRlciBzaW5nbGVGaWxlRG93bmxvYWRlcjsKKworICBAQ2FwdG9yIEFyZ3VtZW50Q2FwdG9yPEdyb3VwS2V5PiBncm91cEtleUNhcHRvcjsKKyAgQENhcHRvciBBcmd1bWVudENhcHRvcjxMaXN0PEdyb3VwS2V5Pj4gZ3JvdXBLZXlzQ2FwdG9yOworCisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisgICAgZmlsZVN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuYnVpbGQoKSkgLypiYWNrZW5kcyovKTsKKyAgICBjcmVhdGVGaWxlKG9uRGV2aWNlVXJpMSwgInRlc3QiKTsKKyAgICBmaWxlU3RvcmFnZS5jcmVhdGVEaXJlY3Rvcnkob25EZXZpY2VEaXJVcmkpOworICAgIGNyZWF0ZUZpbGUob25EZXZpY2VEaXJGaWxlVXJpMSwgb25EZXZpY2VEaXJGaWxlMUNvbnRlbnQpOworICAgIGNyZWF0ZUZpbGUob25EZXZpY2VEaXJGaWxlVXJpMiwgb25EZXZpY2VEaXJGaWxlMkNvbnRlbnQpOworICAgIGNyZWF0ZUZpbGUob25EZXZpY2VEaXJGaWxlVXJpMywgb25EZXZpY2VEaXJGaWxlM0NvbnRlbnQpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGNyZWF0ZUZpbGUoVXJpIHVyaSwgU3RyaW5nIGNvbnRlbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gZmlsZVN0b3JhZ2Uub3Blbih1cmksIFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgb3V0LndyaXRlKGNvbnRlbnQuZ2V0Qnl0ZXMoVVRGXzgpKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBBY2NvdW50IGFjY291bnQgPSBBY2NvdW50VXRpbC5jcmVhdGUoImFjY291bnQtbmFtZSIsICJhY2NvdW50LXR5cGUiKTsKKyAgICBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0IHJlcXVlc3QxID0KKyAgICAgICAgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWVPcHRpb25hbChPcHRpb25hbC5vZihGSUxFX0dST1VQX05BTUVfMSkpCisgICAgICAgICAgICAuc2V0QWNjb3VudE9wdGlvbmFsKE9wdGlvbmFsLm9mKGFjY291bnQpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChyZXF1ZXN0MS5ncm91cE5hbWVPcHRpb25hbCgpKS5oYXNWYWx1ZShGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChyZXF1ZXN0MS5hY2NvdW50T3B0aW9uYWwoKSkuaGFzVmFsdWUoYWNjb3VudCk7CisKKyAgICBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0IHJlcXVlc3QyID0KKyAgICAgICAgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWVPcHRpb25hbChPcHRpb25hbC5vZihGSUxFX0dST1VQX05BTUVfMSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KHJlcXVlc3QyLmdyb3VwTmFtZU9wdGlvbmFsKCkpLmhhc1ZhbHVlKEZJTEVfR1JPVVBfTkFNRV8xKTsKKyAgICBhc3NlcnRUaGF0KHJlcXVlc3QyLmFjY291bnRPcHRpb25hbCgpKS5pc0Fic2VudCgpOworCisgICAgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5CdWlsZGVyIGJ1aWxkZXIgPSBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0Lm5ld0J1aWxkZXIoKTsKKworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsIGJ1aWxkZXI6OmJ1aWxkKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdF9ncm91cFdpdGhOb0FjY291bnRPbmx5KCkgeworICAgIEFjY291bnQgYWNjb3VudCA9IEFjY291bnRVdGlsLmNyZWF0ZSgiYWNjb3VudC1uYW1lIiwgImFjY291bnQtdHlwZSIpOworICAgIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QuQnVpbGRlciBidWlsZGVyID0KKyAgICAgICAgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cFdpdGhOb0FjY291bnRPbmx5KHRydWUpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lT3B0aW9uYWwoT3B0aW9uYWwub2YoRklMRV9HUk9VUF9OQU1FXzEpKQorICAgICAgICAgICAgLnNldEFjY291bnRPcHRpb25hbChPcHRpb25hbC5vZihhY2NvdW50KSk7CisKKyAgICAvLyBNYWtlIHN1cmUgdGhhdCB3aGVuIHJlcXVlc3QgYWNjb3VudCBpbmRlcGVuZGVudCBncm91cHMsIGFjY291bnRPcHRpb25hbCBzaG91bGQgYmUgYWJzZW50LgorICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsIGJ1aWxkZXI6OmJ1aWxkKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGFkZEZpbGVHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZEludGVybmFsKAorICAgICAgICAgICAgYW55KEdyb3VwS2V5LmNsYXNzKSwgYW55KERhdGFGaWxlR3JvdXBJbnRlcm5hbC5jbGFzcyksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSkpOworICAgIERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIDEgLyogdmVyc2lvbk51bWJlciAqLywKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8xfSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05MWV9PTl9XSUZJKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0RGF0YUZpbGVHcm91cChkYXRhRmlsZUdyb3VwKS5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYWRkRmlsZUdyb3VwX29uRmFpbHVyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZEludGVybmFsKAorICAgICAgICAgICAgYW55KEdyb3VwS2V5LmNsYXNzKSwgYW55KERhdGFGaWxlR3JvdXBJbnRlcm5hbC5jbGFzcyksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmFsc2UpKTsKKyAgICBEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICAxIC8qIHZlcnNpb25OdW1iZXIgKi8sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgICAgIC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldERhdGFGaWxlR3JvdXAoZGF0YUZpbGVHcm91cCkuYnVpbGQoKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBhZGRGaWxlR3JvdXBfaW52YWxpZE93bmVyUGFja2FnZU5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWRJbnRlcm5hbCgKKyAgICAgICAgICAgIGFueShHcm91cEtleS5jbGFzcyksIGFueShEYXRhRmlsZUdyb3VwSW50ZXJuYWwuY2xhc3MpLCBhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKworICAgIC8vIE93bmVyIFBhY2thZ2Ugc2hvdWxkIGJlIHNhbWUgYXMgdGhlIGFwcCBwYWNrYWdlLgorICAgIERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgICJQQUNLQUdFX05BTUUiLAorICAgICAgICAgICAgMSAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworCisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICBudWxsIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAgICAgLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0RGF0YUZpbGVHcm91cChkYXRhRmlsZUdyb3VwKS5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGFkZEZpbGVHcm91cFdpdGhGaWxlR3JvdXBLZXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBBcmd1bWVudENhcHRvcjxHcm91cEtleT4gZ3JvdXBLZXlDYXB0b3IgPSBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhHcm91cEtleS5jbGFzcyk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkSW50ZXJuYWwoCisgICAgICAgICAgICBncm91cEtleUNhcHRvci5jYXB0dXJlKCksIGFueShEYXRhRmlsZUdyb3VwSW50ZXJuYWwuY2xhc3MpLCBhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKworICAgIERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIDEgLyogdmVyc2lvbk51bWJlciAqLywKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8xfSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05MWV9PTl9XSUZJKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBBY2NvdW50IGFjY291bnQgPSBBY2NvdW50VXRpbC5jcmVhdGUoImFjY291bnQtbmFtZSIsICJhY2NvdW50LXR5cGUiKTsKKyAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0IGFkZEZpbGVHcm91cFJlcXVlc3QgPQorICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERhdGFGaWxlR3JvdXAoZGF0YUZpbGVHcm91cCkKKyAgICAgICAgICAgIC5zZXRBY2NvdW50T3B0aW9uYWwoT3B0aW9uYWwub2YoYWNjb3VudCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQobW9iaWxlRGF0YURvd25sb2FkLmFkZEZpbGVHcm91cChhZGRGaWxlR3JvdXBSZXF1ZXN0KS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBHcm91cEtleSBncm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldEFjY291bnQoQWNjb3VudFV0aWwuc2VyaWFsaXplKGFjY291bnQpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChncm91cEtleUNhcHRvci5nZXRWYWx1ZSgpKS5pc0VxdWFsVG8oZ3JvdXBLZXkpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikKKyAgICAgICAgLmFkZEdyb3VwRm9yRG93bmxvYWRJbnRlcm5hbCgKKyAgICAgICAgICAgIGVxKGdyb3VwS2V5KSwgZXEoUHJvdG9Db252ZXJzaW9uVXRpbC5jb252ZXJ0KGRhdGFGaWxlR3JvdXApKSwgYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYWRkRmlsZUdyb3VwV2l0aEZpbGVHcm91cEtleV9vbkZhaWx1cmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBBcmd1bWVudENhcHRvcjxHcm91cEtleT4gZ3JvdXBLZXlDYXB0b3IgPSBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhHcm91cEtleS5jbGFzcyk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkSW50ZXJuYWwoCisgICAgICAgICAgICBncm91cEtleUNhcHRvci5jYXB0dXJlKCksIGFueShEYXRhRmlsZUdyb3VwSW50ZXJuYWwuY2xhc3MpLCBhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICAxIC8qIHZlcnNpb25OdW1iZXIgKi8sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgQWNjb3VudCBhY2NvdW50ID0gQWNjb3VudFV0aWwuY3JlYXRlKCJhY2NvdW50LW5hbWUiLCAiYWNjb3VudC10eXBlIik7CisgICAgQWRkRmlsZUdyb3VwUmVxdWVzdCBhZGRGaWxlR3JvdXBSZXF1ZXN0ID0KKyAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREYXRhRmlsZUdyb3VwKGRhdGFGaWxlR3JvdXApCisgICAgICAgICAgICAuc2V0QWNjb3VudE9wdGlvbmFsKE9wdGlvbmFsLm9mKGFjY291bnQpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaGF0KG1vYmlsZURhdGFEb3dubG9hZC5hZGRGaWxlR3JvdXAoYWRkRmlsZUdyb3VwUmVxdWVzdCkuZ2V0KCkpLmlzRmFsc2UoKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0QWNjb3VudChBY2NvdW50VXRpbC5zZXJpYWxpemUoYWNjb3VudCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkpLmlzRXF1YWxUbyhncm91cEtleSk7CisgICAgdmVyaWZ5KG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyKQorICAgICAgICAuYWRkR3JvdXBGb3JEb3dubG9hZEludGVybmFsKAorICAgICAgICAgICAgZXEoZ3JvdXBLZXkpLCBlcShQcm90b0NvbnZlcnNpb25VdGlsLmNvbnZlcnQoZGF0YUZpbGVHcm91cCkpLCBhbnkoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBhZGRGaWxlR3JvdXBXaXRoRmlsZUdyb3VwS2V5X251bGxBY2NvdW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQXJndW1lbnRDYXB0b3I8R3JvdXBLZXk+IGdyb3VwS2V5Q2FwdG9yID0gQXJndW1lbnRDYXB0b3IuZm9yQ2xhc3MoR3JvdXBLZXkuY2xhc3MpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZEludGVybmFsKAorICAgICAgICAgICAgZ3JvdXBLZXlDYXB0b3IuY2FwdHVyZSgpLCBhbnkoRGF0YUZpbGVHcm91cEludGVybmFsLmNsYXNzKSwgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICAxIC8qIHZlcnNpb25OdW1iZXIgKi8sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgQWRkRmlsZUdyb3VwUmVxdWVzdCBhZGRGaWxlR3JvdXBSZXF1ZXN0ID0KKyAgICAgICAgQWRkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0RGF0YUZpbGVHcm91cChkYXRhRmlsZUdyb3VwKS5idWlsZCgpOworCisgICAgYXNzZXJ0VGhhdChtb2JpbGVEYXRhRG93bmxvYWQuYWRkRmlsZUdyb3VwKGFkZEZpbGVHcm91cFJlcXVlc3QpLmdldCgpKS5pc1RydWUoKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkpLmlzRXF1YWxUbyhncm91cEtleSk7CisgICAgdmVyaWZ5KG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyKQorICAgICAgICAuYWRkR3JvdXBGb3JEb3dubG9hZEludGVybmFsKAorICAgICAgICAgICAgZXEoZ3JvdXBLZXkpLCBlcShQcm90b0NvbnZlcnNpb25VdGlsLmNvbnZlcnQoZGF0YUZpbGVHcm91cCkpLCBhbnkoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBhZGRGaWxlR3JvdXBXaXRoRmlsZUdyb3VwS2V5X3dpdGhWYXJpYW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQXJndW1lbnRDYXB0b3I8R3JvdXBLZXk+IGdyb3VwS2V5Q2FwdG9yID0gQXJndW1lbnRDYXB0b3IuZm9yQ2xhc3MoR3JvdXBLZXkuY2xhc3MpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZEludGVybmFsKAorICAgICAgICAgICAgZ3JvdXBLZXlDYXB0b3IuY2FwdHVyZSgpLCBhbnkoKSwgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXBXaXRoVmFyaWFudCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgICAgIDEgLyogdmVyc2lvbk51bWJlciAqLywKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpCisgICAgICAgICAgICAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoImVuIikKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKCkgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIEFkZEZpbGVHcm91cFJlcXVlc3QgYWRkRmlsZUdyb3VwUmVxdWVzdCA9CisgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGF0YUZpbGVHcm91cChkYXRhRmlsZUdyb3VwV2l0aFZhcmlhbnQpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkT3B0aW9uYWwoT3B0aW9uYWwub2YoImVuIikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQobW9iaWxlRGF0YURvd25sb2FkLmFkZEZpbGVHcm91cChhZGRGaWxlR3JvdXBSZXF1ZXN0KS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBHcm91cEtleSBncm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldFZhcmlhbnRJZCgiZW4iKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChncm91cEtleUNhcHRvci5nZXRWYWx1ZSgpKS5pc0VxdWFsVG8oZ3JvdXBLZXkpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikKKyAgICAgICAgLmFkZEdyb3VwRm9yRG93bmxvYWRJbnRlcm5hbCgKKyAgICAgICAgICAgIGVxKGdyb3VwS2V5KSwgZXEoUHJvdG9Db252ZXJzaW9uVXRpbC5jb252ZXJ0KGRhdGFGaWxlR3JvdXBXaXRoVmFyaWFudCkpLCBhbnkoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZW1vdmVGaWxlR3JvdXBfb25TdWNjZXNzX3JldHVybnNUcnVlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQXJndW1lbnRDYXB0b3I8R3JvdXBLZXk+IGdyb3VwS2V5Q2FwdG9yID0gQXJndW1lbnRDYXB0b3IuZm9yQ2xhc3MoR3JvdXBLZXkuY2xhc3MpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIucmVtb3ZlRmlsZUdyb3VwKGdyb3VwS2V5Q2FwdG9yLmNhcHR1cmUoKSwgZXEoZmFsc2UpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCAvKiBWb2lkICovKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgUmVtb3ZlRmlsZUdyb3VwUmVxdWVzdCByZW1vdmVGaWxlR3JvdXBSZXF1ZXN0ID0KKyAgICAgICAgUmVtb3ZlRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKS5idWlsZCgpOworCisgICAgYXNzZXJ0VGhhdChtb2JpbGVEYXRhRG93bmxvYWQucmVtb3ZlRmlsZUdyb3VwKHJlbW92ZUZpbGVHcm91cFJlcXVlc3QpLmdldCgpKS5pc1RydWUoKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkpLmlzRXF1YWxUbyhncm91cEtleSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZW1vdmVGaWxlR3JvdXBfb25GYWlsdXJlX3JldHVybnNGYWxzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEFyZ3VtZW50Q2FwdG9yPEdyb3VwS2V5PiBncm91cEtleUNhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKEdyb3VwS2V5LmNsYXNzKTsKKyAgICBkb1Rocm93KG5ldyBJT0V4Y2VwdGlvbigpKQorICAgICAgICAud2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikKKyAgICAgICAgLnJlbW92ZUZpbGVHcm91cChncm91cEtleUNhcHRvci5jYXB0dXJlKCksIC8qIHBlbmRpbmdPbmx5PSAqLyBlcShmYWxzZSkpOworCisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKCkgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIFJlbW92ZUZpbGVHcm91cFJlcXVlc3QgcmVtb3ZlRmlsZUdyb3VwUmVxdWVzdCA9CisgICAgICAgIFJlbW92ZUZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkuYnVpbGQoKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleGNlcHRpb24gPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPiBtb2JpbGVEYXRhRG93bmxvYWQucmVtb3ZlRmlsZUdyb3VwKHJlbW92ZUZpbGVHcm91cFJlcXVlc3QpLmdldCgpKTsKKyAgICBhc3NlcnRUaGF0KGV4Y2VwdGlvbikuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKElPRXhjZXB0aW9uLmNsYXNzKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkpLmlzRXF1YWxUbyhncm91cEtleSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZW1vdmVGaWxlR3JvdXBfd2l0aEFjY291bnRfcmV0dXJuc1RydWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBBcmd1bWVudENhcHRvcjxHcm91cEtleT4gZ3JvdXBLZXlDYXB0b3IgPSBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhHcm91cEtleS5jbGFzcyk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5yZW1vdmVGaWxlR3JvdXAoCisgICAgICAgICAgICBncm91cEtleUNhcHRvci5jYXB0dXJlKCksIC8qIHBlbmRpbmdPbmx5PSAqLyBlcShmYWxzZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsIC8qIFZvaWQgKi8pKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBBY2NvdW50IGFjY291bnQgPSBBY2NvdW50VXRpbC5jcmVhdGUoImFjY291bnQtbmFtZSIsICJhY2NvdW50LXR5cGUiKTsKKyAgICBSZW1vdmVGaWxlR3JvdXBSZXF1ZXN0IHJlbW92ZUZpbGVHcm91cFJlcXVlc3QgPQorICAgICAgICBSZW1vdmVGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRBY2NvdW50T3B0aW9uYWwoT3B0aW9uYWwub2YoYWNjb3VudCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQobW9iaWxlRGF0YURvd25sb2FkLnJlbW92ZUZpbGVHcm91cChyZW1vdmVGaWxlR3JvdXBSZXF1ZXN0KS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBHcm91cEtleSBncm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldEFjY291bnQoQWNjb3VudFV0aWwuc2VyaWFsaXplKGFjY291bnQpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChncm91cEtleUNhcHRvci5nZXRWYWx1ZSgpKS5pc0VxdWFsVG8oZ3JvdXBLZXkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlRmlsZUdyb3VwX3dpdGhWYXJpYW50SWRfcmV0dXJuc1RydWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBBcmd1bWVudENhcHRvcjxHcm91cEtleT4gZ3JvdXBLZXlDYXB0b3IgPSBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhHcm91cEtleS5jbGFzcyk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5yZW1vdmVGaWxlR3JvdXAoCisgICAgICAgICAgICBncm91cEtleUNhcHRvci5jYXB0dXJlKCksIC8qIHBlbmRpbmdPbmx5PSAqLyBlcShmYWxzZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsIC8qIFZvaWQgKi8pKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBSZW1vdmVGaWxlR3JvdXBSZXF1ZXN0IHJlbW92ZUZpbGVHcm91cFJlcXVlc3QgPQorICAgICAgICBSZW1vdmVGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWRPcHRpb25hbChPcHRpb25hbC5vZigiZW4iKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0VGhhdChtb2JpbGVEYXRhRG93bmxvYWQucmVtb3ZlRmlsZUdyb3VwKHJlbW92ZUZpbGVHcm91cFJlcXVlc3QpLmdldCgpKS5pc1RydWUoKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJlbiIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkpLmlzRXF1YWxUbyhncm91cEtleSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRGaWxlR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICAgICAgNSAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8xfSwKKyAgICAgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSkKKyAgICAgICAgICAgIC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEJ1aWxkSWQoMTApCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJ0ZXN0LXZhcmlhbnQiKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgZXEodHJ1ZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkYXRhRmlsZUdyb3VwKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXREYXRhRmlsZVVyaShkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShvbkRldmljZVVyaTEpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRV8xKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRPd25lclBhY2thZ2UoKSkuaXNFcXVhbFRvKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygxKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5oYXNBY2NvdW50KCkpLmlzRmFsc2UoKTsKKworICAgIENsaWVudEZpbGUgY2xpZW50RmlsZSA9IGNsaWVudEZpbGVHcm91cC5nZXRGaWxlTGlzdCgpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RmlsZUlkKCkpLmlzRXF1YWxUbyhGSUxFX0lEXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlVXJpKCkpLmlzRXF1YWxUbyhvbkRldmljZVVyaTEudG9TdHJpbmcoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRGaWxlR3JvdXBfd2l0aERpcmVjdG9yeSgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKAorICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICA1IC8qIHZlcnNpb25OdW1iZXIgKi8sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgZXEodHJ1ZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkYXRhRmlsZUdyb3VwKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXREYXRhRmlsZVVyaShkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShvbkRldmljZURpclVyaSkpOworCisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKCkgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXAgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgIC5nZXRGaWxlR3JvdXAoR2V0RmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRWZXJzaW9uTnVtYmVyKCkpLmlzRXF1YWxUbyg1KTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDMpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmhhc0FjY291bnQoKSkuaXNGYWxzZSgpOworCisgICAgTGlzdDxDbGllbnRGaWxlPiBjbGllbnRGaWxlTGlzdCA9IGNsaWVudEZpbGVHcm91cC5nZXRGaWxlTGlzdCgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUxpc3QpCisgICAgICAgIC5jb250YWlucygKKyAgICAgICAgICAgIENsaWVudEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVJZCgiL2ZpbGVfMSIpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmkob25EZXZpY2VEaXJGaWxlVXJpMS50b1N0cmluZygpKQorICAgICAgICAgICAgICAgIC5zZXRGdWxsU2l6ZUluQnl0ZXMob25EZXZpY2VEaXJGaWxlMUNvbnRlbnQuZ2V0Qnl0ZXMoVVRGXzgpLmxlbmd0aCkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlTGlzdCkKKyAgICAgICAgLmNvbnRhaW5zKAorICAgICAgICAgICAgQ2xpZW50RmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCIvZmlsZV8yIikKKyAgICAgICAgICAgICAgICAuc2V0RmlsZVVyaShvbkRldmljZURpckZpbGVVcmkyLnRvU3RyaW5nKCkpCisgICAgICAgICAgICAgICAgLnNldEZ1bGxTaXplSW5CeXRlcyhvbkRldmljZURpckZpbGUyQ29udGVudC5nZXRCeXRlcyhVVEZfOCkubGVuZ3RoKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVMaXN0KQorICAgICAgICAuY29udGFpbnMoCisgICAgICAgICAgICBDbGllbnRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoIi9zdWIvZmlsZSIpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmkob25EZXZpY2VEaXJGaWxlVXJpMy50b1N0cmluZygpKQorICAgICAgICAgICAgICAgIC5zZXRGdWxsU2l6ZUluQnl0ZXMob25EZXZpY2VEaXJGaWxlM0NvbnRlbnQuZ2V0Qnl0ZXMoVVRGXzgpLmxlbmd0aCkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRGaWxlR3JvdXBfd2l0aERpcmVjdG9yeV93aXRoVHJhdmVyc2VEaXNhYmxlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKAorICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICA1IC8qIHZlcnNpb25OdW1iZXIgKi8sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgZXEodHJ1ZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkYXRhRmlsZUdyb3VwKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXREYXRhRmlsZVVyaShkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShvbkRldmljZURpclVyaSkpOworCisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKCkgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXAgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgIC5nZXRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgR2V0RmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldFByZXNlcnZlWmlwRGlyZWN0b3JpZXModHJ1ZSkKKyAgICAgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0T3duZXJQYWNrYWdlKCkpLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldFZlcnNpb25OdW1iZXIoKSkuaXNFcXVhbFRvKDUpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuaGFzQWNjb3VudCgpKS5pc0ZhbHNlKCk7CisKKyAgICBMaXN0PENsaWVudEZpbGU+IGNsaWVudEZpbGVMaXN0ID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlTGlzdCkKKyAgICAgICAgLmNvbnRhaW5zKAorICAgICAgICAgICAgQ2xpZW50RmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCJ0ZXN0LWZpbGUtMSIpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmkob25EZXZpY2VEaXJVcmkudG9TdHJpbmcoKSkKKyAgICAgICAgICAgICAgICAuc2V0RnVsbFNpemVJbkJ5dGVzKEZJTEVfU0laRV8xKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmlzRGlyZWN0b3J5KFVyaS5wYXJzZShjbGllbnRGaWxlTGlzdC5nZXQoMCkuZ2V0RmlsZVVyaSgpKSkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyX3dpdGhBY2NvdW50U3BlY2lmaWVkX3JlbW92ZXNNYXRjaGluZ0FjY291bnRHcm91cHMoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBrZXlUb0dyb3VwTGlzdCA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgIEFjY291bnQgYWNjb3VudDEgPSBBY2NvdW50VXRpbC5jcmVhdGUoImFjY291bnQtbmFtZSIsICJhY2NvdW50LXR5cGUiKTsKKyAgICBBY2NvdW50IGFjY291bnQyID0gQWNjb3VudFV0aWwuY3JlYXRlKCJhY2NvdW50LW5hbWUyIiwgImFjY291bnQtdHlwZSIpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgICAgIC8qIHZlcnNpb25OdW1iZXIgPSAqLyA1LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8xfSwKKyAgICAgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSkKKyAgICAgICAgICAgIC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgICAgIC8qIHZlcnNpb25OdW1iZXIgPSAqLyA2LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8xfSwKKyAgICAgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSkKKyAgICAgICAgICAgIC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBHcm91cEtleSBhY2NvdW50MUdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0QWNjb3VudChBY2NvdW50VXRpbC5zZXJpYWxpemUoYWNjb3VudDEpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZG93bmxvYWRlZEFjY291bnQxR3JvdXBLZXkgPSBhY2NvdW50MUdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKyAgICBHcm91cEtleSBwZW5kaW5nQWNjb3VudDFHcm91cEtleSA9IGFjY291bnQxR3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKworICAgIEdyb3VwS2V5IGFjY291bnQyR3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FXzEpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXRBY2NvdW50KEFjY291bnRVdGlsLnNlcmlhbGl6ZShhY2NvdW50MikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBHcm91cEtleSBkb3dubG9hZGVkQWNjb3VudDJHcm91cEtleSA9IGFjY291bnQyR3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZCh0cnVlKS5idWlsZCgpOworICAgIEdyb3VwS2V5IHBlbmRpbmdBY2NvdW50Mkdyb3VwS2V5ID0gYWNjb3VudDJHcm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworCisgICAgR3JvdXBLZXkgbm9BY2NvdW50R3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FXzEpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEdyb3VwS2V5IGRvd25sb2FkZWRHcm91cEtleSA9IG5vQWNjb3VudEdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKyAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXkgPSBub0FjY291bnRHcm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworCisgICAga2V5VG9Hcm91cExpc3QuYWRkKFBhaXIuY3JlYXRlKGRvd25sb2FkZWRHcm91cEtleSwgZG93bmxvYWRlZEZpbGVHcm91cCkpOworICAgIGtleVRvR3JvdXBMaXN0LmFkZChQYWlyLmNyZWF0ZShkb3dubG9hZGVkQWNjb3VudDFHcm91cEtleSwgZG93bmxvYWRlZEZpbGVHcm91cCkpOworICAgIGtleVRvR3JvdXBMaXN0LmFkZChQYWlyLmNyZWF0ZShkb3dubG9hZGVkQWNjb3VudDJHcm91cEtleSwgZG93bmxvYWRlZEZpbGVHcm91cCkpOworICAgIGtleVRvR3JvdXBMaXN0LmFkZChQYWlyLmNyZWF0ZShwZW5kaW5nR3JvdXBLZXksIHBlbmRpbmdGaWxlR3JvdXApKTsKKyAgICBrZXlUb0dyb3VwTGlzdC5hZGQoUGFpci5jcmVhdGUocGVuZGluZ0FjY291bnQxR3JvdXBLZXksIHBlbmRpbmdGaWxlR3JvdXApKTsKKyAgICBrZXlUb0dyb3VwTGlzdC5hZGQoUGFpci5jcmVhdGUocGVuZGluZ0FjY291bnQyR3JvdXBLZXksIHBlbmRpbmdGaWxlR3JvdXApKTsKKworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0QWxsRnJlc2hHcm91cHMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoa2V5VG9Hcm91cExpc3QpKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLnJlbW92ZUZpbGVHcm91cHMoZ3JvdXBLZXlzQ2FwdG9yLmNhcHR1cmUoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIC8qIGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIC8vIFNldHVwIHJlcXVlc3QgdGhhdCBtYXRjaGVzIGFsbCBmcmVzaCBncm91cHMsIGJ1dCBhbHNvIGluY2x1ZGUgYWNjb3VudCB0byBtYWtlIHN1cmUgb25seQorICAgIC8vIGFjY291bnQgYXNzb2NpYXRlZCBmaWxlIGdyb3VwcyBhcmUgcmVtb3ZlZAorICAgIFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QgcmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCA9CisgICAgICAgIFJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0QWNjb3VudE9wdGlvbmFsKE9wdGlvbmFsLm9mKGFjY291bnQxKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgUmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyUmVzcG9uc2UgcmVzcG9uc2UgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQucmVtb3ZlRmlsZUdyb3Vwc0J5RmlsdGVyKHJlbW92ZUZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QpLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChyZXNwb25zZS5yZW1vdmVkRmlsZUdyb3Vwc0NvdW50KCkpLmlzRXF1YWxUbygxKTsKKyAgICB2ZXJpZnkobW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsIHRpbWVzKDEpKS5yZW1vdmVGaWxlR3JvdXBzKGFueUxpc3QoKSk7CisgICAgTGlzdDxHcm91cEtleT4gcmVtb3ZlZEdyb3VwS2V5cyA9IGdyb3VwS2V5c0NhcHRvci5nZXRWYWx1ZSgpOworICAgIGFzc2VydFRoYXQocmVtb3ZlZEdyb3VwS2V5cykuY29udGFpbnNFeGFjdGx5KGFjY291bnQxR3JvdXBLZXkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0RmlsZUdyb3VwX251bGxGaWxlVXJpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIDUgLyogdmVyc2lvbk51bWJlciAqLywKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8xfSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05MWV9PTl9XSUZJKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChhbnkoR3JvdXBLZXkuY2xhc3MpLCBlcSh0cnVlKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGRhdGFGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldERhdGFGaWxlVXJpKGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKSwgZGF0YUZpbGVHcm91cCkpCisgICAgICAgIC50aGVuUmV0dXJuKAorICAgICAgICAgICAgRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLlVOS05PV05fRVJST1IpCisgICAgICAgICAgICAgICAgICAgIC5zZXRNZXNzYWdlKCJGYWlsIHRvIGRvd25sb2FkIGZpbGUgZ3JvdXAiKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkpOworCisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKCkgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIGFzc2VydE51bGwoCisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cChHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FXzEpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0RmlsZUdyb3VwX251bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChhbnkoR3JvdXBLZXkuY2xhc3MpLCBlcSh0cnVlKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBhc3NlcnROdWxsKAorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgIC5nZXRGaWxlR3JvdXAoR2V0RmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpKTsKKworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tFdmVudExvZ2dlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRGaWxlR3JvdXBfd2l0aEFjY291bnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgNSAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIEFyZ3VtZW50Q2FwdG9yPEdyb3VwS2V5PiBncm91cEtleUNhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKEdyb3VwS2V5LmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChncm91cEtleUNhcHRvci5jYXB0dXJlKCksIGVxKHRydWUpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgQWNjb3VudCBhY2NvdW50ID0gQWNjb3VudFV0aWwuY3JlYXRlKCJhY2NvdW50LW5hbWUiLCAiYWNjb3VudC10eXBlIik7CisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICBHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgICAgICAgICAuc2V0QWNjb3VudE9wdGlvbmFsKE9wdGlvbmFsLm9mKGFjY291bnQpKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRV8xKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRPd25lclBhY2thZ2UoKSkuaXNFcXVhbFRvKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0QWNjb3VudCgpKS5pc0VxdWFsVG8oQWNjb3VudFV0aWwuc2VyaWFsaXplKGFjY291bnQpKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSURfMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVVcmkoKSkuaXNFcXVhbFRvKG9uRGV2aWNlVXJpMS50b1N0cmluZygpKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0QWNjb3VudChBY2NvdW50VXRpbC5zZXJpYWxpemUoYWNjb3VudCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkpLmlzRXF1YWxUbyhncm91cEtleSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRGaWxlR3JvdXBfd2l0aFZhcmlhbnRJZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKAorICAgICAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgICAgICA1IC8qIHZlcnNpb25OdW1iZXIgKi8sCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzF9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05MWV9PTl9XSUZJKQorICAgICAgICAgICAgLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJlbiIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIEFyZ3VtZW50Q2FwdG9yPEdyb3VwS2V5PiBncm91cEtleUNhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKEdyb3VwS2V5LmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChncm91cEtleUNhcHRvci5jYXB0dXJlKCksIGVxKHRydWUpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICBHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkT3B0aW9uYWwoT3B0aW9uYWwub2YoImVuIikpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0T3duZXJQYWNrYWdlKCkpLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldFZlcnNpb25OdW1iZXIoKSkuaXNFcXVhbFRvKDUpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEFjY291bnQoKSkuaXNFbXB0eSgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldFZhcmlhbnRJZCgpKS5pc0VxdWFsVG8oImVuIik7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygxKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJlbiIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkpLmlzRXF1YWxUbyhncm91cEtleSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRGaWxlR3JvdXBfaW5jbHVkZXNJZGVudGlmeWluZ1Byb3BlcnRpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBBbnkgY3VzdG9tUHJvcGVydHkgPQorICAgICAgICBBbnkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VHlwZVVybCgidHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUucHJvdG9idWYuc3RyaW5ndmFsdWUiKQorICAgICAgICAgICAgLnNldFZhbHVlKFN0cmluZ1ZhbHVlLm9mKCJURVNUX1BST1BFUlRZIikudG9CeXRlU3RyaW5nKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICAgICAgNSAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8xfSwKKyAgICAgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSkKKyAgICAgICAgICAgIC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEJ1aWxkSWQoMUwpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJ0ZXN0dmFyaWFudCIpCisgICAgICAgICAgICAuc2V0Q3VzdG9tUHJvcGVydHkoY3VzdG9tUHJvcGVydHkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGFueShHcm91cEtleS5jbGFzcyksIGVxKHRydWUpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmdldEZpbGVHcm91cChHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FXzEpLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRV8xKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRWZXJzaW9uTnVtYmVyKCkpLmlzRXF1YWxUbyg1KTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRCdWlsZElkKCkpLmlzRXF1YWxUbygxTCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0VmFyaWFudElkKCkpLmlzRXF1YWxUbygidGVzdHZhcmlhbnQiKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRDdXN0b21Qcm9wZXJ0eSgpKS5pc0VxdWFsVG8oY3VzdG9tUHJvcGVydHkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0RmlsZUdyb3VwX2luY2x1ZGVzTG9jYWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgICAgIDUgLyogdmVyc2lvbk51bWJlciAqLywKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpCisgICAgICAgICAgICAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRMb2NhbGUoImVuLVVTIikKKyAgICAgICAgICAgIC5hZGRMb2NhbGUoImVuLUNBIikKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgZXEodHJ1ZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkYXRhRmlsZUdyb3VwKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXREYXRhRmlsZVVyaShkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShvbkRldmljZVVyaTEpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldExvY2FsZUxpc3QoKSkuY29udGFpbnNFeGFjdGx5KCJlbi1VUyIsICJlbi1DQSIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0RmlsZUdyb3VwX2luY2x1ZGVzR3JvdXBMZXZlbE1ldGFkYXRhV2hlblByb3ZpZGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQW55IGN1c3RvbU1ldGFkYXRhID0KKyAgICAgICAgQW55Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFR5cGVVcmwoInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb3RvYnVmLnN0cmluZ3ZhbHVlIikKKyAgICAgICAgICAgIC5zZXRWYWx1ZShTdHJpbmdWYWx1ZS5vZigiVEVTVF9NRVRBREFUQSIpLnRvQnl0ZVN0cmluZygpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgICAgIDUgLyogdmVyc2lvbk51bWJlciAqLywKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpCisgICAgICAgICAgICAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRDdXN0b21NZXRhZGF0YShjdXN0b21NZXRhZGF0YSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgZXEodHJ1ZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkYXRhRmlsZUdyb3VwKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXREYXRhRmlsZVVyaShkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShvbkRldmljZVVyaTEpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEN1c3RvbU1ldGFkYXRhKCkpLmlzRXF1YWxUbyhjdXN0b21NZXRhZGF0YSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRGaWxlR3JvdXBfaW5jbHVkZXNGaWxlTGV2ZWxNZXRhZGF0YVdoZW5Qcm92aWRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEFueSBjdXN0b21NZXRhZGF0YSA9CisgICAgICAgIEFueS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRUeXBlVXJsKCJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5zdHJpbmd2YWx1ZSIpCisgICAgICAgICAgICAuc2V0VmFsdWUoU3RyaW5nVmFsdWUub2YoIlRFU1RfTUVUQURBVEEiKS50b0J5dGVTdHJpbmcoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgTWV0YWRhdGFQcm90by5EYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEZpbGVJZChGSUxFX0lEXzEpCisgICAgICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMXzEpCisgICAgICAgICAgICAgICAgICAgIC5zZXRDdXN0b21NZXRhZGF0YShjdXN0b21NZXRhZGF0YSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYWRkRmlsZSgKKyAgICAgICAgICAgICAgICBNZXRhZGF0YVByb3RvLkRhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKEZJTEVfSURfMikKKyAgICAgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoRklMRV9VUkxfMikKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGFueShHcm91cEtleS5jbGFzcyksIGVxKHRydWUpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXREYXRhRmlsZVVyaShkYXRhRmlsZUdyb3VwLmdldEZpbGUoMSksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShvbkRldmljZVVyaTEpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZ2V0RmlsZUdyb3VwKEdldEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmhhc0N1c3RvbU1ldGFkYXRhKCkpLmlzRmFsc2UoKTsKKworICAgIENsaWVudEZpbGUgY2xpZW50RmlsZTEgPQorICAgICAgICBjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRGaWxlSWQoKS5lcXVhbHMoRklMRV9JRF8xKQorICAgICAgICAgICAgPyBjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZSgwKQorICAgICAgICAgICAgOiBjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZSgxKTsKKyAgICBDbGllbnRGaWxlIGNsaWVudEZpbGUyID0KKyAgICAgICAgY2xpZW50RmlsZUdyb3VwLmdldEZpbGUoMCkuZ2V0RmlsZUlkKCkuZXF1YWxzKEZJTEVfSURfMSkKKyAgICAgICAgICAgID8gY2xpZW50RmlsZUdyb3VwLmdldEZpbGUoMSkKKyAgICAgICAgICAgIDogY2xpZW50RmlsZUdyb3VwLmdldEZpbGUoMCk7CisKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUxLmhhc0N1c3RvbU1ldGFkYXRhKCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZTEuZ2V0Q3VzdG9tTWV0YWRhdGEoKSkuaXNFcXVhbFRvKGN1c3RvbU1ldGFkYXRhKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUyLmhhc0N1c3RvbU1ldGFkYXRhKCkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdldEZpbGVHcm91cHNCeUZpbHRlcl9zaW5nbGVHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIExpc3Q8UGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPj4ga2V5RGF0YUZpbGVHcm91cExpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkRmlsZUdyb3VwID0KKyAgICAgICAgY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKAorICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICA1IC8qIHZlcnNpb25OdW1iZXIgKi8sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisKKyAgICBHcm91cEtleSBncm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZXEoZ3JvdXBLZXkpLCBlcSh0cnVlKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGRvd25sb2FkZWRGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldERhdGFGaWxlVXJpKAorICAgICAgICAgICAgZG93bmxvYWRlZEZpbGVHcm91cC5nZXRGaWxlKDApLCBkb3dubG9hZGVkRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisgICAga2V5RGF0YUZpbGVHcm91cExpc3QuYWRkKAorICAgICAgICBQYWlyLmNyZWF0ZShncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKHRydWUpLmJ1aWxkKCksIGRvd25sb2FkZWRGaWxlR3JvdXApKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nRmlsZUdyb3VwID0KKyAgICAgICAgY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKAorICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICA3IC8qIHZlcnNpb25OdW1iZXIgKi8sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8yfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8yfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMn0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisgICAgcGVuZGluZ0ZpbGVHcm91cCA9CisgICAgICAgIHBlbmRpbmdGaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlKDAsIHBlbmRpbmdGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkRmlsZUJ5dGVTaXplKDIyMjIyMikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChncm91cEtleSwgZmFsc2UpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShwZW5kaW5nRmlsZUdyb3VwKSk7CisgICAga2V5RGF0YUZpbGVHcm91cExpc3QuYWRkKAorICAgICAgICBQYWlyLmNyZWF0ZShncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpLCBwZW5kaW5nRmlsZUdyb3VwKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcGVuZGluZ0ZpbGVHcm91cDIgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMiwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIDQgLyogdmVyc2lvbk51bWJlciAqLywKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xLCBGSUxFX0lEXzJ9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMSwgRklMRV9TSVpFXzJ9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzEsIEZJTEVfQ0hFQ0tTVU1fMn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzEsIEZJTEVfVVJMXzJ9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIEdyb3VwS2V5IGdyb3VwS2V5MiA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMikKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXkyLCBmYWxzZSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHBlbmRpbmdGaWxlR3JvdXAyKSk7CisgICAga2V5RGF0YUZpbGVHcm91cExpc3QuYWRkKAorICAgICAgICBQYWlyLmNyZWF0ZShncm91cEtleTIudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKSwgcGVuZGluZ0ZpbGVHcm91cDIpKTsKKworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0QWxsRnJlc2hHcm91cHMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoa2V5RGF0YUZpbGVHcm91cExpc3QpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICAvLyBXZSBzaG91bGQgZ2V0IGJhY2sgMiBncm91cHMgZm9yIEZJTEVfR1JPVVBfTkFNRV8xLgorICAgIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QgZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCA9CisgICAgICAgIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lT3B0aW9uYWwoT3B0aW9uYWwub2YoRklMRV9HUk9VUF9OQU1FXzEpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgSW1tdXRhYmxlTGlzdDxDbGllbnRGaWxlR3JvdXA+IGNsaWVudEZpbGVHcm91cHMgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyKGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QpLmdldCgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwcykuaGFzU2l6ZSgyKTsKKworICAgIENsaWVudEZpbGVHcm91cCBkb3dubG9hZGVkQ2xpZW50RmlsZUdyb3VwID0gY2xpZW50RmlsZUdyb3Vwcy5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkQ2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZENsaWVudEZpbGVHcm91cC5nZXRPd25lclBhY2thZ2UoKSkuaXNFcXVhbFRvKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkQ2xpZW50RmlsZUdyb3VwLmdldFZlcnNpb25OdW1iZXIoKSkuaXNFcXVhbFRvKDUpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZENsaWVudEZpbGVHcm91cC5nZXRTdGF0dXMoKSkuaXNFcXVhbFRvKFN0YXR1cy5ET1dOTE9BREVEKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRDbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygxKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRDbGllbnRGaWxlR3JvdXAuaGFzQWNjb3VudCgpKS5pc0ZhbHNlKCk7CisKKyAgICBDbGllbnRGaWxlIGNsaWVudEZpbGUgPSBkb3dubG9hZGVkQ2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSURfMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVVcmkoKSkuaXNFcXVhbFRvKG9uRGV2aWNlVXJpMS50b1N0cmluZygpKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RnVsbFNpemVJbkJ5dGVzKCkpLmlzRXF1YWxUbyhGSUxFX1NJWkVfMSk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgcGVuZGluZ0NsaWVudEZpbGVHcm91cCA9IGNsaWVudEZpbGVHcm91cHMuZ2V0KDEpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRV8xKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0T3duZXJQYWNrYWdlKCkpLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cC5nZXRWZXJzaW9uTnVtYmVyKCkpLmlzRXF1YWxUbyg3KTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0U3RhdHVzKCkpLmlzRXF1YWxUbyhTdGF0dXMuUEVORElORyk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwLmhhc0FjY291bnQoKSkuaXNGYWxzZSgpOworCisgICAgY2xpZW50RmlsZSA9IHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVJZCgpKS5pc0VxdWFsVG8oRklMRV9JRF8xKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RG93bmxvYWRTaXplSW5CeXRlcygpKS5pc0VxdWFsVG8oMjIyMjIyKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RmlsZVVyaSgpKS5pc0VtcHR5KCk7CisKKyAgICAvLyBXZSBzaG91bGQgZ2V0IGJhY2sgMSBncm91cCBmb3IgRklMRV9HUk9VUF9OQU1FXzIuCisgICAgZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCA9CisgICAgICAgIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lT3B0aW9uYWwoT3B0aW9uYWwub2YoRklMRV9HUk9VUF9OQU1FXzIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgY2xpZW50RmlsZUdyb3VwcyA9IG1vYmlsZURhdGFEb3dubG9hZC5nZXRGaWxlR3JvdXBzQnlGaWx0ZXIoZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCkuZ2V0KCk7CisgICAgQ2xpZW50RmlsZUdyb3VwIHBlbmRpbmdDbGllbnRGaWxlR3JvdXAyID0gY2xpZW50RmlsZUdyb3Vwcy5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwMi5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRV8yKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAyLmdldE93bmVyUGFja2FnZSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAyLmdldFZlcnNpb25OdW1iZXIoKSkuaXNFcXVhbFRvKDQpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cDIuZ2V0U3RhdHVzKCkpLmlzRXF1YWxUbyhTdGF0dXMuUEVORElORyk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwMi5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDIpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cDIuaGFzQWNjb3VudCgpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRGaWxlR3JvdXBzQnlGaWx0ZXJfaW5jbHVkZUFsbEdyb3VwcygpIHRocm93cyBFeGNlcHRpb24geworICAgIExpc3Q8UGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPj4ga2V5RGF0YUZpbGVHcm91cExpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKworICAgIEFjY291bnQgYWNjb3VudCA9IEFjY291bnRVdGlsLmNyZWF0ZSgiYWNjb3VudC1uYW1lIiwgImFjY291bnQtdHlwZSIpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIDUgLyogdmVyc2lvbk51bWJlciAqLywKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8xfSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05MWV9PTl9XSUZJKTsKKyAgICBHcm91cEtleSBncm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldEFjY291bnQoQWNjb3VudFV0aWwuc2VyaWFsaXplKGFjY291bnQpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXREYXRhRmlsZVVyaSgKKyAgICAgICAgICAgIGRvd25sb2FkZWRGaWxlR3JvdXAuZ2V0RmlsZSgwKSwgZG93bmxvYWRlZEZpbGVHcm91cCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG9uRGV2aWNlVXJpMSkpOworICAgIGtleURhdGFGaWxlR3JvdXBMaXN0LmFkZCgKKyAgICAgICAgUGFpci5jcmVhdGUoZ3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZCh0cnVlKS5idWlsZCgpLCBkb3dubG9hZGVkRmlsZUdyb3VwKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcGVuZGluZ0ZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgNywKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzJ9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzJ9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8yfSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05MWV9PTl9XSUZJKTsKKyAgICBrZXlEYXRhRmlsZUdyb3VwTGlzdC5hZGQoCisgICAgICAgIFBhaXIuY3JlYXRlKGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCksIHBlbmRpbmdGaWxlR3JvdXApKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nRmlsZUdyb3VwMiA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8yLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgNCAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzEsIEZJTEVfSURfMn0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xLCBGSUxFX1NJWkVfMn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMSwgRklMRV9DSEVDS1NVTV8yfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMSwgRklMRV9VUkxfMn0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisgICAgR3JvdXBLZXkgZ3JvdXBLZXkyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8yKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChncm91cEtleTIsIGZhbHNlKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUocGVuZGluZ0ZpbGVHcm91cDIpKTsKKyAgICBrZXlEYXRhRmlsZUdyb3VwTGlzdC5hZGQoCisgICAgICAgIFBhaXIuY3JlYXRlKGdyb3VwS2V5Mi50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpLCBwZW5kaW5nRmlsZUdyb3VwMikpOworCisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRBbGxGcmVzaEdyb3VwcygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShrZXlEYXRhRmlsZUdyb3VwTGlzdCkpOworCisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKCkgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIC8vIFdlIHNob3VsZCBnZXQgYmFjayBhbGwgMyBncm91cHMgZm9yIHRoaXMga2V5LgorICAgIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QgZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCA9CisgICAgICAgIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QubmV3QnVpbGRlcigpLnNldEluY2x1ZGVBbGxHcm91cHModHJ1ZSkuYnVpbGQoKTsKKyAgICBMaXN0PENsaWVudEZpbGVHcm91cD4gY2xpZW50RmlsZUdyb3VwcyA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5nZXRGaWxlR3JvdXBzQnlGaWx0ZXIoZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXBzKS5oYXNTaXplKDMpOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGRvd25sb2FkZWRDbGllbnRGaWxlR3JvdXAgPSBjbGllbnRGaWxlR3JvdXBzLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRDbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkQ2xpZW50RmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRDbGllbnRGaWxlR3JvdXAuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkQ2xpZW50RmlsZUdyb3VwLmdldFN0YXR1cygpKS5pc0VxdWFsVG8oU3RhdHVzLkRPV05MT0FERUQpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZENsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZENsaWVudEZpbGVHcm91cC5nZXRBY2NvdW50KCkpLmlzRXF1YWxUbyhBY2NvdW50VXRpbC5zZXJpYWxpemUoYWNjb3VudCkpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gZG93bmxvYWRlZENsaWVudEZpbGVHcm91cC5nZXRGaWxlTGlzdCgpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RmlsZUlkKCkpLmlzRXF1YWxUbyhGSUxFX0lEXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlVXJpKCkpLmlzRXF1YWxUbyhvbkRldmljZVVyaTEudG9TdHJpbmcoKSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZ1bGxTaXplSW5CeXRlcygpKS5pc0VxdWFsVG8oRklMRV9TSVpFXzEpOworCisgICAgQ2xpZW50RmlsZUdyb3VwIHBlbmRpbmdDbGllbnRGaWxlR3JvdXAgPSBjbGllbnRGaWxlR3JvdXBzLmdldCgxKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNyk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwLmdldFN0YXR1cygpKS5pc0VxdWFsVG8oU3RhdHVzLlBFTkRJTkcpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cC5nZXRBY2NvdW50KCkpLmlzRXF1YWxUbyhBY2NvdW50VXRpbC5zZXJpYWxpemUoYWNjb3VudCkpOworCisgICAgY2xpZW50RmlsZSA9IHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVJZCgpKS5pc0VxdWFsVG8oRklMRV9JRF8xKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RmlsZVVyaSgpKS5pc0VtcHR5KCk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgcGVuZGluZ0NsaWVudEZpbGVHcm91cDIgPSBjbGllbnRGaWxlR3JvdXBzLmdldCgyKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAyLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzIpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cDIuZ2V0T3duZXJQYWNrYWdlKCkpLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cDIuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNCk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwMi5nZXRTdGF0dXMoKSkuaXNFcXVhbFRvKFN0YXR1cy5QRU5ESU5HKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAyLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMik7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwMi5oYXNBY2NvdW50KCkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdldEZpbGVHcm91cHNCeUZpbHRlcl9ub0RhdGEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCAqLywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0QWxsRnJlc2hHcm91cHMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoSW1tdXRhYmxlTGlzdC5vZigpKSk7CisKKyAgICBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0IGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QgPQorICAgICAgICBHZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRJbmNsdWRlQWxsR3JvdXBzKHRydWUpLmJ1aWxkKCk7CisgICAgTGlzdDxDbGllbnRGaWxlR3JvdXA+IGNsaWVudEZpbGVHcm91cHMgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyKGdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QpLmdldCgpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwcykuaXNFbXB0eSgpOworCisgICAgZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCA9CisgICAgICAgIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lT3B0aW9uYWwoT3B0aW9uYWwub2YoRklMRV9HUk9VUF9OQU1FXzEpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgY2xpZW50RmlsZUdyb3VwcyA9IG1vYmlsZURhdGFEb3dubG9hZC5nZXRGaWxlR3JvdXBzQnlGaWx0ZXIoZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXBzKS5pc0VtcHR5KCk7CisKKyAgICB2ZXJpZnlOb0ludGVyYWN0aW9ucyhtb2NrRXZlbnRMb2dnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyX3dpdGhBY2NvdW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBrZXlEYXRhRmlsZUdyb3VwTGlzdCA9IG5ldyBBcnJheUxpc3Q8PigpOworCisgICAgQWNjb3VudCBhY2NvdW50MSA9IEFjY291bnRVdGlsLmNyZWF0ZSgiYWNjb3VudC1uYW1lLTEiLCAiYWNjb3VudC10eXBlIik7CisgICAgQWNjb3VudCBhY2NvdW50MiA9IEFjY291bnRVdGlsLmNyZWF0ZSgiYWNjb3VudC1uYW1lLTIiLCAiYWNjb3VudC10eXBlIik7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZEZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgNSAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0QWNjb3VudChBY2NvdW50VXRpbC5zZXJpYWxpemUoYWNjb3VudDEpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXksIHRydWUpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkb3dubG9hZGVkRmlsZUdyb3VwKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXREYXRhRmlsZVVyaSgKKyAgICAgICAgICAgIGRvd25sb2FkZWRGaWxlR3JvdXAuZ2V0RmlsZSgwKSwgZG93bmxvYWRlZEZpbGVHcm91cCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG9uRGV2aWNlVXJpMSkpOworICAgIGtleURhdGFGaWxlR3JvdXBMaXN0LmFkZCgKKyAgICAgICAgUGFpci5jcmVhdGUoZ3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZCh0cnVlKS5idWlsZCgpLCBkb3dubG9hZGVkRmlsZUdyb3VwKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcGVuZGluZ0ZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgNyAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzJ9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGdyb3VwS2V5LCBmYWxzZSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHBlbmRpbmdGaWxlR3JvdXApKTsKKyAgICBrZXlEYXRhRmlsZUdyb3VwTGlzdC5hZGQoCisgICAgICAgIFBhaXIuY3JlYXRlKGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCksIHBlbmRpbmdGaWxlR3JvdXApKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nRmlsZUdyb3VwMiA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgNCAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzEsIEZJTEVfSURfMn0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xLCBGSUxFX1NJWkVfMn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMSwgRklMRV9DSEVDS1NVTV8yfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMSwgRklMRV9VUkxfMn0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisgICAgR3JvdXBLZXkgZ3JvdXBLZXkyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0QWNjb3VudChBY2NvdW50VXRpbC5zZXJpYWxpemUoYWNjb3VudDIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXkyLCBmYWxzZSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHBlbmRpbmdGaWxlR3JvdXAyKSk7CisgICAga2V5RGF0YUZpbGVHcm91cExpc3QuYWRkKAorICAgICAgICBQYWlyLmNyZWF0ZShncm91cEtleTIudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKSwgcGVuZGluZ0ZpbGVHcm91cDIpKTsKKworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0QWxsRnJlc2hHcm91cHMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoa2V5RGF0YUZpbGVHcm91cExpc3QpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICAvLyBXZSBzaG91bGQgZ2V0IGJhY2sgMiBncm91cHMgZm9yIEZJTEVfR1JPVVBfTkFNRV8xIHdpdGggYWNjb3VudDEuCisgICAgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCBnZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0ID0KKyAgICAgICAgR2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWVPcHRpb25hbChPcHRpb25hbC5vZihGSUxFX0dST1VQX05BTUVfMSkpCisgICAgICAgICAgICAuc2V0QWNjb3VudE9wdGlvbmFsKE9wdGlvbmFsLm9mKGFjY291bnQxKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEltbXV0YWJsZUxpc3Q8Q2xpZW50RmlsZUdyb3VwPiBjbGllbnRGaWxlR3JvdXBzID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmdldEZpbGVHcm91cHNCeUZpbHRlcihnZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0KS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cHMpLmhhc1NpemUoMik7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgZG93bmxvYWRlZENsaWVudEZpbGVHcm91cCA9IGNsaWVudEZpbGVHcm91cHMuZ2V0KDApOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZENsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRV8xKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRDbGllbnRGaWxlR3JvdXAuZ2V0T3duZXJQYWNrYWdlKCkpLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZENsaWVudEZpbGVHcm91cC5nZXRWZXJzaW9uTnVtYmVyKCkpLmlzRXF1YWxUbyg1KTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRDbGllbnRGaWxlR3JvdXAuZ2V0QWNjb3VudCgpKS5pc0VxdWFsVG8oQWNjb3VudFV0aWwuc2VyaWFsaXplKGFjY291bnQxKSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkQ2xpZW50RmlsZUdyb3VwLmdldFN0YXR1cygpKS5pc0VxdWFsVG8oU3RhdHVzLkRPV05MT0FERUQpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZENsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gZG93bmxvYWRlZENsaWVudEZpbGVHcm91cC5nZXRGaWxlTGlzdCgpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RmlsZUlkKCkpLmlzRXF1YWxUbyhGSUxFX0lEXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlVXJpKCkpLmlzRXF1YWxUbyhvbkRldmljZVVyaTEudG9TdHJpbmcoKSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZ1bGxTaXplSW5CeXRlcygpKS5pc0VxdWFsVG8oRklMRV9TSVpFXzEpOworCisgICAgQ2xpZW50RmlsZUdyb3VwIHBlbmRpbmdDbGllbnRGaWxlR3JvdXAgPSBjbGllbnRGaWxlR3JvdXBzLmdldCgxKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNyk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwLmdldEFjY291bnQoKSkuaXNFcXVhbFRvKEFjY291bnRVdGlsLnNlcmlhbGl6ZShhY2NvdW50MSkpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cC5nZXRTdGF0dXMoKSkuaXNFcXVhbFRvKFN0YXR1cy5QRU5ESU5HKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygxKTsKKworICAgIGNsaWVudEZpbGUgPSBwZW5kaW5nQ2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSURfMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVVcmkoKSkuaXNFbXB0eSgpOworCisgICAgLy8gV2Ugc2hvdWxkIGdldCBiYWNrIDEgZ3JvdXAgZm9yIEZJTEVfR1JPVVBfTkFNRV8xIHdpdGggYWNjb3VudDIuCisgICAgZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCA9CisgICAgICAgIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lT3B0aW9uYWwoT3B0aW9uYWwub2YoRklMRV9HUk9VUF9OQU1FXzEpKQorICAgICAgICAgICAgLnNldEFjY291bnRPcHRpb25hbChPcHRpb25hbC5vZihhY2NvdW50MikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBjbGllbnRGaWxlR3JvdXBzID0gbW9iaWxlRGF0YURvd25sb2FkLmdldEZpbGVHcm91cHNCeUZpbHRlcihnZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0KS5nZXQoKTsKKyAgICBDbGllbnRGaWxlR3JvdXAgcGVuZGluZ0NsaWVudEZpbGVHcm91cDIgPSBjbGllbnRGaWxlR3JvdXBzLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAyLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cDIuZ2V0T3duZXJQYWNrYWdlKCkpLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cDIuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNCk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwMi5nZXRBY2NvdW50KCkpLmlzRXF1YWxUbyhBY2NvdW50VXRpbC5zZXJpYWxpemUoYWNjb3VudDIpKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAyLmdldFN0YXR1cygpKS5pc0VxdWFsVG8oU3RhdHVzLlBFTkRJTkcpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cDIuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdldEZpbGVHcm91cHNCeUZpbHRlcl9ncm91cFdpdGhOb0FjY291bnRPbmx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBrZXlEYXRhRmlsZUdyb3VwTGlzdCA9IG5ldyBBcnJheUxpc3Q8PigpOworCisgICAgQWNjb3VudCBhY2NvdW50MSA9IEFjY291bnRVdGlsLmNyZWF0ZSgiYWNjb3VudC1uYW1lLTEiLCAiYWNjb3VudC10eXBlIik7CisgICAgQWNjb3VudCBhY2NvdW50MiA9IEFjY291bnRVdGlsLmNyZWF0ZSgiYWNjb3VudC1uYW1lLTIiLCAiYWNjb3VudC10eXBlIik7CisKKyAgICAvLyBkb3dubG9hZGVkRmlsZUdyb3VwIGlzIGFzc29jaWF0ZWQgd2l0aCBhY2NvdW50MS4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZEZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgLyp2ZXJzaW9uTnVtYmVyPSovIDUsCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSURfMX0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkxfMX0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FXzEpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXRBY2NvdW50KEFjY291bnRVdGlsLnNlcmlhbGl6ZShhY2NvdW50MSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChncm91cEtleSwgdHJ1ZSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGRvd25sb2FkZWRGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldERhdGFGaWxlVXJpKAorICAgICAgICAgICAgZG93bmxvYWRlZEZpbGVHcm91cC5nZXRGaWxlKDApLCBkb3dubG9hZGVkRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisgICAga2V5RGF0YUZpbGVHcm91cExpc3QuYWRkKAorICAgICAgICBQYWlyLmNyZWF0ZShncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKHRydWUpLmJ1aWxkKCksIGRvd25sb2FkZWRGaWxlR3JvdXApKTsKKworICAgIC8vIHBlbmRpbmdGaWxlR3JvdXAgaXMgYXNzb2NpYXRlZCB3aXRoIGFjY291bnQyLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nRmlsZUdyb3VwID0KKyAgICAgICAgY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKAorICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICAvKnZlcnNpb25OdW1iZXI9Ki8gNywKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzJ9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzJ9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8yfSwKKyAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05MWV9PTl9XSUZJKTsKKyAgICBHcm91cEtleSBncm91cEtleTIgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FXzEpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXRBY2NvdW50KEFjY291bnRVdGlsLnNlcmlhbGl6ZShhY2NvdW50MikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChncm91cEtleTIsIGZhbHNlKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUocGVuZGluZ0ZpbGVHcm91cCkpOworICAgIGtleURhdGFGaWxlR3JvdXBMaXN0LmFkZCgKKyAgICAgICAgUGFpci5jcmVhdGUoZ3JvdXBLZXkyLnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCksIHBlbmRpbmdGaWxlR3JvdXApKTsKKworICAgIC8vIHBlbmRpbmdGaWxlR3JvdXAyIGlzIGFuIGFjY291bnQgaW5kZXBlbmRlbnQgZ3JvdXAuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdGaWxlR3JvdXAyID0KKyAgICAgICAgY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKAorICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICAvKnZlcnNpb25OdW1iZXI9Ki8gNCwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xLCBGSUxFX0lEXzJ9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMSwgRklMRV9TSVpFXzJ9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzEsIEZJTEVfQ0hFQ0tTVU1fMn0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzEsIEZJTEVfVVJMXzJ9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIEdyb3VwS2V5IGdyb3VwS2V5MyA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXkzLCBmYWxzZSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHBlbmRpbmdGaWxlR3JvdXAyKSk7CisgICAga2V5RGF0YUZpbGVHcm91cExpc3QuYWRkKAorICAgICAgICBQYWlyLmNyZWF0ZShncm91cEtleTMudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKSwgcGVuZGluZ0ZpbGVHcm91cDIpKTsKKworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0QWxsRnJlc2hHcm91cHMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoa2V5RGF0YUZpbGVHcm91cExpc3QpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLypmaWxlR3JvdXBQb3B1bGF0b3JMaXN0PSovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgLypkb3dubG9hZE1vbml0b3JPcHRpb25hbD0qLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIC8qIGZvcmVncm91bmREb3dubG9hZFNlcnZpY2VDbGFzc09wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIC8vIFdlIHNob3VsZCBnZXQgYmFjayBvbmx5IDEgZ3JvdXAgZm9yIEZJTEVfR1JPVVBfTkFNRV8xIHdpdGggZ3JvdXBXaXRoTm9BY2NvdW50T25seSBiZWluZyBzZXQKKyAgICAvLyB0byB0cnVlLgorICAgIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QgZ2V0RmlsZUdyb3Vwc0J5RmlsdGVyUmVxdWVzdCA9CisgICAgICAgIEdldEZpbGVHcm91cHNCeUZpbHRlclJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBXaXRoTm9BY2NvdW50T25seSh0cnVlKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZU9wdGlvbmFsKE9wdGlvbmFsLm9mKEZJTEVfR1JPVVBfTkFNRV8xKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEltbXV0YWJsZUxpc3Q8Q2xpZW50RmlsZUdyb3VwPiBjbGllbnRGaWxlR3JvdXBzID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmdldEZpbGVHcm91cHNCeUZpbHRlcihnZXRGaWxlR3JvdXBzQnlGaWx0ZXJSZXF1ZXN0KS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cHMpLmhhc1NpemUoMSk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgcGVuZGluZ0NsaWVudEZpbGVHcm91cCA9IGNsaWVudEZpbGVHcm91cHMuZ2V0KDApOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRV8xKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0T3duZXJQYWNrYWdlKCkpLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0NsaWVudEZpbGVHcm91cC5nZXRWZXJzaW9uTnVtYmVyKCkpLmlzRXF1YWxUbyg0KTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdDbGllbnRGaWxlR3JvdXAuZ2V0U3RhdHVzKCkpLmlzRXF1YWxUbyhTdGF0dXMuUEVORElORyk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMik7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nQ2xpZW50RmlsZUdyb3VwLmhhc0FjY291bnQoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW1wb3J0RmlsZXNfd2hlblN1Y2Nlc3NmdWxfcmV0dXJucygpIHRocm93cyBFeGNlcHRpb24geworICAgIFN0cmluZyBpbmxpbmVGaWxlVXJsID0gU3RyaW5nLmZvcm1hdCgiaW5saW5lZmlsZTpzaGExOiVzIiwgRklMRV9DSEVDS1NVTV8xKTsKKyAgICBEYXRhRmlsZSBpbmxpbmVGaWxlID0KKyAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZUlkKEZJTEVfSURfMSkKKyAgICAgICAgICAgIC5zZXRCeXRlU2l6ZShGSUxFX1NJWkVfMSkKKyAgICAgICAgICAgIC5zZXRDaGVja3N1bShGSUxFX0NIRUNLU1VNXzEpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChpbmxpbmVGaWxlVXJsKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgSW1tdXRhYmxlTGlzdDxEYXRhRmlsZT4gdXBkYXRlZERhdGFGaWxlTGlzdCA9IEltbXV0YWJsZUxpc3Qub2YoaW5saW5lRmlsZSk7CisgICAgSW1tdXRhYmxlTWFwPFN0cmluZywgRmlsZVNvdXJjZT4gaW5saW5lRmlsZU1hcCA9CisgICAgICAgIEltbXV0YWJsZU1hcC5vZigKKyAgICAgICAgICAgIEZJTEVfSURfMSwgRmlsZVNvdXJjZS5vZkJ5dGVTdHJpbmcoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoIlRFU1RfQ09OVEVOVCIpKSk7CisKKyAgICAvLyBUT0RPOiByZWx5IG9uIGFjdHVhbCBpbXBsZW1lbnRhdGlvbiBvbmNlIGZlYXR1cmUgaXMgZnVsbHkgaW1wbGVtZW50ZWQuCisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5pbXBvcnRGaWxlcygKKyAgICAgICAgICAgIGFueSgpLCBhbnlMb25nKCksIGFueSgpLCBhbnkoKSwgYW55KCksIGFueSgpLCBhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLAorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICAvLyBTaW5jZSB3ZSB1c2UgbW9ja3MsIGp1c3QgY2FsbCB0aGUgbWV0aG9kIGRpcmVjdGx5LCBubyBuZWVkIHRvIGNhbGwgYWRkRmlsZUdyb3VwIGZpcnN0CisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5pbXBvcnRGaWxlcygKKyAgICAgICAgICAgIEltcG9ydEZpbGVzUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgICAgIC5zZXRCdWlsZElkKDEpCisgICAgICAgICAgICAgICAgLnNldFZhcmlhbnRJZCgidGVzdHZhcmlhbnQiKQorICAgICAgICAgICAgICAgIC5zZXRVcGRhdGVkRGF0YUZpbGVMaXN0KHVwZGF0ZWREYXRhRmlsZUxpc3QpCisgICAgICAgICAgICAgICAgLnNldElubGluZUZpbGVNYXAoaW5saW5lRmlsZU1hcCkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gVmVyaWZ5IG1vY2tzIHdlcmUgY2FsbGVkCisgICAgR3JvdXBLZXkgZXhwZWN0ZWRHcm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgSW1tdXRhYmxlTGlzdDxNZXRhZGF0YVByb3RvLkRhdGFGaWxlPiBleHBlY3RlZERhdGFGaWxlTGlzdCA9CisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoUHJvdG9Db252ZXJzaW9uVXRpbC5jb252ZXJ0RGF0YUZpbGUoaW5saW5lRmlsZSkpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikKKyAgICAgICAgLmltcG9ydEZpbGVzKAorICAgICAgICAgICAgZXEoZXhwZWN0ZWRHcm91cEtleSksCisgICAgICAgICAgICBlcSgxTCksCisgICAgICAgICAgICBlcSgidGVzdHZhcmlhbnQiKSwKKyAgICAgICAgICAgIGVxKGV4cGVjdGVkRGF0YUZpbGVMaXN0KSwKKyAgICAgICAgICAgIGVxKGlubGluZUZpbGVNYXApLAorICAgICAgICAgICAgZXEoT3B0aW9uYWwuYWJzZW50KCkpLAorICAgICAgICAgICAgYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW1wb3J0RmlsZXNfd2hlbkFjY291bnRJc1NwZWNpZmllZF91c2VzQWNjb3VudCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEFjY291bnQgYWNjb3VudCA9IEFjY291bnRVdGlsLmNyZWF0ZSgiYWNjb3VudC1uYW1lIiwgImFjY291bnQtdHlwZSIpOworICAgIFN0cmluZyBpbmxpbmVGaWxlVXJsID0gU3RyaW5nLmZvcm1hdCgiaW5saW5lZmlsZTpzaGExOiVzIiwgRklMRV9DSEVDS1NVTV8xKTsKKyAgICBEYXRhRmlsZSBpbmxpbmVGaWxlID0KKyAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZUlkKEZJTEVfSURfMSkKKyAgICAgICAgICAgIC5zZXRCeXRlU2l6ZShGSUxFX1NJWkVfMSkKKyAgICAgICAgICAgIC5zZXRDaGVja3N1bShGSUxFX0NIRUNLU1VNXzEpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChpbmxpbmVGaWxlVXJsKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgSW1tdXRhYmxlTGlzdDxEYXRhRmlsZT4gdXBkYXRlZERhdGFGaWxlTGlzdCA9IEltbXV0YWJsZUxpc3Qub2YoaW5saW5lRmlsZSk7CisgICAgSW1tdXRhYmxlTWFwPFN0cmluZywgRmlsZVNvdXJjZT4gaW5saW5lRmlsZU1hcCA9CisgICAgICAgIEltbXV0YWJsZU1hcC5vZigKKyAgICAgICAgICAgIEZJTEVfSURfMSwgRmlsZVNvdXJjZS5vZkJ5dGVTdHJpbmcoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoIlRFU1RfQ09OVEVOVCIpKSk7CisKKyAgICAvLyBUT0RPOiByZWx5IG9uIGFjdHVhbCBpbXBsZW1lbnRhdGlvbiBvbmNlIGZlYXR1cmUgaXMgZnVsbHkgaW1wbGVtZW50ZWQuCisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5pbXBvcnRGaWxlcygKKyAgICAgICAgICAgIGFueSgpLCBhbnlMb25nKCksIGFueSgpLCBhbnkoKSwgYW55KCksIGFueSgpLCBhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLAorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICAvLyBTaW5jZSB3ZSB1c2UgbW9ja3MsIGp1c3QgY2FsbCB0aGUgbWV0aG9kIGRpcmVjdGx5LCBubyBuZWVkIHRvIGNhbGwgYWRkRmlsZUdyb3VwIGZpcnN0CisgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgIC5pbXBvcnRGaWxlcygKKyAgICAgICAgICAgIEltcG9ydEZpbGVzUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgICAgIC5zZXRBY2NvdW50T3B0aW9uYWwoT3B0aW9uYWwub2YoYWNjb3VudCkpCisgICAgICAgICAgICAgICAgLnNldEJ1aWxkSWQoMSkKKyAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJ0ZXN0dmFyaWFudCIpCisgICAgICAgICAgICAgICAgLnNldFVwZGF0ZWREYXRhRmlsZUxpc3QodXBkYXRlZERhdGFGaWxlTGlzdCkKKyAgICAgICAgICAgICAgICAuc2V0SW5saW5lRmlsZU1hcChpbmxpbmVGaWxlTWFwKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuZ2V0KCk7CisKKyAgICAvLyBWZXJpZnkgbW9ja3Mgd2VyZSBjYWxsZWQKKyAgICBHcm91cEtleSBleHBlY3RlZEdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldEFjY291bnQoQWNjb3VudFV0aWwuc2VyaWFsaXplKGFjY291bnQpKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBJbW11dGFibGVMaXN0PE1ldGFkYXRhUHJvdG8uRGF0YUZpbGU+IGV4cGVjdGVkRGF0YUZpbGVMaXN0ID0KKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihQcm90b0NvbnZlcnNpb25VdGlsLmNvbnZlcnREYXRhRmlsZShpbmxpbmVGaWxlKSk7CisgICAgdmVyaWZ5KG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyKQorICAgICAgICAuaW1wb3J0RmlsZXMoCisgICAgICAgICAgICBlcShleHBlY3RlZEdyb3VwS2V5KSwKKyAgICAgICAgICAgIGVxKDFMKSwKKyAgICAgICAgICAgIGVxKCJ0ZXN0dmFyaWFudCIpLAorICAgICAgICAgICAgZXEoZXhwZWN0ZWREYXRhRmlsZUxpc3QpLAorICAgICAgICAgICAgZXEoaW5saW5lRmlsZU1hcCksCisgICAgICAgICAgICBlcShPcHRpb25hbC5hYnNlbnQoKSksCisgICAgICAgICAgICBhbnkoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbXBvcnRGaWxlc193aGVuRmFpbHNfcmV0dXJuc0ZhaWx1cmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgaW5saW5lRmlsZVVybCA9IFN0cmluZy5mb3JtYXQoImlubGluZWZpbGU6JXMiLCBGSUxFX0NIRUNLU1VNXzEpOworICAgIERhdGFGaWxlIGlubGluZUZpbGUgPQorICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlSWQoRklMRV9JRF8xKQorICAgICAgICAgICAgLnNldEJ5dGVTaXplKEZJTEVfU0laRV8xKQorICAgICAgICAgICAgLnNldENoZWNrc3VtKEZJTEVfQ0hFQ0tTVU1fMSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKGlubGluZUZpbGVVcmwpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBJbW11dGFibGVMaXN0PERhdGFGaWxlPiB1cGRhdGVkRGF0YUZpbGVMaXN0ID0gSW1tdXRhYmxlTGlzdC5vZihpbmxpbmVGaWxlKTsKKyAgICBJbW11dGFibGVNYXA8U3RyaW5nLCBGaWxlU291cmNlPiBpbmxpbmVGaWxlTWFwID0KKyAgICAgICAgSW1tdXRhYmxlTWFwLm9mKAorICAgICAgICAgICAgRklMRV9JRF8xLCBGaWxlU291cmNlLm9mQnl0ZVN0cmluZyhCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiVEVTVF9DT05URU5UIikpKTsKKworICAgIC8vIFRPRE86IHJlbHkgb24gYWN0dWFsIGltcGxlbWVudGF0aW9uIG9uY2UgZmVhdHVyZSBpcyBmdWxseSBpbXBsZW1lbnRlZC4KKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmltcG9ydEZpbGVzKAorICAgICAgICAgICAgYW55KCksIGFueUxvbmcoKSwgYW55KCksIGFueSgpLCBhbnkoKSwgYW55KCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUobmV3IEV4Y2VwdGlvbigiVGVzdCBmYWlsdXJlIikpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLAorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICAvLyBTaW5jZSB3ZSB1c2UgbW9ja3MsIGp1c3QgY2FsbCB0aGUgbWV0aG9kIGRpcmVjdGx5LCBubyBuZWVkIHRvIGNhbGwgYWRkRmlsZUdyb3VwIGZpcnN0CisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4ID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgKCkgLT4KKyAgICAgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgICAgICAgICAgLmltcG9ydEZpbGVzKAorICAgICAgICAgICAgICAgICAgICAgICAgSW1wb3J0RmlsZXNSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FXzEpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldEJ1aWxkSWQoMSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJ0ZXN0dmFyaWFudCIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFVwZGF0ZWREYXRhRmlsZUxpc3QodXBkYXRlZERhdGFGaWxlTGlzdCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0SW5saW5lRmlsZU1hcChpbmxpbmVGaWxlTWFwKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgICAgICAgICAuZ2V0KCkpOworICAgIGFzc2VydFRoYXQoZXgpLmhhc01lc3NhZ2VUaGF0KCkuY29udGFpbnMoIlRlc3QgZmFpbHVyZSIpOworCisgICAgLy8gVmVyaWZ5IG1vY2tzIHdlcmUgY2FsbGVkCisgICAgR3JvdXBLZXkgZXhwZWN0ZWRHcm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgSW1tdXRhYmxlTGlzdDxNZXRhZGF0YVByb3RvLkRhdGFGaWxlPiBleHBlY3RlZERhdGFGaWxlTGlzdCA9CisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoUHJvdG9Db252ZXJzaW9uVXRpbC5jb252ZXJ0RGF0YUZpbGUoaW5saW5lRmlsZSkpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikKKyAgICAgICAgLmltcG9ydEZpbGVzKAorICAgICAgICAgICAgZXEoZXhwZWN0ZWRHcm91cEtleSksCisgICAgICAgICAgICBlcSgxTCksCisgICAgICAgICAgICBlcSgidGVzdHZhcmlhbnQiKSwKKyAgICAgICAgICAgIGVxKGV4cGVjdGVkRGF0YUZpbGVMaXN0KSwKKyAgICAgICAgICAgIGVxKGlubGluZUZpbGVNYXApLAorICAgICAgICAgICAgZXEoT3B0aW9uYWwuYWJzZW50KCkpLAorICAgICAgICAgICAgYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgNSAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIEFyZ3VtZW50Q2FwdG9yPEdyb3VwS2V5PiBncm91cEtleUNhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKEdyb3VwS2V5LmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmRvd25sb2FkRmlsZUdyb3VwKGdyb3VwS2V5Q2FwdG9yLmNhcHR1cmUoKSwgYW55KCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrRG93bmxvYWRNb25pdG9yKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgQ291bnREb3duTGF0Y2ggb25Db21wbGV0ZUxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoCisgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25hbC5vZigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRG93bmxvYWRMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uQ29tcGxldGUoQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRPd25lclBhY2thZ2UoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0byB2ZXJpZnkgdGhhdCBvbkNvbXBsZXRlIGlzIGNhbGxlZC4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Db21wbGV0ZUxhdGNoLmNvdW50RG93bigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IG9uQ29tcGxldGUgaXMgY2FsbGVkLgorICAgIGlmICghb25Db21wbGV0ZUxhdGNoLmF3YWl0KExBVENIX1dBSVRfVElNRV9NUywgVGltZVVuaXQuTUlMTElTRUNPTkRTKSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIm9uQ29tcGxldGUgaXMgbm90IGNhbGxlZCIpOworICAgIH0KKworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRWZXJzaW9uTnVtYmVyKCkpLmlzRXF1YWxUbyg1KTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmhhc0FjY291bnQoKSkuaXNGYWxzZSgpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSURfMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVVcmkoKSkuaXNFcXVhbFRvKG9uRGV2aWNlVXJpMS50b1N0cmluZygpKTsKKworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikuZG93bmxvYWRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgYW55KCksIGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTW9uaXRvcikKKyAgICAgICAgLmFkZERvd25sb2FkTGlzdGVuZXIoZXEoRklMRV9HUk9VUF9OQU1FXzEpLCBhbnkoRG93bmxvYWRMaXN0ZW5lci5jbGFzcykpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGVxKEZJTEVfR1JPVVBfTkFNRV8xKSk7CisKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChncm91cEtleUNhcHRvci5nZXRWYWx1ZSgpLmhhc0FjY291bnQoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlR3JvdXBfZmFpbGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQXJndW1lbnRDYXB0b3I8R3JvdXBLZXk+IGdyb3VwS2V5Q2FwdG9yID0gQXJndW1lbnRDYXB0b3IuZm9yQ2xhc3MoR3JvdXBLZXkuY2xhc3MpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZG93bmxvYWRGaWxlR3JvdXAoZ3JvdXBLZXlDYXB0b3IuY2FwdHVyZSgpLCBhbnkoKSwgYW55KCkpKQorICAgICAgICAudGhlblJldHVybigKKyAgICAgICAgICAgIEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5VTktOT1dOX0VSUk9SKQorICAgICAgICAgICAgICAgICAgICAuc2V0TWVzc2FnZSgiRmFpbCB0byBkb3dubG9hZCBmaWxlIGdyb3VwIikKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgKi8sCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZE1vbml0b3IpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPENsaWVudEZpbGVHcm91cD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbCgKKyAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwub2YoCisgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRG93bmxvYWRMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uUHJvZ3Jlc3MobG9uZyBjdXJyZW50U2l6ZSkge30KKworICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Db21wbGV0ZShDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwKSB7fQorICAgICAgICAgICAgICAgICAgICAgICAgfSkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworCisgICAgQ291bnREb3duTGF0Y2ggb25GYWlsdXJlTGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKyAgICBGdXR1cmVzLmFkZENhbGxiYWNrKAorICAgICAgICBkb3dubG9hZEZ1dHVyZSwKKyAgICAgICAgbmV3IEZ1dHVyZUNhbGxiYWNrPENsaWVudEZpbGVHcm91cD4oKSB7CisgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgcHVibGljIHZvaWQgb25TdWNjZXNzKENsaWVudEZpbGVHcm91cCByZXN1bHQpIHt9CisKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgdm9pZCBvbkZhaWx1cmUoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgIC8vIFRoaXMgaXMgdG8gZW5zdXJlIHRoYXQgb25GYWlsdXJlIGlzIGNhbGxlZC4KKyAgICAgICAgICAgIG9uRmFpbHVyZUxhdGNoLmNvdW50RG93bigpOworICAgICAgICAgIH0KKyAgICAgICAgfSwKKyAgICAgICAgTW9yZUV4ZWN1dG9ycy5kaXJlY3RFeGVjdXRvcigpKTsKKworICAgIGFzc2VydFRocm93cyhFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsIGRvd25sb2FkRnV0dXJlOjpnZXQpOworICAgIERvd25sb2FkRXhjZXB0aW9uIGUgPSBMYWJzRnV0dXJlcy5nZXRGYWlsdXJlQ2F1c2VBcyhkb3dubG9hZEZ1dHVyZSwgRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIGFzc2VydFRoYXQoZSkuaGFzTWVzc2FnZVRoYXQoKS5jb250YWlucygiRmFpbCIpOworCisgICAgaWYgKCFvbkZhaWx1cmVMYXRjaC5hd2FpdChMQVRDSF9XQUlUX1RJTUVfTVMsIFRpbWVVbml0Lk1JTExJU0VDT05EUykpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJsYXRjaCB0aW1lb3V0OiBvbkZhaWx1cmUgaXMgbm90IGNhbGxlZCIpOworICAgIH0KKworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikuZG93bmxvYWRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgYW55KCksIGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTW9uaXRvcikKKyAgICAgICAgLmFkZERvd25sb2FkTGlzdGVuZXIoZXEoRklMRV9HUk9VUF9OQU1FXzEpLCBhbnkoRG93bmxvYWRMaXN0ZW5lci5jbGFzcykpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGVxKEZJTEVfR1JPVVBfTkFNRV8xKSk7CisKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChncm91cEtleUNhcHRvci5nZXRWYWx1ZSgpLmhhc0FjY291bnQoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlR3JvdXBfd2l0aEFjY291bnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgNSAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIEFyZ3VtZW50Q2FwdG9yPEdyb3VwS2V5PiBncm91cEtleUNhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKEdyb3VwS2V5LmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmRvd25sb2FkRmlsZUdyb3VwKGdyb3VwS2V5Q2FwdG9yLmNhcHR1cmUoKSwgYW55KCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrRG93bmxvYWRNb25pdG9yKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgQ291bnREb3duTGF0Y2ggb25Db21wbGV0ZUxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworCisgICAgQWNjb3VudCBhY2NvdW50ID0gQWNjb3VudFV0aWwuY3JlYXRlKCJhY2NvdW50LW5hbWUiLCAiYWNjb3VudC10eXBlIik7CisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgICAgICAgICAgLnNldEFjY291bnRPcHRpb25hbChPcHRpb25hbC5vZihhY2NvdW50KSkKKyAgICAgICAgICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoCisgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25hbC5vZigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRG93bmxvYWRMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uQ29tcGxldGUoQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRPd25lclBhY2thZ2UoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0byB2ZXJpZnkgdGhhdCBvbkNvbXBsZXRlIGlzIGNhbGxlZC4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Db21wbGV0ZUxhdGNoLmNvdW50RG93bigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IG9uQ29tcGxldGUgaXMgY2FsbGVkLgorICAgIGlmICghb25Db21wbGV0ZUxhdGNoLmF3YWl0KExBVENIX1dBSVRfVElNRV9NUywgVGltZVVuaXQuTUlMTElTRUNPTkRTKSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIm9uQ29tcGxldGUgaXMgbm90IGNhbGxlZCIpOworICAgIH0KKworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRWZXJzaW9uTnVtYmVyKCkpLmlzRXF1YWxUbyg1KTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRBY2NvdW50KCkpLmlzRXF1YWxUbyhBY2NvdW50VXRpbC5zZXJpYWxpemUoYWNjb3VudCkpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisKKyAgICBDbGllbnRGaWxlIGNsaWVudEZpbGUgPSBjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVJZCgpKS5pc0VxdWFsVG8oRklMRV9JRF8xKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RmlsZVVyaSgpKS5pc0VxdWFsVG8ob25EZXZpY2VVcmkxLnRvU3RyaW5nKCkpOworCisgICAgdmVyaWZ5KG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyKS5kb3dubG9hZEZpbGVHcm91cChhbnkoR3JvdXBLZXkuY2xhc3MpLCBhbnkoKSwgYW55KCkpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKQorICAgICAgICAuYWRkRG93bmxvYWRMaXN0ZW5lcihlcShGSUxFX0dST1VQX05BTUVfMSksIGFueShEb3dubG9hZExpc3RlbmVyLmNsYXNzKSk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZE1vbml0b3IpLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoZXEoRklMRV9HUk9VUF9OQU1FXzEpKTsKKworICAgIGFzc2VydFRoYXQoZ3JvdXBLZXlDYXB0b3IuZ2V0VmFsdWUoKS5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRV8xKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkuZ2V0QWNjb3VudCgpKS5pc0VxdWFsVG8oQWNjb3VudFV0aWwuc2VyaWFsaXplKGFjY291bnQpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkRmlsZUdyb3VwX3dpdGhWYXJpYW50SWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICAgICAgLyogdmVyc2lvbk51bWJlciA9ICovIDUsCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7RklMRV9TSVpFXzF9LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9DSEVDS1NVTV8xfSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05MWV9PTl9XSUZJKQorICAgICAgICAgICAgLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJlbiIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIEFyZ3VtZW50Q2FwdG9yPEdyb3VwS2V5PiBncm91cEtleUNhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKEdyb3VwS2V5LmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmRvd25sb2FkRmlsZUdyb3VwKGdyb3VwS2V5Q2FwdG9yLmNhcHR1cmUoKSwgYW55KCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ICovLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrRG93bmxvYWRNb25pdG9yKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgICAgICAgICAgLnNldFZhcmlhbnRJZE9wdGlvbmFsKE9wdGlvbmFsLm9mKCJlbiIpKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldFZhcmlhbnRJZCgpKS5pc0VxdWFsVG8oImVuIik7CisKKyAgICB2ZXJpZnkobW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIpLmRvd25sb2FkRmlsZUdyb3VwKGFueShHcm91cEtleS5jbGFzcyksIGFueSgpLCBhbnkoKSk7CisKKyAgICBHcm91cEtleSBleHBlY3RlZEdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJlbiIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkpLmlzRXF1YWxUbyhleHBlY3RlZEdyb3VwS2V5KTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkRmlsZUdyb3VwV2l0aEZvcmVncm91bmRTZXJ2aWNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIC8qIHZlcnNpb25OdW1iZXIgPSAqLyA1LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIEFyZ3VtZW50Q2FwdG9yPEdyb3VwS2V5PiBncm91cEtleUNhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKEdyb3VwS2V5LmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmRvd25sb2FkRmlsZUdyb3VwKGdyb3VwS2V5Q2FwdG9yLmNhcHR1cmUoKSwgYW55KCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXlDYXB0b3IuY2FwdHVyZSgpLCBhbnlCb29sZWFuKCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkYXRhRmlsZUdyb3VwKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZE1vbml0b3IpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwKKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgQ291bnREb3duTGF0Y2ggb25Db21wbGV0ZUxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworCisgICAgQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZAorICAgICAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwV2l0aEZvcmVncm91bmRTZXJ2aWNlKAorICAgICAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEdyb3VwTmFtZShGSUxFX0dST1VQX05BTUVfMSkKKyAgICAgICAgICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoCisgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25hbC5vZigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgRG93bmxvYWRMaXN0ZW5lcigpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uQ29tcGxldGUoQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRPd25lclBhY2thZ2UoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0byB2ZXJpZnkgdGhhdCBvbkNvbXBsZXRlIGlzIGNhbGxlZC4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Db21wbGV0ZUxhdGNoLmNvdW50RG93bigpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5nZXQoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IG9uQ29tcGxldGUgaXMgY2FsbGVkLgorICAgIGlmICghb25Db21wbGV0ZUxhdGNoLmF3YWl0KExBVENIX1dBSVRfVElNRV9NUywgVGltZVVuaXQuTUlMTElTRUNPTkRTKSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oIm9uQ29tcGxldGUgaXMgbm90IGNhbGxlZCIpOworICAgIH0KKworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRWZXJzaW9uTnVtYmVyKCkpLmlzRXF1YWxUbyg1KTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmhhc0FjY291bnQoKSkuaXNGYWxzZSgpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSURfMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVVcmkoKSkuaXNFcXVhbFRvKG9uRGV2aWNlVXJpMS50b1N0cmluZygpKTsKKworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikuZG93bmxvYWRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgYW55KCksIGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTW9uaXRvcikKKyAgICAgICAgLmFkZERvd25sb2FkTGlzdGVuZXIoZXEoRklMRV9HUk9VUF9OQU1FXzEpLCBhbnkoRG93bmxvYWRMaXN0ZW5lci5jbGFzcykpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGVxKEZJTEVfR1JPVVBfTkFNRV8xKSk7CisKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChncm91cEtleUNhcHRvci5nZXRWYWx1ZSgpLmhhc0FjY291bnQoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlR3JvdXBXaXRoRm9yZWdyb3VuZFNlcnZpY2VfZmFpbGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIC8qIHZlcnNpb25OdW1iZXIgPSAqLyA1LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIEFyZ3VtZW50Q2FwdG9yPEdyb3VwS2V5PiBncm91cEtleUNhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKEdyb3VwS2V5LmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmRvd25sb2FkRmlsZUdyb3VwKGdyb3VwS2V5Q2FwdG9yLmNhcHR1cmUoKSwgYW55KCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oCisgICAgICAgICAgICBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUikKKyAgICAgICAgICAgICAgICAgICAgLnNldE1lc3NhZ2UoIkZhaWwgdG8gZG93bmxvYWQgZmlsZSBncm91cCIpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXlDYXB0b3IuY2FwdHVyZSgpLCBlcShmYWxzZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkYXRhRmlsZUdyb3VwKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXlDYXB0b3IuY2FwdHVyZSgpLCBlcSh0cnVlKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Q2xpZW50RmlsZUdyb3VwPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5kb3dubG9hZEZpbGVHcm91cFdpdGhGb3JlZ3JvdW5kU2VydmljZSgKKyAgICAgICAgICAgIERvd25sb2FkRmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgICAgIC5zZXRMaXN0ZW5lck9wdGlvbmFsKAorICAgICAgICAgICAgICAgICAgICBPcHRpb25hbC5vZigKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBEb3dubG9hZExpc3RlbmVyKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkNvbXBsZXRlKENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXApIHt9CisgICAgICAgICAgICAgICAgICAgICAgICB9KSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICBDb3VudERvd25MYXRjaCBvbkZhaWx1cmVMYXRjaCA9IG5ldyBDb3VudERvd25MYXRjaCgxKTsKKworICAgIEZ1dHVyZXMuYWRkQ2FsbGJhY2soCisgICAgICAgIGRvd25sb2FkRnV0dXJlLAorICAgICAgICBuZXcgRnV0dXJlQ2FsbGJhY2s8Q2xpZW50RmlsZUdyb3VwPigpIHsKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoQ2xpZW50RmlsZUdyb3VwIHJlc3VsdCkge30KKworICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgIHB1YmxpYyB2b2lkIG9uRmFpbHVyZShUaHJvd2FibGUgdCkgeworICAgICAgICAgICAgLy8gVGhpcyBpcyB0byBlbnN1cmUgdGhhdCBvbkZhaWx1cmUgaXMgY2FsbGVkLgorICAgICAgICAgICAgb25GYWlsdXJlTGF0Y2guY291bnREb3duKCk7CisgICAgICAgICAgfQorICAgICAgICB9LAorICAgICAgICBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCkpOworCisgICAgYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgZG93bmxvYWRGdXR1cmU6OmdldCk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gZSA9IExhYnNGdXR1cmVzLmdldEZhaWx1cmVDYXVzZUFzKGRvd25sb2FkRnV0dXJlLCBEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgYXNzZXJ0VGhhdChlKS5oYXNNZXNzYWdlVGhhdCgpLmNvbnRhaW5zKCJGYWlsIik7CisKKyAgICBpZiAoIW9uRmFpbHVyZUxhdGNoLmF3YWl0KExBVENIX1dBSVRfVElNRV9NUywgVGltZVVuaXQuTUlMTElTRUNPTkRTKSkgeworICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oImxhdGNoIHRpbWVvdXQ6IG9uRmFpbHVyZSBpcyBub3QgY2FsbGVkIik7CisgICAgfQorCisgICAgdmVyaWZ5KG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyKS5kb3dubG9hZEZpbGVHcm91cChhbnkoR3JvdXBLZXkuY2xhc3MpLCBhbnkoKSwgYW55KCkpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKQorICAgICAgICAuYWRkRG93bmxvYWRMaXN0ZW5lcihlcShGSUxFX0dST1VQX05BTUVfMSksIGFueShEb3dubG9hZExpc3RlbmVyLmNsYXNzKSk7CisKKyAgICAvLyBTbGVlcCBmb3IgMSBzZWMgdG8gd2FpdCBmb3IgdGhlIGxpc3RlbmVyLm9uRmFpbHVyZSB0byBmaW5pc2guCisgICAgVGhyZWFkLnNsZWVwKC8qbWlsbGlzPSovIDEwMDApOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGVxKEZJTEVfR1JPVVBfTkFNRV8xKSk7CisKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChncm91cEtleUNhcHRvci5nZXRWYWx1ZSgpLmhhc0FjY291bnQoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlR3JvdXBXaXRoRm9yZWdyb3VuZFNlcnZpY2Vfd2l0aEFjY291bnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgNSAvKiB2ZXJzaW9uTnVtYmVyICovLAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIEFyZ3VtZW50Q2FwdG9yPEdyb3VwS2V5PiBncm91cEtleUNhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKEdyb3VwS2V5LmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmRvd25sb2FkRmlsZUdyb3VwKGdyb3VwS2V5Q2FwdG9yLmNhcHR1cmUoKSwgYW55KCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXlDYXB0b3IuY2FwdHVyZSgpLCBlcShmYWxzZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkYXRhRmlsZUdyb3VwKSk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoZ3JvdXBLZXlDYXB0b3IuY2FwdHVyZSgpLCBlcSh0cnVlKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIENvdW50RG93bkxhdGNoIG9uQ29tcGxldGVMYXRjaCA9IG5ldyBDb3VudERvd25MYXRjaCgxKTsKKworICAgIEFjY291bnQgYWNjb3VudCA9IEFjY291bnRVdGlsLmNyZWF0ZSgiYWNjb3VudC1uYW1lIiwgImFjY291bnQtdHlwZSIpOworICAgIENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXAgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cFdpdGhGb3JlZ3JvdW5kU2VydmljZSgKKyAgICAgICAgICAgICAgICBEb3dubG9hZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FXzEpCisgICAgICAgICAgICAgICAgICAgIC5zZXRBY2NvdW50T3B0aW9uYWwoT3B0aW9uYWwub2YoYWNjb3VudCkpCisgICAgICAgICAgICAgICAgICAgIC5zZXRMaXN0ZW5lck9wdGlvbmFsKAorICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwub2YoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERvd25sb2FkTGlzdGVuZXIoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uUHJvZ3Jlc3MobG9uZyBjdXJyZW50U2l6ZSkge30KKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkNvbXBsZXRlKENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRV8xKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0T3duZXJQYWNrYWdlKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaXNFcXVhbFRvKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldFZlcnNpb25OdW1iZXIoKSkuaXNFcXVhbFRvKDUpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdG8gdmVyaWZ5IHRoYXQgb25Db21wbGV0ZSBpcyBjYWxsZWQuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ29tcGxldGVMYXRjaC5jb3VudERvd24oKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuZ2V0KCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBvbkNvbXBsZXRlIGlzIGNhbGxlZC4KKyAgICBpZiAoIW9uQ29tcGxldGVMYXRjaC5hd2FpdChMQVRDSF9XQUlUX1RJTUVfTVMsIFRpbWVVbml0Lk1JTExJU0VDT05EUykpIHsKKyAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKCJvbkNvbXBsZXRlIGlzIG5vdCBjYWxsZWQiKTsKKyAgICB9CisKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfTkFNRV8xKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRPd25lclBhY2thZ2UoKSkuaXNFcXVhbFRvKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0VmVyc2lvbk51bWJlcigpKS5pc0VxdWFsVG8oNSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0QWNjb3VudCgpKS5pc0VxdWFsVG8oQWNjb3VudFV0aWwuc2VyaWFsaXplKGFjY291bnQpKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDEpOworCisgICAgQ2xpZW50RmlsZSBjbGllbnRGaWxlID0gY2xpZW50RmlsZUdyb3VwLmdldEZpbGVMaXN0KCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZS5nZXRGaWxlSWQoKSkuaXNFcXVhbFRvKEZJTEVfSURfMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVVcmkoKSkuaXNFcXVhbFRvKG9uRGV2aWNlVXJpMS50b1N0cmluZygpKTsKKworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikuZG93bmxvYWRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgYW55KCksIGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTW9uaXRvcikKKyAgICAgICAgLmFkZERvd25sb2FkTGlzdGVuZXIoZXEoRklMRV9HUk9VUF9OQU1FXzEpLCBhbnkoRG93bmxvYWRMaXN0ZW5lci5jbGFzcykpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGVxKEZJTEVfR1JPVVBfTkFNRV8xKSk7CisKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5Q2FwdG9yLmdldFZhbHVlKCkuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChncm91cEtleUNhcHRvci5nZXRWYWx1ZSgpLmdldEFjY291bnQoKSkuaXNFcXVhbFRvKEFjY291bnRVdGlsLnNlcmlhbGl6ZShhY2NvdW50KSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZEZpbGVHcm91cFdpdGhGb3JlZ3JvdW5kU2VydmljZV93aXRoVmFyaWFudElkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICAgICAgRklMRV9HUk9VUF9OQU1FXzEsCisgICAgICAgICAgICAgICAgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpLAorICAgICAgICAgICAgICAgIC8qIHZlcnNpb25OdW1iZXIgPSAqLyA1LAorICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRF8xfSwKKyAgICAgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTF8xfSwKKyAgICAgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSkKKyAgICAgICAgICAgIC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFZhcmlhbnRJZCgiZW4iKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBBcmd1bWVudENhcHRvcjxHcm91cEtleT4gZ3JvdXBLZXlDYXB0b3IgPSBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhHcm91cEtleS5jbGFzcyk7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5kb3dubG9hZEZpbGVHcm91cChncm91cEtleUNhcHRvci5jYXB0dXJlKCksIGFueSgpLCBhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGRhdGFGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldERhdGFGaWxlVXJpKGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKSwgZGF0YUZpbGVHcm91cCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG9uRGV2aWNlVXJpMSkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGdyb3VwS2V5Q2FwdG9yLmNhcHR1cmUoKSwgZXEoZmFsc2UpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGdyb3VwS2V5Q2FwdG9yLmNhcHR1cmUoKSwgZXEodHJ1ZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZE1vbml0b3IpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXBXaXRoRm9yZWdyb3VuZFNlcnZpY2UoCisgICAgICAgICAgICAgICAgRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgICAgICAgICAuc2V0VmFyaWFudElkT3B0aW9uYWwoT3B0aW9uYWwub2YoImVuIikpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0VmFyaWFudElkKCkpLmlzRXF1YWxUbygiZW4iKTsKKworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikuZG93bmxvYWRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgYW55KCksIGFueSgpKTsKKworICAgIEdyb3VwS2V5IGV4cGVjdGVkR3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FXzEpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoImVuIikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZ3JvdXBLZXlDYXB0b3IuZ2V0VmFsdWUoKSkuaXNFcXVhbFRvKGV4cGVjdGVkR3JvdXBLZXkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRGaWxlR3JvdXBXaXRoRm9yZWdyb3VuZFNlcnZpY2Vfd2hlbkFscmVhZHlEb3dubG9hZGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUVfMSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIC8qIHZlcnNpb25OdW1iZXIgPSAqLyA1LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkVfMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU1fMX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTkxZX09OX1dJRkkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUob25EZXZpY2VVcmkxKSk7CisKKyAgICAvLyBNb2NrIHNpdHVhdGlvbjogbm8gcGVuZGluZyBncm91cCBidXQgdGhlcmUgaXMgYSBkb3dubG9hZGVkIGdyb3VwCisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5nZXRGaWxlR3JvdXAoYW55KCksIGVxKGZhbHNlKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChhbnkoKSwgZXEodHJ1ZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkYXRhRmlsZUdyb3VwKSk7CisKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZE1vbml0b3IpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBDb3VudERvd25MYXRjaCBvbkNvbXBsZXRlTGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKyAgICBDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkCisgICAgICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXBXaXRoRm9yZWdyb3VuZFNlcnZpY2UoCisgICAgICAgICAgICAgICAgRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbCgKKyAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsLm9mKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBEb3dubG9hZExpc3RlbmVyKCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblByb2dyZXNzKGxvbmcgY3VycmVudFNpemUpIHt9CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Db21wbGV0ZShDbGllbnRGaWxlR3JvdXAgY2xpZW50RmlsZUdyb3VwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldE93bmVyUGFja2FnZSgpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGVHcm91cC5nZXRWZXJzaW9uTnVtYmVyKCkpLmlzRXF1YWxUbyg1KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygxKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRvIHZlcmlmeSB0aGF0IG9uQ29tcGxldGUgaXMgY2FsbGVkLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNvbXBsZXRlTGF0Y2guY291bnREb3duKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgb25Db21wbGV0ZSBpcyBjYWxsZWQuCisgICAgaWYgKCFvbkNvbXBsZXRlTGF0Y2guYXdhaXQoTEFUQ0hfV0FJVF9USU1FX01TLCBUaW1lVW5pdC5NSUxMSVNFQ09ORFMpKSB7CisgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigib25Db21wbGV0ZSBpcyBub3QgY2FsbGVkIik7CisgICAgfQorCisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuZ2V0T3duZXJQYWNrYWdlKCkpLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldFZlcnNpb25OdW1iZXIoKSkuaXNFcXVhbFRvKDUpOworICAgIGFzc2VydFRoYXQoY2xpZW50RmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlR3JvdXAuaGFzQWNjb3VudCgpKS5pc0ZhbHNlKCk7CisKKyAgICBDbGllbnRGaWxlIGNsaWVudEZpbGUgPSBjbGllbnRGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChjbGllbnRGaWxlLmdldEZpbGVJZCgpKS5pc0VxdWFsVG8oRklMRV9JRF8xKTsKKyAgICBhc3NlcnRUaGF0KGNsaWVudEZpbGUuZ2V0RmlsZVVyaSgpKS5pc0VxdWFsVG8ob25EZXZpY2VVcmkxLnRvU3RyaW5nKCkpOworCisgICAgdmVyaWZ5KG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLCB0aW1lcygxKSkuZ2V0RmlsZUdyb3VwKGFueShHcm91cEtleS5jbGFzcyksIGVxKHRydWUpKTsKKyAgICB2ZXJpZnkobW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsIHRpbWVzKDEpKS5nZXRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgZXEoZmFsc2UpKTsKKyAgICB2ZXJpZnkobW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsIHRpbWVzKDApKQorICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAoYW55KEdyb3VwS2V5LmNsYXNzKSwgYW55KCksIGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTW9uaXRvcikKKyAgICAgICAgLmFkZERvd25sb2FkTGlzdGVuZXIoZXEoRklMRV9HUk9VUF9OQU1FXzEpLCBhbnkoRG93bmxvYWRMaXN0ZW5lci5jbGFzcykpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGVxKEZJTEVfR1JPVVBfTkFNRV8xKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZEZpbGVHcm91cFdpdGhGb3JlZ3JvdW5kU2VydmljZV93aGVuTm9WZXJzaW9uRm91bmRfZmFpbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChncm91cEtleUNhcHRvci5jYXB0dXJlKCksIGFueUJvb2xlYW4oKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIENvdW50RG93bkxhdGNoIG9uRmFpbHVyZUxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxDbGllbnRGaWxlR3JvdXA+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmRvd25sb2FkRmlsZUdyb3VwV2l0aEZvcmVncm91bmRTZXJ2aWNlKAorICAgICAgICAgICAgRG93bmxvYWRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoRklMRV9HUk9VUF9OQU1FXzEpCisgICAgICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoCisgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsLm9mKAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3IERvd25sb2FkTGlzdGVuZXIoKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvblByb2dyZXNzKGxvbmcgY3VycmVudFNpemUpIHt9CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIG9uQ29tcGxldGUoQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoIm9uQ29tcGxldGUgc2hvdWxkIG5vdCBiZSBjYWxsZWQiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaWMgdm9pZCBvbkZhaWx1cmUoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KHQpLmlzSW5zdGFuY2VPZihEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0VGhhdCgoKERvd25sb2FkRXhjZXB0aW9uKSB0KS5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuR1JPVVBfTk9UX0ZPVU5EX0VSUk9SKTsKKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdG8gdmVyaWZ5IG9uRmFpbHVyZSBpcyBjYWxsZWQuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25GYWlsdXJlTGF0Y2guY291bnREb3duKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIH0pKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKworICAgIGFzc2VydFRocm93cyhFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsIGRvd25sb2FkRnV0dXJlOjpnZXQpOworCisgICAgLy8gVmVyaWZ5IG9uRmFpbHVyZSBpcyBjYWxsZWQKKyAgICBpZiAoIW9uRmFpbHVyZUxhdGNoLmF3YWl0KExBVENIX1dBSVRfVElNRV9NUywgVGltZVVuaXQuTUlMTElTRUNPTkRTKSkgeworICAgICAgZmFpbCgib25GYWlsdXJlIHNob3VsZCBiZSBjYWxsZWQiKTsKKyAgICB9CisKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBlID0gTGFic0Z1dHVyZXMuZ2V0RmFpbHVyZUNhdXNlQXMoZG93bmxvYWRGdXR1cmUsIERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBhc3NlcnRUaGF0KGUuZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuR1JPVVBfTk9UX0ZPVU5EX0VSUk9SKTsKKworICAgIC8vIFZlcmlmeSBkaWQgbm90IGF0dGVtcHQgYSBkb3dubG9hZAorICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwgdGltZXMoMCkpCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cChhbnkoR3JvdXBLZXkuY2xhc3MpLCBhbnkoKSwgYW55KCkpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yLCB0aW1lcygwKSkKKyAgICAgICAgLmFkZERvd25sb2FkTGlzdGVuZXIoZXEoRklMRV9HUk9VUF9OQU1FXzEpLCBhbnkoRG93bmxvYWRMaXN0ZW5lci5jbGFzcykpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbWFpbnRlbmFuY2Vfc3VjY2VzcygpIHRocm93cyBFeGNlcHRpb24geworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLypmaWxlR3JvdXBQb3B1bGF0b3JMaXN0PSovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgLypkb3dubG9hZE1vbml0b3JPcHRpb25hbD0qLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5tYWludGVuYW5jZSgpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZC5tYWludGVuYW5jZSgpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyKS5tYWludGVuYW5jZSgpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtYWludGVuYW5jZV9mYWlsdXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICAvKmZpbGVHcm91cFBvcHVsYXRvckxpc3Q9Ki8gSW1tdXRhYmxlTGlzdC5vZigpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAvKmRvd25sb2FkTW9uaXRvck9wdGlvbmFsPSovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLm1haW50ZW5hbmNlKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKG5ldyBJT0V4Y2VwdGlvbigidGVzdC1mYWlsdXJlIikpKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBlID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gbW9iaWxlRGF0YURvd25sb2FkLm1haW50ZW5hbmNlKCkuZ2V0KCkpOworICAgIGFzc2VydFRoYXQoZSkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKElPRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBhc3NlcnRUaGF0KGUpLmhhc0NhdXNlVGhhdCgpLmhhc01lc3NhZ2VUaGF0KCkuaXNFcXVhbFRvKCJ0ZXN0LWZhaWx1cmUiKTsKKworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikubWFpbnRlbmFuY2UoKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2NoZWR1bGVQZXJpb2RpY1Rhc2tzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ID0gKi8gSW1tdXRhYmxlTGlzdC5vZigpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuc2NoZWR1bGVQZXJpb2RpY1Rhc2tzKCk7CisKKyAgICB2ZXJpZnkobW9ja1Rhc2tTY2hlZHVsZXIpCisgICAgICAgIC5zY2hlZHVsZVBlcmlvZGljVGFzaygKKyAgICAgICAgICAgIFRhc2tTY2hlZHVsZXIuQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSywKKyAgICAgICAgICAgIChuZXcgRmxhZ3MoKSB7fSkuY2hhcmdpbmdHY21UYXNrUGVyaW9kKCksCisgICAgICAgICAgICBOZXR3b3JrU3RhdGUuTkVUV09SS19TVEFURV9BTlksCisgICAgICAgICAgICAvKiBjb25zdHJhaW50T3ZlcnJpZGVzID0gKi8gT3B0aW9uYWwuYWJzZW50KCkpOworCisgICAgdmVyaWZ5KG1vY2tUYXNrU2NoZWR1bGVyKQorICAgICAgICAuc2NoZWR1bGVQZXJpb2RpY1Rhc2soCisgICAgICAgICAgICBUYXNrU2NoZWR1bGVyLk1BSU5URU5BTkNFX1BFUklPRElDX1RBU0ssCisgICAgICAgICAgICAobmV3IEZsYWdzKCkge30pLm1haW50ZW5hbmNlR2NtVGFza1BlcmlvZCgpLAorICAgICAgICAgICAgTmV0d29ya1N0YXRlLk5FVFdPUktfU1RBVEVfQU5ZLAorICAgICAgICAgICAgLyogY29uc3RyYWludE92ZXJyaWRlcyA9ICovIE9wdGlvbmFsLmFic2VudCgpKTsKKworICAgIHZlcmlmeShtb2NrVGFza1NjaGVkdWxlcikKKyAgICAgICAgLnNjaGVkdWxlUGVyaW9kaWNUYXNrKAorICAgICAgICAgICAgVGFza1NjaGVkdWxlci5DRUxMVUxBUl9DSEFSR0lOR19QRVJJT0RJQ19UQVNLLAorICAgICAgICAgICAgKG5ldyBGbGFncygpIHt9KS5jZWxsdWxhckNoYXJnaW5nR2NtVGFza1BlcmlvZCgpLAorICAgICAgICAgICAgTmV0d29ya1N0YXRlLk5FVFdPUktfU1RBVEVfQ09OTkVDVEVELAorICAgICAgICAgICAgLyogY29uc3RyYWludE92ZXJyaWRlcyA9ICovIE9wdGlvbmFsLmFic2VudCgpKTsKKworICAgIHZlcmlmeShtb2NrVGFza1NjaGVkdWxlcikKKyAgICAgICAgLnNjaGVkdWxlUGVyaW9kaWNUYXNrKAorICAgICAgICAgICAgVGFza1NjaGVkdWxlci5XSUZJX0NIQVJHSU5HX1BFUklPRElDX1RBU0ssCisgICAgICAgICAgICAobmV3IEZsYWdzKCkge30pLndpZmlDaGFyZ2luZ0djbVRhc2tQZXJpb2QoKSwKKyAgICAgICAgICAgIE5ldHdvcmtTdGF0ZS5ORVRXT1JLX1NUQVRFX1VOTUVURVJFRCwKKyAgICAgICAgICAgIC8qIGNvbnN0cmFpbnRPdmVycmlkZXMgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSk7CisKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1Rhc2tTY2hlZHVsZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2NoZWR1bGVQZXJpb2RpY1Rhc2tzX251bGxUYXNrU2NoZWR1bGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICAvKiBmaWxlR3JvdXBQb3B1bGF0b3JMaXN0ID0gKi8gSW1tdXRhYmxlTGlzdC5vZigpLAorICAgICAgICAgICAgLyogdGFza1NjaGVkdWxlck9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZC5zY2hlZHVsZVBlcmlvZGljVGFza3MoKTsKKworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tUYXNrU2NoZWR1bGVyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHNjaGVkdWxlUGVyaW9kaWNCYWNrZ3JvdW5kVGFza3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZC5zY2hlZHVsZVBlcmlvZGljQmFja2dyb3VuZFRhc2tzKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja1Rhc2tTY2hlZHVsZXIpCisgICAgICAgIC5zY2hlZHVsZVBlcmlvZGljVGFzaygKKyAgICAgICAgICAgIFRhc2tTY2hlZHVsZXIuQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSywKKyAgICAgICAgICAgIChuZXcgRmxhZ3MoKSB7fSkuY2hhcmdpbmdHY21UYXNrUGVyaW9kKCksCisgICAgICAgICAgICBOZXR3b3JrU3RhdGUuTkVUV09SS19TVEFURV9BTlksCisgICAgICAgICAgICAvKiBjb25zdHJhaW50T3ZlcnJpZGVzID0gKi8gT3B0aW9uYWwuYWJzZW50KCkpOworCisgICAgdmVyaWZ5KG1vY2tUYXNrU2NoZWR1bGVyKQorICAgICAgICAuc2NoZWR1bGVQZXJpb2RpY1Rhc2soCisgICAgICAgICAgICBUYXNrU2NoZWR1bGVyLk1BSU5URU5BTkNFX1BFUklPRElDX1RBU0ssCisgICAgICAgICAgICAobmV3IEZsYWdzKCkge30pLm1haW50ZW5hbmNlR2NtVGFza1BlcmlvZCgpLAorICAgICAgICAgICAgTmV0d29ya1N0YXRlLk5FVFdPUktfU1RBVEVfQU5ZLAorICAgICAgICAgICAgLyogY29uc3RyYWludE92ZXJyaWRlcyA9ICovIE9wdGlvbmFsLmFic2VudCgpKTsKKworICAgIHZlcmlmeShtb2NrVGFza1NjaGVkdWxlcikKKyAgICAgICAgLnNjaGVkdWxlUGVyaW9kaWNUYXNrKAorICAgICAgICAgICAgVGFza1NjaGVkdWxlci5DRUxMVUxBUl9DSEFSR0lOR19QRVJJT0RJQ19UQVNLLAorICAgICAgICAgICAgKG5ldyBGbGFncygpIHt9KS5jZWxsdWxhckNoYXJnaW5nR2NtVGFza1BlcmlvZCgpLAorICAgICAgICAgICAgTmV0d29ya1N0YXRlLk5FVFdPUktfU1RBVEVfQ09OTkVDVEVELAorICAgICAgICAgICAgLyogY29uc3RyYWludE92ZXJyaWRlcyA9ICovIE9wdGlvbmFsLmFic2VudCgpKTsKKworICAgIHZlcmlmeShtb2NrVGFza1NjaGVkdWxlcikKKyAgICAgICAgLnNjaGVkdWxlUGVyaW9kaWNUYXNrKAorICAgICAgICAgICAgVGFza1NjaGVkdWxlci5XSUZJX0NIQVJHSU5HX1BFUklPRElDX1RBU0ssCisgICAgICAgICAgICAobmV3IEZsYWdzKCkge30pLndpZmlDaGFyZ2luZ0djbVRhc2tQZXJpb2QoKSwKKyAgICAgICAgICAgIE5ldHdvcmtTdGF0ZS5ORVRXT1JLX1NUQVRFX1VOTUVURVJFRCwKKyAgICAgICAgICAgIC8qIGNvbnN0cmFpbnRPdmVycmlkZXMgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSk7CisKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1Rhc2tTY2hlZHVsZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2NoZWR1bGVQZXJpb2RpY0JhY2tncm91bmRUYXNrc19udWxsVGFza1NjaGVkdWxlcigpIHRocm93cyBFeGNlcHRpb24geworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIC8qIHRhc2tTY2hlZHVsZXJPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuc2NoZWR1bGVQZXJpb2RpY0JhY2tncm91bmRUYXNrcygpLmdldCgpOworCisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja1Rhc2tTY2hlZHVsZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2NoZWR1bGVQZXJpb2RpY0JhY2tncm91bmRUYXNrc193aXRoQ29uc3RyYWludE92ZXJyaWRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgQ29uc3RyYWludE92ZXJyaWRlcyB3aWZpT3ZlcnJpZGVzID0KKyAgICAgICAgQ29uc3RyYWludE92ZXJyaWRlcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRSZXF1aXJlc0NoYXJnaW5nKGZhbHNlKQorICAgICAgICAgICAgLnNldFJlcXVpcmVzRGV2aWNlSWRsZSh0cnVlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgQ29uc3RyYWludE92ZXJyaWRlcyBjZWxsdWxhck92ZXJyaWRlcyA9CisgICAgICAgIENvbnN0cmFpbnRPdmVycmlkZXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0UmVxdWlyZXNDaGFyZ2luZyh0cnVlKQorICAgICAgICAgICAgLnNldFJlcXVpcmVzRGV2aWNlSWRsZShmYWxzZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgTWFwPFN0cmluZywgQ29uc3RyYWludE92ZXJyaWRlcz4gY29uc3RyYWludE92ZXJyaWRlc01hcCA9IG5ldyBIYXNoTWFwPD4oKTsKKyAgICBjb25zdHJhaW50T3ZlcnJpZGVzTWFwLnB1dChUYXNrU2NoZWR1bGVyLldJRklfQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSywgd2lmaU92ZXJyaWRlcyk7CisgICAgY29uc3RyYWludE92ZXJyaWRlc01hcC5wdXQoVGFza1NjaGVkdWxlci5DRUxMVUxBUl9DSEFSR0lOR19QRVJJT0RJQ19UQVNLLCBjZWxsdWxhck92ZXJyaWRlcyk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuc2NoZWR1bGVQZXJpb2RpY0JhY2tncm91bmRUYXNrcyhPcHRpb25hbC5vZihjb25zdHJhaW50T3ZlcnJpZGVzTWFwKSkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja1Rhc2tTY2hlZHVsZXIpCisgICAgICAgIC5zY2hlZHVsZVBlcmlvZGljVGFzaygKKyAgICAgICAgICAgIFRhc2tTY2hlZHVsZXIuQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSywKKyAgICAgICAgICAgIChuZXcgRmxhZ3MoKSB7fSkuY2hhcmdpbmdHY21UYXNrUGVyaW9kKCksCisgICAgICAgICAgICBOZXR3b3JrU3RhdGUuTkVUV09SS19TVEFURV9BTlksCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSk7CisKKyAgICB2ZXJpZnkobW9ja1Rhc2tTY2hlZHVsZXIpCisgICAgICAgIC5zY2hlZHVsZVBlcmlvZGljVGFzaygKKyAgICAgICAgICAgIFRhc2tTY2hlZHVsZXIuTUFJTlRFTkFOQ0VfUEVSSU9ESUNfVEFTSywKKyAgICAgICAgICAgIChuZXcgRmxhZ3MoKSB7fSkubWFpbnRlbmFuY2VHY21UYXNrUGVyaW9kKCksCisgICAgICAgICAgICBOZXR3b3JrU3RhdGUuTkVUV09SS19TVEFURV9BTlksCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSk7CisKKyAgICB2ZXJpZnkobW9ja1Rhc2tTY2hlZHVsZXIpCisgICAgICAgIC5zY2hlZHVsZVBlcmlvZGljVGFzaygKKyAgICAgICAgICAgIFRhc2tTY2hlZHVsZXIuQ0VMTFVMQVJfQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSywKKyAgICAgICAgICAgIChuZXcgRmxhZ3MoKSB7fSkuY2VsbHVsYXJDaGFyZ2luZ0djbVRhc2tQZXJpb2QoKSwKKyAgICAgICAgICAgIE5ldHdvcmtTdGF0ZS5ORVRXT1JLX1NUQVRFX0NPTk5FQ1RFRCwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKGNlbGx1bGFyT3ZlcnJpZGVzKSk7CisKKyAgICB2ZXJpZnkobW9ja1Rhc2tTY2hlZHVsZXIpCisgICAgICAgIC5zY2hlZHVsZVBlcmlvZGljVGFzaygKKyAgICAgICAgICAgIFRhc2tTY2hlZHVsZXIuV0lGSV9DSEFSR0lOR19QRVJJT0RJQ19UQVNLLAorICAgICAgICAgICAgKG5ldyBGbGFncygpIHt9KS53aWZpQ2hhcmdpbmdHY21UYXNrUGVyaW9kKCksCisgICAgICAgICAgICBOZXR3b3JrU3RhdGUuTkVUV09SS19TVEFURV9VTk1FVEVSRUQsCisgICAgICAgICAgICBPcHRpb25hbC5vZih3aWZpT3ZlcnJpZGVzKSk7CisKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1Rhc2tTY2hlZHVsZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2NoZWR1bGVQZXJpb2RpY0JhY2tncm91bmRUYXNrc19udWxsVGFza1NjaGVkdWxlcl9hbmRPdmVycmlkZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIC8qIGZpbGVHcm91cFBvcHVsYXRvckxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICAvKiB0YXNrU2NoZWR1bGVyT3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgbW9iaWxlRGF0YURvd25sb2FkLnNjaGVkdWxlUGVyaW9kaWNCYWNrZ3JvdW5kVGFza3MoT3B0aW9uYWwuYWJzZW50KCkpLmdldCgpOworCisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja1Rhc2tTY2hlZHVsZXIpOworICB9CisKKyAgLy8gQSBoZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEgRGF0YUZpbGVncm91cC4KKyAgcHJpdmF0ZSBzdGF0aWMgRGF0YUZpbGVHcm91cCBjcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgU3RyaW5nIGdyb3VwTmFtZSwKKyAgICAgIFN0cmluZyBvd25lclBhY2thZ2UsCisgICAgICBpbnQgdmVyc2lvbk51bWJlciwKKyAgICAgIFN0cmluZ1tdIGZpbGVJZCwKKyAgICAgIGludFtdIGJ5dGVTaXplLAorICAgICAgU3RyaW5nW10gY2hlY2tzdW0sCisgICAgICBTdHJpbmdbXSB1cmwsCisgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5IGRldmljZU5ldHdvcmtQb2xpY3kpIHsKKyAgICBpZiAoZmlsZUlkLmxlbmd0aCAhPSBieXRlU2l6ZS5sZW5ndGgKKyAgICAgICAgfHwgZmlsZUlkLmxlbmd0aCAhPSBjaGVja3N1bS5sZW5ndGgKKyAgICAgICAgfHwgZmlsZUlkLmxlbmd0aCAhPSB1cmwubGVuZ3RoKSB7CisgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CisgICAgfQorCisgICAgRGF0YUZpbGVHcm91cC5CdWlsZGVyIGRhdGFGaWxlR3JvdXBCdWlsZGVyID0KKyAgICAgICAgRGF0YUZpbGVHcm91cC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoZ3JvdXBOYW1lKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShvd25lclBhY2thZ2UpCisgICAgICAgICAgICAuc2V0RmlsZUdyb3VwVmVyc2lvbk51bWJlcih2ZXJzaW9uTnVtYmVyKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucygKKyAgICAgICAgICAgICAgICBEb3dubG9hZENvbmRpdGlvbnMubmV3QnVpbGRlcigpLnNldERldmljZU5ldHdvcmtQb2xpY3koZGV2aWNlTmV0d29ya1BvbGljeSkpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlSWQubGVuZ3RoOyArK2kpIHsKKyAgICAgIERhdGFGaWxlIGZpbGUgPQorICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAuc2V0RmlsZUlkKGZpbGVJZFtpXSkKKyAgICAgICAgICAgICAgLnNldEJ5dGVTaXplKGJ5dGVTaXplW2ldKQorICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oY2hlY2tzdW1baV0pCisgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKHVybFtpXSkKKyAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICBkYXRhRmlsZUdyb3VwQnVpbGRlci5hZGRGaWxlKGZpbGUpOworICAgIH0KKworICAgIHJldHVybiBkYXRhRmlsZUdyb3VwQnVpbGRlci5idWlsZCgpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgRGF0YUZpbGVHcm91cEludGVybmFsIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgIFN0cmluZyBncm91cE5hbWUsCisgICAgICBTdHJpbmcgb3duZXJQYWNrYWdlLAorICAgICAgaW50IHZlcnNpb25OdW1iZXIsCisgICAgICBTdHJpbmdbXSBmaWxlSWQsCisgICAgICBpbnRbXSBieXRlU2l6ZSwKKyAgICAgIFN0cmluZ1tdIGNoZWNrc3VtLAorICAgICAgU3RyaW5nW10gdXJsLAorICAgICAgRGV2aWNlTmV0d29ya1BvbGljeSBkZXZpY2VOZXR3b3JrUG9saWN5KQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIFByb3RvQ29udmVyc2lvblV0aWwuY29udmVydCgKKyAgICAgICAgY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIGdyb3VwTmFtZSwKKyAgICAgICAgICAgIG93bmVyUGFja2FnZSwKKyAgICAgICAgICAgIHZlcnNpb25OdW1iZXIsCisgICAgICAgICAgICBmaWxlSWQsCisgICAgICAgICAgICBieXRlU2l6ZSwKKyAgICAgICAgICAgIGNoZWNrc3VtLAorICAgICAgICAgICAgdXJsLAorICAgICAgICAgICAgZGV2aWNlTmV0d29ya1BvbGljeSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaGFuZGxlVGFza19tYWludGVuYW5jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIubWFpbnRlbmFuY2UoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLk1BSU5URU5BTkNFX1BFUklPRElDX1RBU0spLmdldCgpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikubWFpbnRlbmFuY2UoKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaGFuZGxlVGFza19jaGFyZ2luZygpIHRocm93cyBFeGNlcHRpb24geworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihtb2NrRmlsZUdyb3VwUG9wdWxhdG9yKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci52ZXJpZnlBbGxQZW5kaW5nR3JvdXBzKGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cFBvcHVsYXRvci5yZWZyZXNoRmlsZUdyb3Vwcyhtb2JpbGVEYXRhRG93bmxvYWQpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLkNIQVJHSU5HX1BFUklPRElDX1RBU0spLmdldCgpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3VwUG9wdWxhdG9yKS5yZWZyZXNoRmlsZUdyb3Vwcyhtb2JpbGVEYXRhRG93bmxvYWQpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikudmVyaWZ5QWxsUGVuZGluZ0dyb3VwcyhhbnkoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGhhbmRsZVRhc2tfd2lmaV9jaGFyZ2luZygpIHRocm93cyBFeGNlcHRpb24geworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihtb2NrRmlsZUdyb3VwUG9wdWxhdG9yKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgd2hlbihtb2NrRmlsZUdyb3VwUG9wdWxhdG9yLnJlZnJlc2hGaWxlR3JvdXBzKG1vYmlsZURhdGFEb3dubG9hZCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmRvd25sb2FkQWxsUGVuZGluZ0dyb3VwcyhlcSh0cnVlKSAvKndpZmkqLywgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLldJRklfQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSykuZ2V0KCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBQb3B1bGF0b3IsIHRpbWVzKDIpKS5yZWZyZXNoRmlsZUdyb3Vwcyhtb2JpbGVEYXRhRG93bmxvYWQpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwgdGltZXMoMikpLmRvd25sb2FkQWxsUGVuZGluZ0dyb3VwcyhlcSh0cnVlKSwgYW55KCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBoYW5kbGVUYXNrX2NlbGx1bGFyX2NoYXJnaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9CisgICAgICAgIG5ldyBNb2JpbGVEYXRhRG93bmxvYWRJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLAorICAgICAgICAgICAgRVhFQ1VUT1IsCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKG1vY2tGaWxlR3JvdXBQb3B1bGF0b3IpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICAvKiBkb3dubG9hZE1vbml0b3JPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBzaW5nbGVGaWxlRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpIC8qIGN1c3RvbUZpbGVHcm91cFZhbGlkYXRvciAqLyk7CisKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBQb3B1bGF0b3IucmVmcmVzaEZpbGVHcm91cHMobW9iaWxlRGF0YURvd25sb2FkKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZG93bmxvYWRBbGxQZW5kaW5nR3JvdXBzKGVxKGZhbHNlKSAvKndpZmkqLywgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLkNFTExVTEFSX0NIQVJHSU5HX1BFUklPRElDX1RBU0spLmdldCgpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3VwUG9wdWxhdG9yLCB0aW1lcygyKSkucmVmcmVzaEZpbGVHcm91cHMobW9iaWxlRGF0YURvd25sb2FkKTsKKyAgICB2ZXJpZnkobW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsIHRpbWVzKDIpKS5kb3dubG9hZEFsbFBlbmRpbmdHcm91cHMoZXEoZmFsc2UpLCBhbnkoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGhhbmRsZVRhc2tfbm9fZmlsZWdyb3VwX3BvcHVsYXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci52ZXJpZnlBbGxQZW5kaW5nR3JvdXBzKGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworICAgIHdoZW4obW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuZG93bmxvYWRBbGxQZW5kaW5nR3JvdXBzKGFueUJvb2xlYW4oKSAvKndpZmkqLywgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLkNIQVJHSU5HX1BFUklPRElDX1RBU0spLmdldCgpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcikudmVyaWZ5QWxsUGVuZGluZ0dyb3VwcyhhbnkoKSk7CisKKyAgICBtb2JpbGVEYXRhRG93bmxvYWQuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLkNFTExVTEFSX0NIQVJHSU5HX1BFUklPRElDX1RBU0spLmdldCgpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwgdGltZXMoMikpLmRvd25sb2FkQWxsUGVuZGluZ0dyb3VwcyhlcShmYWxzZSksIGFueSgpKTsKKworICAgIG1vYmlsZURhdGFEb3dubG9hZC5oYW5kbGVUYXNrKFRhc2tTY2hlZHVsZXIuV0lGSV9DSEFSR0lOR19QRVJJT0RJQ19UQVNLKS5nZXQoKTsKKyAgICB2ZXJpZnkobW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsIHRpbWVzKDIpKS5kb3dubG9hZEFsbFBlbmRpbmdHcm91cHMoZXEodHJ1ZSksIGFueSgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGhhbmRsZVRhc2tfaW52YWxpZF90YWcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0V2ZW50TG9nZ2VyLAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgICAgICBFWEVDVVRPUiwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobW9ja0ZpbGVHcm91cFBvcHVsYXRvciksCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrVGFza1NjaGVkdWxlciksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIC8qIGRvd25sb2FkTW9uaXRvck9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBPcHRpb25hbC5vZih0aGlzLmdldENsYXNzKCkpLCAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBmb3JlZ3JvdW5kIGRvd25sb2FkIHNlcnZpY2UuCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogY3VzdG9tRmlsZUdyb3VwVmFsaWRhdG9yICovKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBlID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBtb2JpbGVEYXRhRG93bmxvYWQuaGFuZGxlVGFzaygiaW52YWxpZC10YWciKS5nZXQoKSk7CisgICAgYXNzZXJ0VGhhdChlKS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGhhbmRsZVRhc2tfb25lUG9wdWxhdG9yRmFpbHNfY29udGludWVzVG9SdW5PdGhlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlR3JvdXBQb3B1bGF0b3IgZmFpbGluZ1BvcHVsYXRvciA9CisgICAgICAgIChNb2JpbGVEYXRhRG93bmxvYWQgdW51c2VkKSAtPgorICAgICAgICAgICAgRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUobmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidGVzdCIpKTsKKworICAgIEF0b21pY0Jvb2xlYW4gcmVmcmVzaGVkT25lU3VjY2VlZGluZ1BvcHVsYXRvciA9IG5ldyBBdG9taWNCb29sZWFuKGZhbHNlKTsKKyAgICBGaWxlR3JvdXBQb3B1bGF0b3Igb25lU3VjY2VlZGluZ1BvcHVsYXRvciA9CisgICAgICAgIChNb2JpbGVEYXRhRG93bmxvYWQgdW51c2VkKSAtPiB7CisgICAgICAgICAgcmVmcmVzaGVkT25lU3VjY2VlZGluZ1BvcHVsYXRvci5zZXQodHJ1ZSk7CisgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICB9OworCisgICAgQXRvbWljQm9vbGVhbiByZWZyZXNoZWRBbm90aGVyU3VjY2VlZGluZ1BvcHVsYXRvciA9IG5ldyBBdG9taWNCb29sZWFuKGZhbHNlKTsKKyAgICBGaWxlR3JvdXBQb3B1bGF0b3IgYW5vdGhlclN1Y2NlZWRpbmdQb3B1bGF0b3IgPQorICAgICAgICAoTW9iaWxlRGF0YURvd25sb2FkIHVudXNlZCkgLT4geworICAgICAgICAgIHJlZnJlc2hlZEFub3RoZXJTdWNjZWVkaW5nUG9wdWxhdG9yLnNldCh0cnVlKTsKKyAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgIH07CisKKyAgICAvLyBUaGUgcG9wdWxhdG9ycyB3aWxsIGJlIGV4ZWN1dGVkIGluIHRoaXMgb3JkZXIuCisgICAgSW1tdXRhYmxlTGlzdDxGaWxlR3JvdXBQb3B1bGF0b3I+IHBvcHVsYXRvcnMgPQorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKGZhaWxpbmdQb3B1bGF0b3IsIG9uZVN1Y2NlZWRpbmdQb3B1bGF0b3IsIGFub3RoZXJTdWNjZWVkaW5nUG9wdWxhdG9yKTsKKworICAgIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkSW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrRXZlbnRMb2dnZXIsCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciwKKyAgICAgICAgICAgIEVYRUNVVE9SLAorICAgICAgICAgICAgcG9wdWxhdG9ycywKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tUYXNrU2NoZWR1bGVyKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgc2luZ2xlRmlsZURvd25sb2FkZXIsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworCisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci52ZXJpZnlBbGxQZW5kaW5nR3JvdXBzKGFueSgpIC8qIHZhbGlkYXRvciAqLykpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmRvd25sb2FkQWxsUGVuZGluZ0dyb3VwcygKKyAgICAgICAgICAgIGFueUJvb2xlYW4oKSAvKndpZmkqLywgYW55KCkgLyogdmFsaWRhdG9yICovKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBoYW5kbGVGdXR1cmUgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuaGFuZGxlVGFzayhUYXNrU2NoZWR1bGVyLldJRklfQ0hBUkdJTkdfUEVSSU9ESUNfVEFTSyk7CisgICAgYXNzZXJ0VGhhdChoYW5kbGVGdXR1cmUpLndoZW5Eb25lKCkuaXNTdWNjZXNzZnVsKCk7CisKKyAgICBoYW5kbGVGdXR1cmUuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChyZWZyZXNoZWRPbmVTdWNjZWVkaW5nUG9wdWxhdG9yLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHJlZnJlc2hlZEFub3RoZXJTdWNjZWVkaW5nUG9wdWxhdG9yLmdldCgpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlcG9ydFVzYWdlX2Jhc2ljKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPSBjcmVhdGVEZWZhdWx0RGF0YUZpbGVHcm91cEludGVybmFsKCk7CisKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldEZpbGVHcm91cChhbnkoR3JvdXBLZXkuY2xhc3MpLCBlcSh0cnVlKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGRhdGFGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLmdldERhdGFGaWxlVXJpKGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKSwgZGF0YUZpbGVHcm91cCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG9uRGV2aWNlVXJpMSkpOworCisgICAgTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCA9IGNyZWF0ZURlZmF1bHRNb2JpbGVEYXRhRG93bmxvYWQoKTsKKworICAgIENsaWVudEZpbGVHcm91cCBjbGllbnRGaWxlR3JvdXAgPQorICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQKKyAgICAgICAgICAgIC5nZXRGaWxlR3JvdXAoR2V0RmlsZUdyb3VwUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKEZJTEVfR1JPVVBfTkFNRV8xKS5idWlsZCgpKQorICAgICAgICAgICAgLmdldCgpOworCisgICAgVXNhZ2VFdmVudCB1c2FnZUV2ZW50ID0KKyAgICAgICAgVXNhZ2VFdmVudC5idWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRFdmVudENvZGUoMCkKKyAgICAgICAgICAgIC5zZXRBcHBWZXJzaW9uKDEyMykKKyAgICAgICAgICAgIC5zZXRDbGllbnRGaWxlR3JvdXAoY2xpZW50RmlsZUdyb3VwKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgbW9iaWxlRGF0YURvd25sb2FkLnJlcG9ydFVzYWdlKHVzYWdlRXZlbnQpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tFdmVudExvZ2dlcikubG9nTWRkVXNhZ2VFdmVudChjcmVhdGVGaWxlR3JvdXBTdGF0cyhjbGllbnRGaWxlR3JvdXApLCBudWxsKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIFZvaWQgY3JlYXRlRmlsZUdyb3VwU3RhdHMoQ2xpZW50RmlsZUdyb3VwIGNsaWVudEZpbGVHcm91cCkgeworICAgIHJldHVybiBudWxsOworICB9CisKKyAgcHJpdmF0ZSBNb2JpbGVEYXRhRG93bmxvYWQgY3JlYXRlRGVmYXVsdE1vYmlsZURhdGFEb3dubG9hZCgpIHsKKyAgICByZXR1cm4gbmV3IE1vYmlsZURhdGFEb3dubG9hZEltcGwoCisgICAgICAgIGNvbnRleHQsCisgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIsCisgICAgICAgIEVYRUNVVE9SLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKCkgLyogZmlsZUdyb3VwUG9wdWxhdG9yTGlzdCAqLywKKyAgICAgICAgT3B0aW9uYWwub2YobW9ja1Rhc2tTY2hlZHVsZXIpLAorICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgT3B0aW9uYWwuYWJzZW50KCkgLyogZG93bmxvYWRNb25pdG9yT3B0aW9uYWwgKi8sCisgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgZmxhZ3MsCisgICAgICAgIHNpbmdsZUZpbGVEb3dubG9hZGVyLAorICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSAvKiBjdXN0b21GaWxlR3JvdXBWYWxpZGF0b3IgKi8pOworICB9CisKKyAgcHJpdmF0ZSBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgY3JlYXRlRGVmYXVsdERhdGFGaWxlR3JvdXBJbnRlcm5hbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHJldHVybiBjcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoCisgICAgICAgIEZJTEVfR1JPVVBfTkFNRV8xLAorICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgIDEgLyogdmVyc2lvbk51bWJlciAqLywKKyAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0lEXzF9LAorICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRV8xfSwKKyAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNXzF9LAorICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfVVJMXzF9LAorICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9UZXN0RmlsZUdyb3VwUG9wdWxhdG9yLmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvVGVzdEZpbGVHcm91cFBvcHVsYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMwODllOTUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvVGVzdEZpbGVHcm91cFBvcHVsYXRvci5qYXZhCkBAIC0wLDAgKzEsMTUyIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZDsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQudGV4dC5UZXh0VXRpbHM7CitpbXBvcnQgYW5kcm9pZC51dGlsLkxvZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRvd25sb2FkQ29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VOZXR3b3JrUG9saWN5OworCisvKiogVGVzdCBGaWxlR3JvdXAgUG9wdWxhdG9yLiAqLworcHVibGljIGNsYXNzIFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IgaW1wbGVtZW50cyBGaWxlR3JvdXBQb3B1bGF0b3IgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiTUREIFRlc3RGaWxlR3JvdXBQb3B1bGF0b3IiOworCisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9HUk9VUF9OQU1FID0gInRlc3QtZ3JvdXAiOworICBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfSUQgPSAidGVzdC1maWxlLWlkIjsKKyAgc3RhdGljIGZpbmFsIGludCBGSUxFX1NJWkUgPSA1NTQ7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9DSEVDS1NVTSA9ICJhMWNiYTlkODdiMTQ0MGY0MWNlOWU3ZGEzOGM0M2UxZjZiZDdkNWRmIjsKKyAgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX1VSTCA9ICJodHRwczovL3d3dy5nc3RhdGljLmNvbS9zdWdnZXN0LWRldi9vZHdzMV9lbXB0eS5qYXIiOworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworCisgIHB1YmxpYyBUZXN0RmlsZUdyb3VwUG9wdWxhdG9yKENvbnRleHQgY29udGV4dCkgeworICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVmcmVzaEZpbGVHcm91cHMoTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCkgeworICAgIExvZy5kKFRBRywgIkFkZGluZyBmaWxlIGdyb3VwcyAiICsgRklMRV9HUk9VUF9OQU1FKTsKKworICAgIERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICBGSUxFX0dST1VQX05BTUUsCisgICAgICAgICAgICBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCksCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfSUR9LAorICAgICAgICAgICAgbmV3IGludFtdIHtGSUxFX1NJWkV9LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX0NIRUNLU1VNfSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9VUkx9LAorICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSyk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IGFkZEZpbGVHcm91cEZ1dHVyZSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5hZGRGaWxlR3JvdXAoCisgICAgICAgICAgICBBZGRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXREYXRhRmlsZUdyb3VwKGRhdGFGaWxlR3JvdXApLmJ1aWxkKCkpOworICAgIHJldHVybiBGdXR1cmVzLnRyYW5zZm9ybSgKKyAgICAgICAgYWRkRmlsZUdyb3VwRnV0dXJlLAorICAgICAgICByZXN1bHQgLT4geworICAgICAgICAgIGlmIChyZXN1bHQuYm9vbGVhblZhbHVlKCkpIHsKKyAgICAgICAgICAgIExvZy5kKFRBRywgIkFkZGVkIGZpbGUgZ3JvdXBzICIgKyBkYXRhRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgTG9nLmQoVEFHLCAiRmFpbGVkIHRvIGFkZCBmaWxlIGdyb3VwICIgKyBkYXRhRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIG51bGw7CisgICAgICAgIH0sCisgICAgICAgIE1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3IoKSk7CisgIH0KKworICAvLyBBIGhlbHBlciBmdW5jdGlvbiB0byBjcmVhdGUgYSBEYXRhRmlsZWdyb3VwLgorICBzdGF0aWMgRGF0YUZpbGVHcm91cCBjcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgU3RyaW5nIGdyb3VwTmFtZSwKKyAgICAgIFN0cmluZyBvd25lclBhY2thZ2UsCisgICAgICBTdHJpbmdbXSBmaWxlSWQsCisgICAgICBpbnRbXSBieXRlU2l6ZSwKKyAgICAgIFN0cmluZ1tdIGNoZWNrc3VtLAorICAgICAgU3RyaW5nW10gdXJsLAorICAgICAgRGV2aWNlTmV0d29ya1BvbGljeSBkZXZpY2VOZXR3b3JrUG9saWN5KSB7CisgICAgaWYgKGZpbGVJZC5sZW5ndGggIT0gYnl0ZVNpemUubGVuZ3RoCisgICAgICAgIHx8IGZpbGVJZC5sZW5ndGggIT0gY2hlY2tzdW0ubGVuZ3RoCisgICAgICAgIHx8IGZpbGVJZC5sZW5ndGggIT0gdXJsLmxlbmd0aCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIERhdGFGaWxlR3JvdXAuQnVpbGRlciBkYXRhRmlsZUdyb3VwQnVpbGRlciA9CisgICAgICAgIERhdGFGaWxlR3JvdXAubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKGdyb3VwTmFtZSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2Uob3duZXJQYWNrYWdlKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucygKKyAgICAgICAgICAgICAgICBEb3dubG9hZENvbmRpdGlvbnMubmV3QnVpbGRlcigpLnNldERldmljZU5ldHdvcmtQb2xpY3koZGV2aWNlTmV0d29ya1BvbGljeSkpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlSWQubGVuZ3RoOyArK2kpIHsKKyAgICAgIERhdGFGaWxlIGZpbGUgPQorICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAuc2V0RmlsZUlkKGZpbGVJZFtpXSkKKyAgICAgICAgICAgICAgLnNldEJ5dGVTaXplKGJ5dGVTaXplW2ldKQorICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oY2hlY2tzdW1baV0pCisgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKHVybFtpXSkKKyAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICBkYXRhRmlsZUdyb3VwQnVpbGRlci5hZGRGaWxlKGZpbGUpOworICAgIH0KKworICAgIHJldHVybiBkYXRhRmlsZUdyb3VwQnVpbGRlci5idWlsZCgpOworICB9CisKKyAgLy8gQWxsb3dzIHRvIGNvbmZpZ3VyZSBhbmRyb2lkLXNoYXJlZCBhbmQgbm9uLWFuZHJvaWQtc2hhcmVkIGZpbGVzLgorICBzdGF0aWMgRGF0YUZpbGVHcm91cCBjcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgU3RyaW5nIGdyb3VwTmFtZSwKKyAgICAgIFN0cmluZyBvd25lclBhY2thZ2UsCisgICAgICBTdHJpbmdbXSBmaWxlSWQsCisgICAgICBpbnRbXSBieXRlU2l6ZSwKKyAgICAgIFN0cmluZ1tdIGNoZWNrc3VtLAorICAgICAgU3RyaW5nW10gYW5kcm9pZFNoYXJpbmdDaGVja3N1bSwKKyAgICAgIFN0cmluZ1tdIHVybCwKKyAgICAgIERldmljZU5ldHdvcmtQb2xpY3kgZGV2aWNlTmV0d29ya1BvbGljeSkgeworICAgIGlmIChmaWxlSWQubGVuZ3RoICE9IGJ5dGVTaXplLmxlbmd0aAorICAgICAgICB8fCBmaWxlSWQubGVuZ3RoICE9IGNoZWNrc3VtLmxlbmd0aAorICAgICAgICB8fCBmaWxlSWQubGVuZ3RoICE9IHVybC5sZW5ndGgpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKKyAgICB9CisKKyAgICBEYXRhRmlsZUdyb3VwLkJ1aWxkZXIgZGF0YUZpbGVHcm91cEJ1aWxkZXIgPQorICAgICAgICBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShncm91cE5hbWUpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKG93bmVyUGFja2FnZSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoCisgICAgICAgICAgICAgICAgRG93bmxvYWRDb25kaXRpb25zLm5ld0J1aWxkZXIoKS5zZXREZXZpY2VOZXR3b3JrUG9saWN5KGRldmljZU5ldHdvcmtQb2xpY3kpKTsKKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZUlkLmxlbmd0aDsgKytpKSB7CisgICAgICBEYXRhRmlsZS5CdWlsZGVyIGZpbGVCdWlsZGVyID0KKyAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgLnNldEZpbGVJZChmaWxlSWRbaV0pCisgICAgICAgICAgICAgIC5zZXRCeXRlU2l6ZShieXRlU2l6ZVtpXSkKKyAgICAgICAgICAgICAgLnNldENoZWNrc3VtKGNoZWNrc3VtW2ldKQorICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCh1cmxbaV0pOworICAgICAgaWYgKCFUZXh0VXRpbHMuaXNFbXB0eShhbmRyb2lkU2hhcmluZ0NoZWNrc3VtW2ldKSkgeworICAgICAgICBmaWxlQnVpbGRlcgorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyaW5nVHlwZShEYXRhRmlsZS5BbmRyb2lkU2hhcmluZ1R5cGUuQU5EUk9JRF9CTE9CX1dIRU5fQVZBSUxBQkxFKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW1UeXBlKERhdGFGaWxlLkFuZHJvaWRTaGFyaW5nQ2hlY2tzdW1UeXBlLlNIQTJfMjU2KQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oYW5kcm9pZFNoYXJpbmdDaGVja3N1bVtpXSk7CisgICAgICB9CisgICAgICBkYXRhRmlsZUdyb3VwQnVpbGRlci5hZGRGaWxlKGZpbGVCdWlsZGVyLmJ1aWxkKCkpOworICAgIH0KKyAgICByZXR1cm4gZGF0YUZpbGVHcm91cEJ1aWxkZXIuYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1R3b1N0ZXBQb3B1bGF0b3IuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Ud29TdGVwUG9wdWxhdG9yLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODgxYzRhNAotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9Ud29TdGVwUG9wdWxhdG9yLmphdmEKQEAgLTAsMCArMSwxMTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgc3RhdGljIGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0cy5VVEZfODsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlByZWNvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZsdWVudEZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlQ2FsbGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuQ2xpZW50Q29uZmlnUHJvdG8uQ2xpZW50RmlsZUdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGUuQ2hlY2tzdW1UeXBlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VOZXR3b3JrUG9saWN5OworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CisKKy8qKgorICogQSBmaWxlIGdyb3VwIHBvcHVsYXRvciB0aGF0IGRlbW9uc3RyYXRlIHRoZSAyLXN0ZXAgZG93bmxvYWQuIFRoZSBwb3B1bGF0b3Igd2lsbCByZWFkIHRoZSBjb250ZW50CisgKiBmcm9tIGZpcnN0IGdyb3VwIGFuZCB0aGVuIGFkZCB0aGUgc2Vjb25kIGdyb3VwIHRvIE1ERC4KKyAqLworcHVibGljIGNsYXNzIFR3b1N0ZXBQb3B1bGF0b3IgaW1wbGVtZW50cyBGaWxlR3JvdXBQb3B1bGF0b3IgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIlR3b1N0ZXBQb3B1bGF0b3IiOworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIGZpbmFsIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2U7CisKKyAgcHVibGljIFR3b1N0ZXBQb3B1bGF0b3IoQ29udGV4dCBjb250ZXh0LCBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlKSB7CisgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsKKyAgICB0aGlzLmZpbGVTdG9yYWdlID0gZmlsZVN0b3JhZ2U7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gcmVmcmVzaEZpbGVHcm91cHMoTW9iaWxlRGF0YURvd25sb2FkIG1vYmlsZURhdGFEb3dubG9hZCkgeworICAgIExpc3RlbmFibGVGdXR1cmU8Q2xpZW50RmlsZUdyb3VwPiBzdGVwMUZ1dHVyZSA9CisgICAgICAgIG1vYmlsZURhdGFEb3dubG9hZC5nZXRGaWxlR3JvdXAoCisgICAgICAgICAgICBHZXRGaWxlR3JvdXBSZXF1ZXN0Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoInN0ZXAxLWZpbGUtZ3JvdXAiKS5idWlsZCgpKTsKKworICAgIHJldHVybiBGbHVlbnRGdXR1cmUuZnJvbShzdGVwMUZ1dHVyZSkKKyAgICAgICAgLnRyYW5zZm9ybUFzeW5jKAorICAgICAgICAgICAgY2xpZW50RmlsZUdyb3VwIC0+IHsKKyAgICAgICAgICAgICAgaWYgKGNsaWVudEZpbGVHcm91cCA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgTG9nVXRpbC5kKCIlczogUmV0cmlldmVkIHN0ZXAxLWZpbGUtZ3JvdXAgZnJvbSBNREQiLCBUQUcpOworCisgICAgICAgICAgICAgIC8vIE5vdyByZWFkIHRoZSB1cmwgZnJvbSB0aGUgc3RlcDEudHh0CisgICAgICAgICAgICAgIFVyaSBmaWxlVXJpID0gVXJpLnBhcnNlKGNsaWVudEZpbGVHcm91cC5nZXRGaWxlKDApLmdldEZpbGVVcmkoKSk7CisgICAgICAgICAgICAgIFN0cmluZyBzdGVwMUNvbnRlbnQgPSBudWxsOworICAgICAgICAgICAgICB0cnkgeworICAgICAgICAgICAgICAgIHN0ZXAxQ29udGVudCA9IG5ldyBTdHJpbmcoU3RyZWFtVXRpbHMucmVhZEZpbGVJbkJ5dGVzKGZpbGVTdG9yYWdlLCBmaWxlVXJpKSwgVVRGXzgpOworICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgTG9nVXRpbC5lKGUsICJGYWlsIHRvIHJlYWQgZnJvbSBzdGVwMS50eHQiKTsKKyAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgIC8vIEFkZCBhIGZpbGUgZ3JvdXAgd2hlcmUgdGhlIHVybCBpcyByZWFkIGZyb20gc3RlcDEudHh0CisgICAgICAgICAgICAgIERhdGFGaWxlR3JvdXAgc3RlcDJGaWxlR3JvdXAgPQorICAgICAgICAgICAgICAgICAgTW9iaWxlRGF0YURvd25sb2FkSW50ZWdyYXRpb25UZXN0LmNyZWF0ZURhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgICAgInN0ZXAyLWZpbGUtZ3JvdXAiLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyaW5nW10geyJzdGVwMl9pZCJ9LAorICAgICAgICAgICAgICAgICAgICAgIG5ldyBpbnRbXSB7MTN9LAorICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7IiJ9LAorICAgICAgICAgICAgICAgICAgICAgIG5ldyBDaGVja3N1bVR5cGVbXSB7Q2hlY2tzdW1UeXBlLk5PTkV9LAorICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7c3RlcDFDb250ZW50fSwKKyAgICAgICAgICAgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKTsKKworICAgICAgICAgICAgICBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IGFkZEZpbGVHcm91cEZ1dHVyZSA9CisgICAgICAgICAgICAgICAgICBtb2JpbGVEYXRhRG93bmxvYWQuYWRkRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldERhdGFGaWxlR3JvdXAoc3RlcDJGaWxlR3JvdXApLmJ1aWxkKCkpOworICAgICAgICAgICAgICBGdXR1cmVzLmFkZENhbGxiYWNrKAorICAgICAgICAgICAgICAgICAgYWRkRmlsZUdyb3VwRnV0dXJlLAorICAgICAgICAgICAgICAgICAgbmV3IEZ1dHVyZUNhbGxiYWNrPEJvb2xlYW4+KCkgeworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25TdWNjZXNzKEJvb2xlYW4gcmVzdWx0KSB7CisgICAgICAgICAgICAgICAgICAgICAgUHJlY29uZGl0aW9ucy5jaGVja1N0YXRlKHJlc3VsdC5ib29sZWFuVmFsdWUoKSk7CisgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5ib29sZWFuVmFsdWUoKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmQoVEFHLCAiQWRkZWQgZmlsZSBncm91cCAiICsgc3RlcDJGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBMb2cuZChUQUcsICJGYWlsZWQgdG8gYWRkIGZpbGUgZ3JvdXAgIiArIHN0ZXAyRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKTsKKyAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KSB7CisgICAgICAgICAgICAgICAgICAgICAgTG9nLmUoVEFHLCAiRmFpbGVkIHRvIGFkZCBmaWxlIGdyb3VwIiwgdCk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCkpOworICAgICAgICAgICAgICByZXR1cm4gYWRkRmlsZUdyb3VwRnV0dXJlOworICAgICAgICAgICAgfSwKKyAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3IoKSkKKyAgICAgICAgLnRyYW5zZm9ybShhZGRGaWxlR3JvdXBTdWNjZWVkZWQgLT4gbnVsbCwgTW9yZUV4ZWN1dG9ycy5kaXJlY3RFeGVjdXRvcigpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1ppcEZvbGRlckZpbGVHcm91cFBvcHVsYXRvci5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL1ppcEZvbGRlckZpbGVHcm91cFBvcHVsYXRvci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmZTlhZmQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvWmlwRm9sZGVyRmlsZUdyb3VwUG9wdWxhdG9yLmphdmEKQEAgLTAsMCArMSwxMTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC51dGlsLkxvZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRvd25sb2FkQ29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VOZXR3b3JrUG9saWN5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLlRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm1zOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLlRyYW5zZm9ybVByb3RvLlppcFRyYW5zZm9ybTsKKworLyoqIFRlc3QgRmlsZUdyb3VwIFBvcHVsYXRvciB3aXRoIHppcCBmaWxlIHdoaWNoIGNvbnRhaW5zIDMgZmlsZXMgYW5kIG9uZSBzdWItZm9sZGVyLiAqLworcHVibGljIGNsYXNzIFppcEZvbGRlckZpbGVHcm91cFBvcHVsYXRvciBpbXBsZW1lbnRzIEZpbGVHcm91cFBvcHVsYXRvciB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJNREQgWmlwRm9sZGVyRmlsZUdyb3VwUG9wdWxhdG9yIjsKKworICBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfR1JPVVBfTkFNRSA9ICJ0ZXN0LXppcC1ncm91cCI7CisgIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9JRCA9ICJ0ZXN0LXppcC1maWxlLWlkIjsKKyAgc3RhdGljIGZpbmFsIGludCBGSUxFX1NJWkUgPSAzNzM7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGSUxFX0NIRUNLU1VNID0gIjcwMjRiNmJjZGRmMmIyODk3NjU2ZTkzNTNmN2ZjNzE1ZGY1ZWE5ODYiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9VUkwgPQorICAgICAgImh0dHBzOi8vd3d3LmdzdGF0aWMuY29tL2ljaW5nL2lkZC9hcGl0ZXN0L3ppcF90ZXN0X2ZvbGRlci56aXAiOworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0OworCisgIHB1YmxpYyBaaXBGb2xkZXJGaWxlR3JvdXBQb3B1bGF0b3IoQ29udGV4dCBjb250ZXh0KSB7CisgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiByZWZyZXNoRmlsZUdyb3VwcyhNb2JpbGVEYXRhRG93bmxvYWQgbW9iaWxlRGF0YURvd25sb2FkKSB7CisgICAgRGF0YUZpbGVHcm91cCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIEZJTEVfR1JPVVBfTkFNRSwKKyAgICAgICAgICAgIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSwKKyAgICAgICAgICAgIG5ldyBTdHJpbmdbXSB7RklMRV9JRH0sCisgICAgICAgICAgICBuZXcgaW50W10ge0ZJTEVfU0laRX0sCisgICAgICAgICAgICBuZXcgU3RyaW5nW10ge0ZJTEVfQ0hFQ0tTVU19LAorICAgICAgICAgICAgbmV3IFN0cmluZ1tdIHtGSUxFX1VSTH0sCisgICAgICAgICAgICBEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Qm9vbGVhbj4gYWRkRmlsZUdyb3VwRnV0dXJlID0KKyAgICAgICAgbW9iaWxlRGF0YURvd25sb2FkLmFkZEZpbGVHcm91cCgKKyAgICAgICAgICAgIEFkZEZpbGVHcm91cFJlcXVlc3QubmV3QnVpbGRlcigpLnNldERhdGFGaWxlR3JvdXAoZGF0YUZpbGVHcm91cCkuYnVpbGQoKSk7CisgICAgcmV0dXJuIEZ1dHVyZXMudHJhbnNmb3JtKAorICAgICAgICBhZGRGaWxlR3JvdXBGdXR1cmUsCisgICAgICAgIHJlc3VsdCAtPiB7CisgICAgICAgICAgaWYgKHJlc3VsdC5ib29sZWFuVmFsdWUoKSkgeworICAgICAgICAgICAgTG9nLmQoVEFHLCAiQWRkZWQgZmlsZSBncm91cHMgIiArIGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBMb2cuZChUQUcsICJGYWlsZWQgdG8gYWRkIGZpbGUgZ3JvdXAgIiArIGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gbnVsbDsKKyAgICAgICAgfSwKKyAgICAgICAgTW9yZUV4ZWN1dG9ycy5kaXJlY3RFeGVjdXRvcigpKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgRGF0YUZpbGVHcm91cCBjcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgU3RyaW5nIGdyb3VwTmFtZSwKKyAgICAgIFN0cmluZyBvd25lclBhY2thZ2UsCisgICAgICBTdHJpbmdbXSBmaWxlSWQsCisgICAgICBpbnRbXSBieXRlU2l6ZSwKKyAgICAgIFN0cmluZ1tdIGNoZWNrc3VtLAorICAgICAgU3RyaW5nW10gdXJsLAorICAgICAgRGV2aWNlTmV0d29ya1BvbGljeSBkZXZpY2VOZXR3b3JrUG9saWN5KSB7CisgICAgaWYgKGZpbGVJZC5sZW5ndGggIT0gYnl0ZVNpemUubGVuZ3RoCisgICAgICAgIHx8IGZpbGVJZC5sZW5ndGggIT0gY2hlY2tzdW0ubGVuZ3RoCisgICAgICAgIHx8IGZpbGVJZC5sZW5ndGggIT0gdXJsLmxlbmd0aCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOworICAgIH0KKworICAgIERhdGFGaWxlR3JvdXAuQnVpbGRlciBkYXRhRmlsZUdyb3VwQnVpbGRlciA9CisgICAgICAgIERhdGFGaWxlR3JvdXAubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKGdyb3VwTmFtZSkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2Uob3duZXJQYWNrYWdlKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucygKKyAgICAgICAgICAgICAgICBEb3dubG9hZENvbmRpdGlvbnMubmV3QnVpbGRlcigpLnNldERldmljZU5ldHdvcmtQb2xpY3koZGV2aWNlTmV0d29ya1BvbGljeSkpOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlSWQubGVuZ3RoOyArK2kpIHsKKyAgICAgIERhdGFGaWxlIGZpbGUgPQorICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAuc2V0RmlsZUlkKGZpbGVJZFtpXSkKKyAgICAgICAgICAgICAgLnNldEJ5dGVTaXplKGJ5dGVTaXplW2ldKQorICAgICAgICAgICAgICAuc2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bShjaGVja3N1bVtpXSkKKyAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQodXJsW2ldKQorICAgICAgICAgICAgICAuc2V0RG93bmxvYWRUcmFuc2Zvcm1zKAorICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0WmlwKFppcFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkuc2V0VGFyZ2V0KCIqIikuYnVpbGQoKSkpKQorICAgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAgIGRhdGFGaWxlR3JvdXBCdWlsZGVyLmFkZEZpbGUoZmlsZSk7CisgICAgfQorCisgICAgcmV0dXJuIGRhdGFGaWxlR3JvdXBCdWlsZGVyLmJ1aWxkKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hY2NvdW50L0FjY291bnRVdGlsVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2FjY291bnQvQWNjb3VudFV0aWxUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDc5MzUxNAotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hY2NvdW50L0FjY291bnRVdGlsVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTEyIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5hY2NvdW50OworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CisKK2ltcG9ydCBhbmRyb2lkLmFjY291bnRzLkFjY291bnQ7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKKy8qKiBVbml0IHRlc3RzIGZvciB7QGxpbmsgQWNjb3VudFV0aWx9LiAqLworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGNsYXNzIEFjY291bnRVdGlsVGVzdCB7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY3JlYXRlQWNjb3VudCgpIHsKKyAgICBTdHJpbmcgbmFtZSA9ICJhY2NvdW50LW5hbWUiOworICAgIFN0cmluZyB0eXBlID0gImFjY291bnQtdHlwZSI7CisKKyAgICBBY2NvdW50IGFjY291bnQgPSBBY2NvdW50VXRpbC5jcmVhdGUobmFtZSwgdHlwZSk7CisKKyAgICBhc3NlcnRUaGF0KGFjY291bnQpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoYWNjb3VudC5uYW1lKS5pc0VxdWFsVG8obmFtZSk7CisgICAgYXNzZXJ0VGhhdChhY2NvdW50LnR5cGUpLmlzRXF1YWxUbyh0eXBlKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNyZWF0ZUFjY291bnRfZW1wdHlGaWVsZCgpIHsKKyAgICBTdHJpbmcgbmFtZSA9ICJhY2NvdW50LW5hbWUiOworICAgIFN0cmluZyB0eXBlID0gImFjY291bnQtdHlwZSI7CisKKyAgICAvLyBOZWl0aGVyIG5hbWUgbm9yIHR5cGUgY2FuIGJlIGVtcHR5LgorICAgIGFzc2VydFRoYXQoQWNjb3VudFV0aWwuY3JlYXRlKCIiIC8qIG5hbWUgKi8sIHR5cGUpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KEFjY291bnRVdGlsLmNyZWF0ZShudWxsIC8qIG5hbWUgKi8sIHR5cGUpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KEFjY291bnRVdGlsLmNyZWF0ZShuYW1lLCAiIiAvKiB0eXBlICovKSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChBY2NvdW50VXRpbC5jcmVhdGUobmFtZSwgbnVsbCAvKiB0eXBlICovKSkuaXNOdWxsKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjcmVhdGVBY2NvdW50X2NvbnRhaW5EZWxpbWl0ZXIoKSB7CisgICAgU3RyaW5nIG5hbWUgPSAiYWNjb3VudC1uYW1lIjsKKyAgICBTdHJpbmcgdHlwZSA9ICJhY2NvdW50LXR5cGUiOworCisgICAgLy8gTmVpdGhlciBuYW1lIG9yIHR5cGUgY2FuIGNvbnRhaW4gYWNjb3VudCBkZWxpbWl0ZXIuCisgICAgYXNzZXJ0VGhhdChBY2NvdW50VXRpbC5jcmVhdGUoInByZWZpeDpzdWZmaXgiIC8qIG5hbWUgKi8sIHR5cGUpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KEFjY291bnRVdGlsLmNyZWF0ZShuYW1lLCAicHJlZml4OnN1ZmZpeCIgLyogdHlwZSAqLykpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY3JlYXRlQWNjb3VudF9jb250YWluU3BsaXRDaGFyKCkgeworICAgIFN0cmluZyBuYW1lID0gImFjY291bnQtbmFtZSI7CisgICAgU3RyaW5nIHR5cGUgPSAiYWNjb3VudC10eXBlIjsKKworICAgIC8vIE5laXRoZXIgbmFtZSBvciB0eXBlIGNhbiBjb250YWluIHNwbGl0IGNoYXIuCisgICAgYXNzZXJ0VGhhdChBY2NvdW50VXRpbC5jcmVhdGUoInByZWZpeHxzdWZmaXgiIC8qIG5hbWUgKi8sIHR5cGUpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KEFjY291bnRVdGlsLmNyZWF0ZShuYW1lLCAicHJlZml4fHN1ZmZpeCIgLyogdHlwZSAqLykpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2VyaWFsaXplQWNjb3VudCgpIHsKKyAgICBTdHJpbmcgbmFtZSA9ICJhY2NvdW50LW5hbWUiOworICAgIFN0cmluZyB0eXBlID0gImFjY291bnQtdHlwZSI7CisKKyAgICBBY2NvdW50IGFjY291bnQgPSBuZXcgQWNjb3VudChuYW1lLCB0eXBlKTsKKyAgICBTdHJpbmcgc2VyaWFsaXplZCA9IEFjY291bnRVdGlsLnNlcmlhbGl6ZShhY2NvdW50KTsKKworICAgIGFzc2VydFRoYXQoc2VyaWFsaXplZCkuaXNFcXVhbFRvKCJhY2NvdW50LXR5cGU6YWNjb3VudC1uYW1lIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZXNlcmlhbGl6ZUFjY291bnQoKSB7CisgICAgU3RyaW5nIGFjY291bnRTdHIgPSAiZm9vOmJhciI7CisgICAgQWNjb3VudCBhY2NvdW50ID0gQWNjb3VudFV0aWwuZGVzZXJpYWxpemUoYWNjb3VudFN0cik7CisKKyAgICBhc3NlcnRUaGF0KGFjY291bnQudHlwZSkuaXNFcXVhbFRvKCJmb28iKTsKKyAgICBhc3NlcnRUaGF0KGFjY291bnQubmFtZSkuaXNFcXVhbFRvKCJiYXIiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRlc2VyaWFsaXplQWNjb3VudF9ub0RlbGltaXRlcigpIHsKKyAgICAvLyBObyBhY2NvdW50IGRlbGltaXRlciBpcyBmb3VuZC4KKyAgICBhc3NlcnRUaGF0KEFjY291bnRVdGlsLmRlc2VyaWFsaXplKCJ0eXBlIGFuZCBuYW1lIikpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZGVzZXJpYWxpemVBY2NvdW50X211bHRpcGxlRGVsaW1pdGVyKCkgeworICAgIC8vIE11bHRpcGxlIGFjY291bnQgZGVsaW1pdGVycyBhcmUgZm91bmQuCisgICAgYXNzZXJ0VGhhdChBY2NvdW50VXRpbC5kZXNlcmlhbGl6ZSgidHlwZTpuYW1lOmZvbyIpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KEFjY291bnRVdGlsLmRlc2VyaWFsaXplKCJ0eXBlOjpuYW1lIikpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZGVzZXJpYWxpemVBY2NvdW50X2NvbnRhaW5zU3BsaXRjaGFyKCkgeworICAgIC8vIE5laXRoZXIgbmFtZSBvciB0eXBlIGNhbiBjb250YWluIHNwbGl0IGNoYXIuCisgICAgYXNzZXJ0VGhhdChBY2NvdW50VXRpbC5kZXNlcmlhbGl6ZSgidHlwZTpuYXxtZSIpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KEFjY291bnRVdGlsLmRlc2VyaWFsaXplKCJ0eXxwZTpuYW1lIikpLmlzTnVsbCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYWNjb3VudC9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9hY2NvdW50L0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ4ZTIzZDkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYWNjb3VudC9CVUlMRApAQCAtMCwwICsxLDMyIEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9sb2NhbF90ZXN0IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiQWNjb3VudFV0aWxUZXN0IiwKKyAgICBzcmNzID0gWyJBY2NvdW50VXRpbFRlc3QuamF2YSJdLAorICAgIG1hbmlmZXN0X3ZhbHVlcyA9IHsKKyAgICAgICAgIm1pblNka1ZlcnNpb24iOiAiMTYiLAorICAgICAgICAidGFyZ2V0U2RrVmVyc2lvbiI6ICIyNyIsCisgICAgfSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2FjY291bnQ6QWNjb3VudFV0aWwiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvQlVJTEQgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NjhhNTQ3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvQlVJTEQKQEAgLTAsMCArMSw0NyBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6dGVzdF9kZWZzLmJ6bCIsICJtZGRfbG9jYWxfdGVzdCIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWyIvLzpfX3N1YnBhY2thZ2VzX18iXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK21kZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiTXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlclRlc3QiLAorICAgIHNyY3MgPSBbIk11bHRpU2NoZW1lRmlsZURvd25sb2FkZXJUZXN0LmphdmEiXSwKKyAgICB0ZXN0X2NsYXNzID0gImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuTXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlclRlc3QiLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlcjpGaWxlRG93bmxvYWRlciIsCisgICAgICAgICJAYW5kcm9pZF9zZGtfbGludXgiLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCittZGRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkRvd25sb2FkUmVxdWVzdFRlc3QiLAorICAgIHNyY3MgPSBbIkRvd25sb2FkUmVxdWVzdFRlc3QuamF2YSJdLAorICAgIHRlc3RfY2xhc3MgPSAiY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3RUZXN0IiwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZpbGVTb3VyY2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXI6RmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOk1kZENvbnN0YW50cyIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9wcm90b2J1Zi8vOnByb3RvYnVmX2xpdGUiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvRG93bmxvYWRSZXF1ZXN0VGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvRG93bmxvYWRSZXF1ZXN0VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgxMTU0NDMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9Eb3dubG9hZFJlcXVlc3RUZXN0LmphdmEKQEAgLTAsMCArMSw2MyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlcjsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZGRDb25zdGFudHMuSU5MSU5FX0ZJTEVfVVJMX1NDSEVNRTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5leHQuanVuaXQucnVubmVycy5BbmRyb2lkSlVuaXQ0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkZpbGVTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKKworQFJ1bldpdGgoQW5kcm9pZEpVbml0NC5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBEb3dubG9hZFJlcXVlc3RUZXN0IHsKKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZF93aGVuSW5saW5lRmlsZVVybF93aGVuSW5saW5lRG93bmxvYWRQYXJhbXNOb3RQcm92aWRlZF90aHJvd3MoKSB7CisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICgpIC0+CisgICAgICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImlubGluZWZpbGU6c2hhMTp0ZXN0IikKKyAgICAgICAgICAgICAgICAuc2V0RmlsZVVyaSgKKyAgICAgICAgICAgICAgICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICAgICAgICAgICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyL3Rlc3QiKSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZF93aGVuSW5saW5lRmlsZVVybF93aGVuSW5saW5lRG93bmxvYWRQYXJhbXNQcm92aWRlZF9idWlsZHMoKSB7CisgICAgRG93bmxvYWRSZXF1ZXN0IHJlcXVlc3QgPQorICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTpzaGExOnRlc3QiKQorICAgICAgICAgICAgLnNldEZpbGVVcmkoCisgICAgICAgICAgICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICAgICAgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIvdGVzdCIpKQorICAgICAgICAgICAgLnNldElubGluZURvd25sb2FkUGFyYW1zT3B0aW9uYWwoCisgICAgICAgICAgICAgICAgSW5saW5lRG93bmxvYWRQYXJhbXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRJbmxpbmVGaWxlQ29udGVudCgKKyAgICAgICAgICAgICAgICAgICAgICAgIEZpbGVTb3VyY2Uub2ZCeXRlU3RyaW5nKEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KCJURVNUX0NPTlRFTlQiKSkpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaGF0KHJlcXVlc3QuaW5saW5lRG93bmxvYWRQYXJhbXNPcHRpb25hbCgpKS5pc1ByZXNlbnQoKTsKKyAgICBhc3NlcnRUaGF0KHJlcXVlc3QudXJsVG9Eb3dubG9hZCgpKS5zdGFydHNXaXRoKElOTElORV9GSUxFX1VSTF9TQ0hFTUUpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9NdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvTXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MzJmNGQ5Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvTXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDE3NiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlcjsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLmFueTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLndoZW47CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5leHQuanVuaXQucnVubmVycy5BbmRyb2lkSlVuaXQ0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5TZXR0YWJsZUZ1dHVyZTsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Nb2NrOworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9KVW5pdDsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvUnVsZTsKKworQFJ1bldpdGgoQW5kcm9pZEpVbml0NC5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBNdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyVGVzdCB7CisKKyAgQFJ1bGUgcHVibGljIGZpbmFsIE1vY2tpdG9SdWxlIG1vY2tzID0gTW9ja2l0b0pVbml0LnJ1bGUoKTsKKworICBATW9jayBGaWxlRG93bmxvYWRlciBtb2NrU3RhbmRhcmREb3dubG9hZGVyOworICBTZXR0YWJsZUZ1dHVyZTxWb2lkPiBtb2NrU3RhbmRhcmREb3dubG9hZGVyRG93bmxvYWRGdXR1cmUgPSBTZXR0YWJsZUZ1dHVyZS5jcmVhdGUoKTsKKyAgU2V0dGFibGVGdXR1cmU8Q2hlY2tDb250ZW50Q2hhbmdlUmVzcG9uc2U+IG1vY2tTdGFuZGFyZERvd25sb2FkZXJJc0NvbnRlbnRDaGFuZ2VkRnV0dXJlID0KKyAgICAgIFNldHRhYmxlRnV0dXJlLmNyZWF0ZSgpOworCisgIEBNb2NrIEZpbGVEb3dubG9hZGVyIG1vY2tQaXJEb3dubG9hZGVyOworICBTZXR0YWJsZUZ1dHVyZTxWb2lkPiBtb2NrUGlyRG93bmxvYWRlckRvd25sb2FkRnV0dXJlID0gU2V0dGFibGVGdXR1cmUuY3JlYXRlKCk7CisgIFNldHRhYmxlRnV0dXJlPENoZWNrQ29udGVudENoYW5nZVJlc3BvbnNlPiBtb2NrUGlyRG93bmxvYWRlcklzQ29udGVudENoYW5nZWRGdXR1cmUgPQorICAgICAgU2V0dGFibGVGdXR1cmUuY3JlYXRlKCk7CisKKyAgTXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlciBkb3dubG9hZGVyOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB7CisKKyAgICB3aGVuKG1vY2tTdGFuZGFyZERvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZyhhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKG1vY2tTdGFuZGFyZERvd25sb2FkZXJEb3dubG9hZEZ1dHVyZSk7CisgICAgd2hlbihtb2NrU3RhbmRhcmREb3dubG9hZGVyLmlzQ29udGVudENoYW5nZWQoYW55KCkpKQorICAgICAgICAudGhlblJldHVybihtb2NrU3RhbmRhcmREb3dubG9hZGVySXNDb250ZW50Q2hhbmdlZEZ1dHVyZSk7CisgICAgd2hlbihtb2NrUGlyRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKGFueSgpKSkudGhlblJldHVybihtb2NrUGlyRG93bmxvYWRlckRvd25sb2FkRnV0dXJlKTsKKyAgICB3aGVuKG1vY2tQaXJEb3dubG9hZGVyLmlzQ29udGVudENoYW5nZWQoYW55KCkpKQorICAgICAgICAudGhlblJldHVybihtb2NrUGlyRG93bmxvYWRlcklzQ29udGVudENoYW5nZWRGdXR1cmUpOworCisgICAgZG93bmxvYWRlciA9CisgICAgICAgIE11bHRpU2NoZW1lRmlsZURvd25sb2FkZXIuYnVpbGRlcigpCisgICAgICAgICAgICAuYWRkU2NoZW1lKCJodHRwIiwgbW9ja1N0YW5kYXJkRG93bmxvYWRlcikKKyAgICAgICAgICAgIC5hZGRTY2hlbWUoImh0dHBzIiwgbW9ja1N0YW5kYXJkRG93bmxvYWRlcikKKyAgICAgICAgICAgIC5hZGRTY2hlbWUoInBpciIsIG1vY2tQaXJEb3dubG9hZGVyKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRTY2hlbWVfd29ya3NGb3JIdHRwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhhdChNdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyLmdldFNjaGVtZSgiaHR0cDovL3d3dy5nb29nbGUuY29tIikpLmlzRXF1YWxUbygiaHR0cCIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0U2NoZW1lX3dvcmtzRm9ySHR0cHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaGF0KE11bHRpU2NoZW1lRmlsZURvd25sb2FkZXIuZ2V0U2NoZW1lKCJodHRwczovL3d3dy5nb29nbGUuY29tIikpLmlzRXF1YWxUbygiaHR0cHMiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdldFNjaGVtZV93b3Jrc0ZvckZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaGF0KE11bHRpU2NoZW1lRmlsZURvd25sb2FkZXIuZ2V0U2NoZW1lKCJmaWxlOi8vL2xvY2FsaG9zdC9iYXIiKSkuaXNFcXVhbFRvKCJmaWxlIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRTY2hlbWVfd29ya3NGb3JEYXRhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3RyaW5nIHVybCA9ICJkYXRhOjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxTR1ZzYkc4Z1lXNWtjbTlwWkNFPSI7CisgICAgYXNzZXJ0VGhhdChNdWx0aVNjaGVtZUZpbGVEb3dubG9hZGVyLmdldFNjaGVtZSh1cmwpKS5pc0VxdWFsVG8oImRhdGEiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdldFNjaGVtZV93b3Jrc0ZvclBpcigpIHRocm93cyBFeGNlcHRpb24geworICAgIFN0cmluZyB1cmwgPSAicGlyOi8vZXhhbXBsZS5jb206MTIzNC9kYXRhYmFzZS92ZXJzaW9uLzMiOworICAgIGFzc2VydFRoYXQoTXVsdGlTY2hlbWVGaWxlRG93bmxvYWRlci5nZXRTY2hlbWUodXJsKSkuaXNFcXVhbFRvKCJwaXIiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHN0YXJ0RG93bmxvYWRpbmdfZGVsZWdhdGVzQ29ycmVjdGx5X2h0dHAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEb3dubG9hZFJlcXVlc3QgZG93bmxvYWRSZXF1ZXN0ID0KKyAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImh0dHA6Ly93d3cuZ29vZ2xlLmNvbSIpCisgICAgICAgICAgICAuc2V0RmlsZVVyaShVcmkucGFyc2UoImZpbGU6Ly9kZXYvbnVsbCIpKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5OT05FKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBmdXR1cmUgPSBkb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoZG93bmxvYWRSZXF1ZXN0KTsKKworICAgIHZlcmlmeShtb2NrU3RhbmRhcmREb3dubG9hZGVyKS5zdGFydERvd25sb2FkaW5nKGRvd25sb2FkUmVxdWVzdCk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTdGFuZGFyZERvd25sb2FkZXIpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrUGlyRG93bmxvYWRlcik7CisgICAgYXNzZXJ0VGhhdChmdXR1cmUuaXNEb25lKCkpLmlzRmFsc2UoKTsKKworICAgIC8vIE1ha2Ugc3VyZSB3ZSBhY3R1YWxseSBnb3QgKGEgdmlldyBvZikgdGhlIGNvcnJlY3QgZnV0dXJlLgorICAgIG1vY2tTdGFuZGFyZERvd25sb2FkZXJEb3dubG9hZEZ1dHVyZS5zZXQobnVsbCk7CisgICAgYXNzZXJ0VGhhdChmdXR1cmUuaXNEb25lKCkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc3RhcnREb3dubG9hZGluZ19kZWxlZ2F0ZXNDb3JyZWN0bHlfcGlyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIERvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJwaXI6Ly9leGFtcGxlLmNvbToxMjM0L2RhdGFiYXNlL3ZlcnNpb24vMyIpCisgICAgICAgICAgICAuc2V0RmlsZVVyaShVcmkucGFyc2UoImZpbGU6Ly9kZXYvbnVsbCIpKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5OT05FKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBmdXR1cmUgPSBkb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoZG93bmxvYWRSZXF1ZXN0KTsKKworICAgIHZlcmlmeShtb2NrUGlyRG93bmxvYWRlcikuc3RhcnREb3dubG9hZGluZyhkb3dubG9hZFJlcXVlc3QpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU3RhbmRhcmREb3dubG9hZGVyKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1BpckRvd25sb2FkZXIpOworICAgIGFzc2VydFRoYXQoZnV0dXJlLmlzRG9uZSgpKS5pc0ZhbHNlKCk7CisKKyAgICAvLyBNYWtlIHN1cmUgd2UgYWN0dWFsbHkgZ290IChhIHZpZXcgb2YpIHRoZSBjb3JyZWN0IGZ1dHVyZS4KKyAgICBtb2NrUGlyRG93bmxvYWRlckRvd25sb2FkRnV0dXJlLnNldChudWxsKTsKKyAgICBhc3NlcnRUaGF0KGZ1dHVyZS5pc0RvbmUoKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpc0NvbnRlbnRDaGFuZ2VkX2RlbGVnYXRlc0NvcnJlY3RseV9odHRwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQ2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdCBjaGVja0NvbnRlbnRDaGFuZ2VSZXF1ZXN0ID0KKyAgICAgICAgQ2hlY2tDb250ZW50Q2hhbmdlUmVxdWVzdC5uZXdCdWlsZGVyKCkuc2V0VXJsKCJodHRwOi8vd3d3Lmdvb2dsZS5jb20iKS5idWlsZCgpOworICAgIExpc3RlbmFibGVGdXR1cmU8Q2hlY2tDb250ZW50Q2hhbmdlUmVzcG9uc2U+IGZ1dHVyZSA9CisgICAgICAgIGRvd25sb2FkZXIuaXNDb250ZW50Q2hhbmdlZChjaGVja0NvbnRlbnRDaGFuZ2VSZXF1ZXN0KTsKKworICAgIHZlcmlmeShtb2NrU3RhbmRhcmREb3dubG9hZGVyKS5pc0NvbnRlbnRDaGFuZ2VkKGNoZWNrQ29udGVudENoYW5nZVJlcXVlc3QpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU3RhbmRhcmREb3dubG9hZGVyKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1BpckRvd25sb2FkZXIpOworICAgIGFzc2VydFRoYXQoZnV0dXJlLmlzRG9uZSgpKS5pc0ZhbHNlKCk7CisKKyAgICAvLyBNYWtlIHN1cmUgd2UgYWN0dWFsbHkgZ290IChhIHZpZXcgb2YpIHRoZSBjb3JyZWN0IGZ1dHVyZS4KKyAgICBtb2NrU3RhbmRhcmREb3dubG9hZGVySXNDb250ZW50Q2hhbmdlZEZ1dHVyZS5zZXQoCisgICAgICAgIENoZWNrQ29udGVudENoYW5nZVJlc3BvbnNlLm5ld0J1aWxkZXIoKS5zZXRDb250ZW50Q2hhbmdlZCh0cnVlKS5idWlsZCgpKTsKKyAgICBhc3NlcnRUaGF0KGZ1dHVyZS5pc0RvbmUoKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpc0NvbnRlbnRDaGFuZ2VkX2RlbGVnYXRlc0NvcnJlY3RseV9waXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDaGVja0NvbnRlbnRDaGFuZ2VSZXF1ZXN0IGNoZWNrQ29udGVudENoYW5nZVJlcXVlc3QgPQorICAgICAgICBDaGVja0NvbnRlbnRDaGFuZ2VSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFVybCgicGlyOi8vZXhhbXBsZS5jb206MTIzNC9kYXRhYmFzZS92ZXJzaW9uLzMiKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxDaGVja0NvbnRlbnRDaGFuZ2VSZXNwb25zZT4gZnV0dXJlID0KKyAgICAgICAgZG93bmxvYWRlci5pc0NvbnRlbnRDaGFuZ2VkKGNoZWNrQ29udGVudENoYW5nZVJlcXVlc3QpOworCisgICAgdmVyaWZ5KG1vY2tQaXJEb3dubG9hZGVyKS5pc0NvbnRlbnRDaGFuZ2VkKGNoZWNrQ29udGVudENoYW5nZVJlcXVlc3QpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU3RhbmRhcmREb3dubG9hZGVyKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1BpckRvd25sb2FkZXIpOworICAgIGFzc2VydFRoYXQoZnV0dXJlLmlzRG9uZSgpKS5pc0ZhbHNlKCk7CisKKyAgICAvLyBNYWtlIHN1cmUgd2UgYWN0dWFsbHkgZ290IChhIHZpZXcgb2YpIHRoZSBjb3JyZWN0IGZ1dHVyZS4KKyAgICBtb2NrUGlyRG93bmxvYWRlcklzQ29udGVudENoYW5nZWRGdXR1cmUuc2V0KAorICAgICAgICBDaGVja0NvbnRlbnRDaGFuZ2VSZXNwb25zZS5uZXdCdWlsZGVyKCkuc2V0Q29udGVudENoYW5nZWQodHJ1ZSkuYnVpbGQoKSk7CisgICAgYXNzZXJ0VGhhdChmdXR1cmUuaXNEb25lKCkpLmlzVHJ1ZSgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9pbmxpbmUvQlVJTEQgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9pbmxpbmUvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjEwZjVjZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL2lubGluZS9CVUlMRApAQCAtMCwwICsxLDM5IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDp0ZXN0X2RlZnMuYnpsIiwgIm1kZF9sb2NhbF90ZXN0IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworbWRkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJJbmxpbmVGaWxlRG93bmxvYWRlclRlc3QiLAorICAgIHNyY3MgPSBbIklubGluZUZpbGVEb3dubG9hZGVyVGVzdC5qYXZhIl0sCisgICAgdGVzdF9jbGFzcyA9ICJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLmlubGluZS5JbmxpbmVGaWxlRG93bmxvYWRlclRlc3QiLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZpbGVTb3VyY2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXI6RmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvaW5saW5lOklubGluZUZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFuZHJvaWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3Rpbmc6ZmFrZV9maWxlX2JhY2tlbmQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW0iLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzpwcm90b2J1Zl9saXRlIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL2lubGluZS9JbmxpbmVGaWxlRG93bmxvYWRlclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL2lubGluZS9JbmxpbmVGaWxlRG93bmxvYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hN2UzOTJiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvaW5saW5lL0lubGluZUZpbGVEb3dubG9hZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLmlubGluZTsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5leHQuanVuaXQucnVubmVycy5BbmRyb2lkSlVuaXQ0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uLkRvd25sb2FkUmVzdWx0Q29kZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GaWxlU291cmNlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRDb25zdHJhaW50czsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLklubGluZURvd25sb2FkUGFyYW1zOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkZha2VGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkZha2VGaWxlQmFja2VuZC5PcGVyYXRpb25UeXBlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWFkU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgb3JnLmp1bml0LkFmdGVyOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworCitAUnVuV2l0aChBbmRyb2lkSlVuaXQ0LmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIElubGluZUZpbGVEb3dubG9hZGVyVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfTkFNRSA9ICJmaWxlTmFtZSI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbGVTb3VyY2UgRklMRV9DT05URU5UID0KKyAgICAgIEZpbGVTb3VyY2Uub2ZCeXRlU3RyaW5nKEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KCJURVNUX0NPTlRFTlQiKSk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEV4ZWN1dG9yIERPV05MT0FEX0VYRUNVVE9SID0gRXhlY3V0b3JzLm5ld1NjaGVkdWxlZFRocmVhZFBvb2woMik7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIENvbnRleHQgQ09OVEVYVCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmFrZUZpbGVCYWNrZW5kIEZBS0VfRklMRV9CQUNLRU5EID0KKyAgICAgIG5ldyBGYWtlRmlsZUJhY2tlbmQoQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoQ09OVEVYVCkuYnVpbGQoKSk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgRklMRV9TVE9SQUdFID0KKyAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgIC8qIGJhY2tlbmRzID0gKi8gSW1tdXRhYmxlTGlzdC5vZihGQUtFX0ZJTEVfQkFDS0VORCksCisgICAgICAgICAgLyogdHJhbnNmb3JtcyA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAvKiBtb25pdG9ycyA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSk7CisKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgZmlsZVVyaSA9CisgICAgICBVcmkucGFyc2UoCisgICAgICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLmlubGluZS9maWxlcy9kYXRhZG93bmxvYWQvc2hhcmVkL3B1YmxpYy8iCisgICAgICAgICAgICAgICsgRklMRV9OQU1FKTsKKworICBwcml2YXRlIElubGluZUZpbGVEb3dubG9hZGVyIGlubGluZUZpbGVEb3dubG9hZGVyOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB7CisgICAgaW5saW5lRmlsZURvd25sb2FkZXIgPSBuZXcgSW5saW5lRmlsZURvd25sb2FkZXIoRklMRV9TVE9SQUdFLCBET1dOTE9BRF9FWEVDVVRPUik7CisgIH0KKworICBAQWZ0ZXIKKyAgcHVibGljIHZvaWQgdGVhckRvd24oKSB7CisgICAgRkFLRV9GSUxFX0JBQ0tFTkQuY2xlYXJGYWlsdXJlKE9wZXJhdGlvblR5cGUuQUxMKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHN0YXJ0RG93bmxvYWRpbmdfd2hlbk5vbklubGluZUZpbGVTY2hlbWVHaXZlbl9mYWlscygpIHRocm93cyBFeGNlcHRpb24geworICAgIERvd25sb2FkUmVxdWVzdCBodHRwc0Rvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIERvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJodHRwczovL3VybC50by5kb3dubG9hZCIpCisgICAgICAgICAgICAuc2V0RmlsZVVyaShmaWxlVXJpKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5OT05FKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPiBpbmxpbmVGaWxlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKGh0dHBzRG93bmxvYWRSZXF1ZXN0KS5nZXQoKSk7CisKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIERvd25sb2FkRXhjZXB0aW9uIGRleCA9IChEb3dubG9hZEV4Y2VwdGlvbikgZXguZ2V0Q2F1c2UoKTsKKyAgICBhc3NlcnRUaGF0KGRleC5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuSU5WQUxJRF9JTkxJTkVfRklMRV9VUkxfU0NIRU1FKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHN0YXJ0RG93bmxvYWRpbmdfd2hlbkNvcHlGYWlsc19mYWlscygpIHRocm93cyBFeGNlcHRpb24geworICAgIEZBS0VfRklMRV9CQUNLRU5ELnNldEZhaWx1cmUoT3BlcmF0aW9uVHlwZS5XUklURV9TVFJFQU0sIG5ldyBJT0V4Y2VwdGlvbigidGVzdCBleGNlcHRpb24iKSk7CisKKyAgICBEb3dubG9hZFJlcXVlc3QgZG93bmxvYWRSZXF1ZXN0ID0KKyAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImlubGluZWZpbGU6c2hhMTphYmMiKQorICAgICAgICAgICAgLnNldEZpbGVVcmkoZmlsZVVyaSkKKyAgICAgICAgICAgIC5zZXRJbmxpbmVEb3dubG9hZFBhcmFtc09wdGlvbmFsKAorICAgICAgICAgICAgICAgIElubGluZURvd25sb2FkUGFyYW1zLm5ld0J1aWxkZXIoKS5zZXRJbmxpbmVGaWxlQ29udGVudChGSUxFX0NPTlRFTlQpLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+IGlubGluZUZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoZG93bmxvYWRSZXF1ZXN0KS5nZXQoKSk7CisKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIERvd25sb2FkRXhjZXB0aW9uIGRleCA9IChEb3dubG9hZEV4Y2VwdGlvbikgZXguZ2V0Q2F1c2UoKTsKKyAgICBhc3NlcnRUaGF0KGRleC5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkuaXNFcXVhbFRvKERvd25sb2FkUmVzdWx0Q29kZS5JTkxJTkVfRklMRV9JT19FUlJPUik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzdGFydERvd25sb2FkaW5nX3doZW5Db3B5Q29tcGxldGVzX2lzU3VjY2VzcygpIHRocm93cyBFeGNlcHRpb24geworICAgIERvd25sb2FkUmVxdWVzdCBkb3dubG9hZFJlcXVlc3QgPQorICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTpzaGExOmFiYyIpCisgICAgICAgICAgICAuc2V0RmlsZVVyaShmaWxlVXJpKQorICAgICAgICAgICAgLnNldElubGluZURvd25sb2FkUGFyYW1zT3B0aW9uYWwoCisgICAgICAgICAgICAgICAgSW5saW5lRG93bmxvYWRQYXJhbXMubmV3QnVpbGRlcigpLnNldElubGluZUZpbGVDb250ZW50KEZJTEVfQ09OVEVOVCkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgaW5saW5lRmlsZURvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZyhkb3dubG9hZFJlcXVlc3QpLmdldCgpOworCisgICAgLy8gUmVhZCBmaWxlIGNvbnRlbnQgYmFjayB0byBjaGVjayB0aGF0IGl0IHdhcyBjb3BpZWQgZnJvbSBpbnB1dAorICAgIGFzc2VydFRoYXQoRklMRV9TVE9SQUdFLmV4aXN0cyhmaWxlVXJpKSkuaXNUcnVlKCk7CisgICAgSW5wdXRTdHJlYW0gY29waWVkQ29udGVudFN0cmVhbSA9IEZJTEVfU1RPUkFHRS5vcGVuKGZpbGVVcmksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpOworICAgIEJ5dGVTdHJpbmcgY29waWVkQ29udGVudCA9IEJ5dGVTdHJpbmcucmVhZEZyb20oY29waWVkQ29udGVudFN0cmVhbSk7CisgICAgY29waWVkQ29udGVudFN0cmVhbS5jbG9zZSgpOworICAgIGFzc2VydFRoYXQoY29waWVkQ29udGVudCkuaXNFcXVhbFRvKEZJTEVfQ09OVEVOVC5ieXRlU3RyaW5nKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL0FuZHJvaWRNYW5pZmVzdC54bWwgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL0FuZHJvaWRNYW5pZmVzdC54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjk0YmJjYwotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvQW5kcm9pZE1hbmlmZXN0LnhtbApAQCAtMCwwICsxLDM0IEBACis8IS0tCisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLS0+Cis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI/PgorPG1hbmlmZXN0IHhtbG5zOmFuZHJvaWQ9Imh0dHA6Ly9zY2hlbWFzLmFuZHJvaWQuY29tL2Fway9yZXMvYW5kcm9pZCIKKyAgICBwYWNrYWdlPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLm9mZnJvYWQiID4KKworICA8dXNlcy1zZGsgYW5kcm9pZDptaW5TZGtWZXJzaW9uPSIxNiIgLz4KKyAgPHVzZXMtcGVybWlzc2lvbiBhbmRyb2lkOm5hbWU9ImFuZHJvaWQucGVybWlzc2lvbi5JTlRFUk5FVCIgLz4KKyAgPHVzZXMtcGVybWlzc2lvbiBhbmRyb2lkOm5hbWU9ImFuZHJvaWQucGVybWlzc2lvbi5BQ0NFU1NfTkVUV09SS19TVEFURSIgLz4KKyAgPHVzZXMtcGVybWlzc2lvbiBhbmRyb2lkOm5hbWU9ImFuZHJvaWQucGVybWlzc2lvbi5BQ0NFU1NfV0lGSV9TVEFURSIgLz4KKworICA8YXBwbGljYXRpb24+CisgICAgPHVzZXMtbGlicmFyeSBhbmRyb2lkOm5hbWU9ImFuZHJvaWQudGVzdC5ydW5uZXIiIC8+CisgIDwvYXBwbGljYXRpb24+CisKKyAgPGluc3RydW1lbnRhdGlvbgorICAgICAgYW5kcm9pZDpuYW1lPSJhbmRyb2lkLnRlc3QuSW5zdHJ1bWVudGF0aW9uVGVzdFJ1bm5lciIKKyAgICAgIGFuZHJvaWQ6dGFyZ2V0UGFja2FnZT0iY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5vZmZyb2FkIiAvPgorPC9tYW5pZmVzdD4KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvQlVJTEQgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmYmQzMzAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkL0JVSUxECkBAIC0wLDAgKzEsNjMgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOnRlc3RfZGVmcy5iemwiLCAibWRkX2xvY2FsX3Rlc3QiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCittZGRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIk9mZnJvYWQyRmlsZURvd25sb2FkZXJUZXN0IiwKKyAgICBzcmNzID0gWyJPZmZyb2FkMkZpbGVEb3dubG9hZGVyVGVzdC5qYXZhIl0sCisgICAgZGF0YSA9IFsKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhOmRvd25sb2FkZXJfdGVzdF9kYXRhX2ZpbGVzIiwKKyAgICBdLAorICAgIG1hbmlmZXN0ID0gIkFuZHJvaWRNYW5pZmVzdC54bWwiLAorICAgIHRlc3RfY2xhc3MgPSAiY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5vZmZyb2FkLk9mZnJvYWQyRmlsZURvd25sb2FkZXJUZXN0IiwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyOkZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQ6RXhjZXB0aW9uSGFuZGxlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkOk9mZnJvYWQyRmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXI6ZG93bmxvYWRlcjIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3RyYWNpbmc6Y29uY3VycmVudCIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOlRlc3RIdHRwU2VydmVyIiwKKyAgICAgICAgIkBhbmRyb2lkX3Nka19saW51eCIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ydW5maWxlcyIsCisgICAgICAgICJAZG93bmxvYWRlciIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK21kZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiRXhjZXB0aW9uSGFuZGxlclRlc3QiLAorICAgIHNyY3MgPSBbIkV4Y2VwdGlvbkhhbmRsZXJUZXN0LmphdmEiXSwKKyAgICB0ZXN0X2NsYXNzID0gImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIub2Zmcm9hZC5FeGNlcHRpb25IYW5kbGVyVGVzdCIsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpEb3dubG9hZEV4Y2VwdGlvbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlci9vZmZyb2FkOkV4Y2VwdGlvbkhhbmRsZXIiLAorICAgICAgICAiQGFuZHJvaWRfc2RrX2xpbnV4IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBkb3dubG9hZGVyIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvRXhjZXB0aW9uSGFuZGxlclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvRXhjZXB0aW9uSGFuZGxlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZTZiMTU1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9FeGNlcHRpb25IYW5kbGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTM3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLm9mZnJvYWQ7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkVycm9yRGV0YWlsczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5SZXF1ZXN0RXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uLkRvd25sb2FkUmVzdWx0Q29kZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZU1hcDsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIEV4Y2VwdGlvbkhhbmRsZXJUZXN0IHsKKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtYXBUb0Rvd25sb2FkRXhjZXB0aW9uX3dpdGhEZWZhdWx0SW1wbF9oYW5kbGVzSHR0cFN0YXR1c0Vycm9ycygpIHRocm93cyBFeGNlcHRpb24geworICAgIEVycm9yRGV0YWlscyBlcnJvckRldGFpbHMgPQorICAgICAgICBFcnJvckRldGFpbHMuY3JlYXRlRnJvbUh0dHBFcnJvclJlc3BvbnNlKAorICAgICAgICAgICAgLyogaHR0cFJlc3BvbnNlQ29kZSA9ICovIDQwNCwKKyAgICAgICAgICAgIC8qIGh0dHBSZXNwb25zZUhlYWRlcnMgPSAqLyBJbW11dGFibGVNYXAub2YoKSwKKyAgICAgICAgICAgIC8qIG1lc3NhZ2UgPSAqLyAiNDA0IHJlc3BvbnNlIik7CisgICAgUmVxdWVzdEV4Y2VwdGlvbiByZXF1ZXN0RXhjZXB0aW9uID0gbmV3IFJlcXVlc3RFeGNlcHRpb24oZXJyb3JEZXRhaWxzKTsKKworICAgIEV4Y2VwdGlvbkhhbmRsZXIgaGFuZGxlciA9IEV4Y2VwdGlvbkhhbmRsZXIud2l0aERlZmF1bHRIYW5kbGluZygpOworCisgICAgRG93bmxvYWRFeGNlcHRpb24gcmVtYXBwZWRFeGNlcHRpb24gPQorICAgICAgICBoYW5kbGVyLm1hcFRvRG93bmxvYWRFeGNlcHRpb24oInRlc3QgZXhjZXB0aW9uIiwgcmVxdWVzdEV4Y2VwdGlvbik7CisKKyAgICBhc3NlcnRUaGF0KHJlbWFwcGVkRXhjZXB0aW9uLmdldERvd25sb2FkUmVzdWx0Q29kZSgpKQorICAgICAgICAuaXNFcXVhbFRvKERvd25sb2FkUmVzdWx0Q29kZS5BTkRST0lEX0RPV05MT0FERVJfSFRUUF9FUlJPUik7CisgICAgYXNzZXJ0VGhhdChyZW1hcHBlZEV4Y2VwdGlvbikuaGFzTWVzc2FnZVRoYXQoKS5pc0VxdWFsVG8oInRlc3QgZXhjZXB0aW9uIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZAorICAgICAgbWFwVG9Eb3dubG9hZEV4Y2VwdGlvbl93aXRoRGVmYXVsdEltcGxfaGFuZGxlc0h0dHBTdGF0dXNFcnJvcnNXaXRoRG93bmxvYWRFeGNlcHRpb25VbndyYXBwaW5nKCkKKyAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFcnJvckRldGFpbHMgZXJyb3JEZXRhaWxzID0KKyAgICAgICAgRXJyb3JEZXRhaWxzLmNyZWF0ZUZyb21IdHRwRXJyb3JSZXNwb25zZSgKKyAgICAgICAgICAgIC8qIGh0dHBSZXNwb25zZUNvZGUgPSAqLyA0MDQsCisgICAgICAgICAgICAvKiBodHRwUmVzcG9uc2VIZWFkZXJzID0gKi8gSW1tdXRhYmxlTWFwLm9mKCksCisgICAgICAgICAgICAvKiBtZXNzYWdlID0gKi8gIjQwNCByZXNwb25zZSIpOworICAgIFJlcXVlc3RFeGNlcHRpb24gcmVxdWVzdEV4Y2VwdGlvbiA9IG5ldyBSZXF1ZXN0RXhjZXB0aW9uKGVycm9yRGV0YWlscyk7CisKKyAgICBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5Eb3dubG9hZEV4Y2VwdGlvbiB3cmFwcGVkRXhjZXB0aW9uID0KKyAgICAgICAgbmV3IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkRXhjZXB0aW9uKHJlcXVlc3RFeGNlcHRpb24pOworCisgICAgRXhjZXB0aW9uSGFuZGxlciBoYW5kbGVyID0gRXhjZXB0aW9uSGFuZGxlci53aXRoRGVmYXVsdEhhbmRsaW5nKCk7CisKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiByZW1hcHBlZEV4Y2VwdGlvbiA9CisgICAgICAgIGhhbmRsZXIubWFwVG9Eb3dubG9hZEV4Y2VwdGlvbigidGVzdCBleGNlcHRpb24iLCB3cmFwcGVkRXhjZXB0aW9uKTsKKworICAgIGFzc2VydFRoYXQocmVtYXBwZWRFeGNlcHRpb24uZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpCisgICAgICAgIC5pc0VxdWFsVG8oRG93bmxvYWRSZXN1bHRDb2RlLkFORFJPSURfRE9XTkxPQURFUl9IVFRQX0VSUk9SKTsKKyAgICBhc3NlcnRUaGF0KHJlbWFwcGVkRXhjZXB0aW9uKS5oYXNNZXNzYWdlVGhhdCgpLmlzRXF1YWxUbygidGVzdCBleGNlcHRpb24iKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1hcFRvRG93bmxvYWRFeGNlcHRpb25fd2l0aERlZmF1bHRJbXBsX2hhbmRsZXNHZW5lcmFsRG93bmxvYWRFeGNlcHRpb25FcnJvcigpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5Eb3dubG9hZEV4Y2VwdGlvbiBnZW5lcmFsRXhjZXB0aW9uID0KKyAgICAgICAgbmV3IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkRXhjZXB0aW9uKCJnZW5lcmFsIGVycm9yIik7CisKKyAgICBFeGNlcHRpb25IYW5kbGVyIGhhbmRsZXIgPSBFeGNlcHRpb25IYW5kbGVyLndpdGhEZWZhdWx0SGFuZGxpbmcoKTsKKworICAgIERvd25sb2FkRXhjZXB0aW9uIHJlbWFwcGVkRXhjZXB0aW9uID0KKyAgICAgICAgaGFuZGxlci5tYXBUb0Rvd25sb2FkRXhjZXB0aW9uKCJ0ZXN0IGV4Y2VwdGlvbiIsIGdlbmVyYWxFeGNlcHRpb24pOworCisgICAgYXNzZXJ0VGhhdChyZW1hcHBlZEV4Y2VwdGlvbi5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuQU5EUk9JRF9ET1dOTE9BREVSMl9FUlJPUik7CisgICAgYXNzZXJ0VGhhdChyZW1hcHBlZEV4Y2VwdGlvbikuaGFzTWVzc2FnZVRoYXQoKS5pc0VxdWFsVG8oInRlc3QgZXhjZXB0aW9uIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtYXBUb0Rvd25sb2FkRXhjZXB0aW9uX3dpdGhEZWZhdWx0SW1wbF9yZXR1cm5zVW5rbm93bkV4Y2VwdGlvbldoZW5Db21tb25NYXBwaW5nRmFpbHMoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRXhjZXB0aW9uIHRlc3RFeGNlcHRpb24gPSBuZXcgRXhjZXB0aW9uKCJ0ZXN0Iik7CisKKyAgICBFeGNlcHRpb25IYW5kbGVyIGhhbmRsZXIgPSBFeGNlcHRpb25IYW5kbGVyLndpdGhEZWZhdWx0SGFuZGxpbmcoKTsKKworICAgIERvd25sb2FkRXhjZXB0aW9uIHJlbWFwcGVkRXhjZXB0aW9uID0KKyAgICAgICAgaGFuZGxlci5tYXBUb0Rvd25sb2FkRXhjZXB0aW9uKCJ0ZXN0IGV4Y2VwdGlvbiIsIHRlc3RFeGNlcHRpb24pOworCisgICAgYXNzZXJ0VGhhdChyZW1hcHBlZEV4Y2VwdGlvbi5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUik7CisgICAgYXNzZXJ0VGhhdChyZW1hcHBlZEV4Y2VwdGlvbikuaGFzTWVzc2FnZVRoYXQoKS5pc0VxdWFsVG8oInRlc3QgZXhjZXB0aW9uIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZAorICAgICAgbWFwVG9Eb3dubG9hZEV4Y2VwdGlvbl93aXRoRGVmYXVsdEltcGxfcmV0dXJuc1Vua25vd25FeGNlcHRpb25XaGVuUmVxdWVzdEV4Y2VwdGlvbk1hcHBpbmdGYWlscygpCisgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgUmVxdWVzdEV4Y2VwdGlvbiByZXF1ZXN0RXhjZXB0aW9uID0gbmV3IFJlcXVlc3RFeGNlcHRpb24oImdlbmVyaWMgcmVxdWVzdCBleGNlcHRpb24iKTsKKworICAgIEV4Y2VwdGlvbkhhbmRsZXIgaGFuZGxlciA9IEV4Y2VwdGlvbkhhbmRsZXIud2l0aERlZmF1bHRIYW5kbGluZygpOworCisgICAgRG93bmxvYWRFeGNlcHRpb24gcmVtYXBwZWRFeGNlcHRpb24gPQorICAgICAgICBoYW5kbGVyLm1hcFRvRG93bmxvYWRFeGNlcHRpb24oInRlc3QgZXhjZXB0aW9uIiwgcmVxdWVzdEV4Y2VwdGlvbik7CisKKyAgICBhc3NlcnRUaGF0KHJlbWFwcGVkRXhjZXB0aW9uLmdldERvd25sb2FkUmVzdWx0Q29kZSgpKQorICAgICAgICAuaXNFcXVhbFRvKERvd25sb2FkUmVzdWx0Q29kZS5VTktOT1dOX0VSUk9SKTsKKyAgICBhc3NlcnRUaGF0KHJlbWFwcGVkRXhjZXB0aW9uKS5oYXNNZXNzYWdlVGhhdCgpLmlzRXF1YWxUbygidGVzdCBleGNlcHRpb24iKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1hcFRvRG93bmxvYWRFeGNlcHRpb25fd2l0aERlZmF1bHRJbXBsX2hhbmRsZXNNYWxmb3JtZWRFeGNlcHRpb25DaGFpbigpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBFeGNlcHRpb24gY2F1c2UxID0gbmV3IEV4Y2VwdGlvbigidGVzdCBjYXVzZSAxIik7CisgICAgRXhjZXB0aW9uIGNhdXNlMiA9IG5ldyBFeGNlcHRpb24oInRlc3QgY2F1c2UgMiIsIGNhdXNlMSk7CisgICAgY2F1c2UxLmluaXRDYXVzZShjYXVzZTIpOworCisgICAgRXhjZXB0aW9uSGFuZGxlciBoYW5kbGVyID0gRXhjZXB0aW9uSGFuZGxlci53aXRoRGVmYXVsdEhhbmRsaW5nKCk7CisKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiByZW1hcHBlZEV4Y2VwdGlvbiA9IGhhbmRsZXIubWFwVG9Eb3dubG9hZEV4Y2VwdGlvbigidGVzdCBleGNlcHRpb24iLCBjYXVzZTEpOworCisgICAgYXNzZXJ0VGhhdChyZW1hcHBlZEV4Y2VwdGlvbi5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuVU5LTk9XTl9FUlJPUik7CisgICAgYXNzZXJ0VGhhdChyZW1hcHBlZEV4Y2VwdGlvbikuaGFzTWVzc2FnZVRoYXQoKS5pc0VxdWFsVG8oInRlc3QgZXhjZXB0aW9uIik7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvT2Zmcm9hZDJGaWxlRG93bmxvYWRlclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyL29mZnJvYWQvT2Zmcm9hZDJGaWxlRG93bmxvYWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOWY0MzliCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2Rvd25sb2FkZXIvb2Zmcm9hZC9PZmZyb2FkMkZpbGVEb3dubG9hZGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjg5IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLy8gVE9ETworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLm9mZnJvYWQ7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmU7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0LlNFQ09ORFM7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5Db25uZWN0aXZpdHlIYW5kbGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmRvd25sb2FkZXIuRG93bmxvYWRDb25zdHJhaW50cy5OZXR3b3JrVHlwZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci5Eb3dubG9hZE1ldGFkYXRhOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmRvd25sb2FkZXIuRmxvZ2dlckRvd25sb2FkZXJMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmRvd25sb2FkZXIuT0F1dGhUb2tlblByb3ZpZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLlBsYXRmb3JtVXJsRW5naW5lOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLnRlc3RpbmcuVGVzdFVybEVuZ2luZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZG93bmxvYWRlci50ZXN0aW5nLlRlc3RVcmxFbmdpbmUuVGVzdFVybFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb24uRG93bmxvYWRSZXN1bHRDb2RlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0OworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmludGVncmF0aW9uLmRvd25sb2FkZXIuRG93bmxvYWRNZXRhZGF0YVN0b3JlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWFkU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5Xcml0ZVN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLlRlc3RIdHRwU2VydmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRyYWNpbmcuUHJvcGFnYXRlZEZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JdGVyYWJsZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uaW8uQnl0ZVN0cmVhbXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24ubmV0Lkh0dHBIZWFkZXJzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Bc3luY0Z1bmN0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgY29tLmdvb2dsZS5kZXZ0b29scy5idWlsZC5ydW50aW1lLlJ1bmZpbGVzUGF0aHM7CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLm5ldC5VUkk7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvdW50RG93bkxhdGNoOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IG9yZy5qdW5pdC5BZnRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCisvKioKKyAqIFVuaXQgdGVzdHMgZm9yIHtAbGluaworICogY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5vZmZyb2FkLk9mZnJvYWQyRmlsZURvd25sb2FkZXJ9LgorICovCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgY2xhc3MgT2Zmcm9hZDJGaWxlRG93bmxvYWRlclRlc3QgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUUkFGRklDX1RBRyA9IDEwMDA7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZSBET1dOTE9BRF9FWEVDVVRPUiA9CisgICAgICBFeGVjdXRvcnMubmV3U2NoZWR1bGVkVGhyZWFkUG9vbCgyKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlIENPTlRST0xfRVhFQ1VUT1IgPQorICAgICAgTW9yZUV4ZWN1dG9ycy5saXN0ZW5pbmdEZWNvcmF0b3IoRXhlY3V0b3JzLm5ld0NhY2hlZFRocmVhZFBvb2woKSk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBNQVhfQ09OTkVDVElPTl9XQUlUX1NFQ1MgPSAxMEw7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVhfUExBVEZPUk1fRU5HSU5FX1RJTUVPVVRfTUlMTElTID0gMTAwMDsKKworICAvKiogRW5kcG9pbnQgdGhhdCBjYW4gYmUgcmVnaXN0ZXJlZCB0byBUZXN0SHR0cFNlcnZlciB0byBzZXJ2ZSBhIGZpbGUgdGhhdCBjYW4gYmUgZG93bmxvYWRlZC4gKi8KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfREFUQV9FTkRQT0lOVCA9ICIvdGVzdGZpbGUiOworCisgIC8qKiBQYXRoIHRvIHRoZSB1bmRlcmx5aW5nIHRlc3QgZGF0YSB0aGF0IGlzIHRoZSBzb3VyY2Ugb2Ygd2hhdCBUZXN0SHR0cFNlcnZlciB3aWxsIHNlcnZlLiAqLworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVTVF9EQVRBX1BBVEggPQorICAgICAgUnVuZmlsZXNQYXRocy5yZXNvbHZlKAorICAgICAgICAgICAgICAidGhpcmRfcGFydHkvamF2YV9zcmMvYW5kcm9pZF9saWJzL21vYmlsZWRhdGFkb3dubG9hZC9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGEvZnVsbF9maWxlLnR4dCIpCisgICAgICAgICAgLnRvU3RyaW5nKCk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFBBUlRJQUxfVEVTVF9EQVRBX1BBVEggPQorICAgICAgUnVuZmlsZXNQYXRocy5yZXNvbHZlKAorICAgICAgICAgICAgICAidGhpcmRfcGFydHkvamF2YV9zcmMvYW5kcm9pZF9saWJzL21vYmlsZWRhdGFkb3dubG9hZC9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGEvcGFydGlhbF9maWxlLnR4dCIpCisgICAgICAgICAgLnRvU3RyaW5nKCk7CisKKyAgcHJpdmF0ZSBDb250ZXh0IGNvbnRleHQ7CisKKyAgcHJpdmF0ZSBVcmkuQnVpbGRlciB0ZXN0VXJsUHJlZml4OworICBwcml2YXRlIFRlc3RIdHRwU2VydmVyIHRlc3RIdHRwU2VydmVyOworCisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHJpdmF0ZSBGYWtlQ29ubmVjdGl2aXR5SGFuZGxlciBmYWtlQ29ubmVjdGl2aXR5SGFuZGxlcjsKKyAgcHJpdmF0ZSBGYWtlRG93bmxvYWRNZXRhZGF0YVN0b3JlIGZha2VEb3dubG9hZE1ldGFkYXRhU3RvcmU7CisgIHByaXZhdGUgRmFrZU9BdXRoVG9rZW5Qcm92aWRlciBmYWtlT0F1dGhUb2tlblByb3ZpZGVyOworICBwcml2YXRlIEZha2VUcmFmZmljU3RhdHNUYWdnZXIgZmFrZVRyYWZmaWNTdGF0c1RhZ2dlcjsKKyAgcHJpdmF0ZSBUZXN0VXJsRW5naW5lIHRlc3RVcmxFbmdpbmU7CisgIHByaXZhdGUgRG93bmxvYWRlciBkb3dubG9hZGVyOworCisgIHByaXZhdGUgT2Zmcm9hZDJGaWxlRG93bmxvYWRlciBmaWxlRG93bmxvYWRlcjsKKworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5VXJpIHRtcFVyaSA9IG5ldyBUZW1wb3JhcnlVcmkoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisgICAgZmlsZVN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIC8qIGJhY2tlbmRzID0gKi8gSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgICAgICBBbmRyb2lkRmlsZUJhY2tlbmQuYnVpbGRlcihjb250ZXh0KS5idWlsZCgpLCBuZXcgSmF2YUZpbGVCYWNrZW5kKCkpLAorICAgICAgICAgICAgLyogdHJhbnNmb3JtcyA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIC8qIG1vbml0b3JzID0gKi8gSW1tdXRhYmxlTGlzdC5vZigpKTsKKworICAgIGZha2VEb3dubG9hZE1ldGFkYXRhU3RvcmUgPSBuZXcgRmFrZURvd25sb2FkTWV0YWRhdGFTdG9yZSgpOworCisgICAgZmFrZVRyYWZmaWNTdGF0c1RhZ2dlciA9IG5ldyBGYWtlVHJhZmZpY1N0YXRzVGFnZ2VyKCk7CisKKyAgICBQbGF0Zm9ybVVybEVuZ2luZSB1cmxFbmdpbmUgPQorICAgICAgICBuZXcgUGxhdGZvcm1VcmxFbmdpbmUoCisgICAgICAgICAgICBDT05UUk9MX0VYRUNVVE9SLAorICAgICAgICAgICAgTUFYX1BMQVRGT1JNX0VOR0lORV9USU1FT1VUX01JTExJUywKKyAgICAgICAgICAgIE1BWF9QTEFURk9STV9FTkdJTkVfVElNRU9VVF9NSUxMSVMsCisgICAgICAgICAgICBmYWtlVHJhZmZpY1N0YXRzVGFnZ2VyKTsKKworICAgIHRlc3RVcmxFbmdpbmUgPSBuZXcgVGVzdFVybEVuZ2luZSh1cmxFbmdpbmUpOworCisgICAgZmFrZUNvbm5lY3Rpdml0eUhhbmRsZXIgPSBuZXcgRmFrZUNvbm5lY3Rpdml0eUhhbmRsZXIoKTsKKworICAgIGRvd25sb2FkZXIgPQorICAgICAgICBuZXcgRG93bmxvYWRlci5CdWlsZGVyKCkKKyAgICAgICAgICAgIC53aXRoSU9FeGVjdXRvcihDT05UUk9MX0VYRUNVVE9SKQorICAgICAgICAgICAgLndpdGhDb25uZWN0aXZpdHlIYW5kbGVyKGZha2VDb25uZWN0aXZpdHlIYW5kbGVyKQorICAgICAgICAgICAgLndpdGhNYXhDb25jdXJyZW50RG93bmxvYWRzKDIpCisgICAgICAgICAgICAud2l0aExvZ2dlcihuZXcgRmxvZ2dlckRvd25sb2FkZXJMb2dnZXIoKSkKKyAgICAgICAgICAgIC5hZGRVcmxFbmdpbmUoSW1tdXRhYmxlTGlzdC5vZigiaHR0cCIsICJodHRwcyIpLCB0ZXN0VXJsRW5naW5lKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBmYWtlT0F1dGhUb2tlblByb3ZpZGVyID0gbmV3IEZha2VPQXV0aFRva2VuUHJvdmlkZXIoKTsKKworICAgIGZpbGVEb3dubG9hZGVyID0KKyAgICAgICAgbmV3IE9mZnJvYWQyRmlsZURvd25sb2FkZXIoCisgICAgICAgICAgICBkb3dubG9hZGVyLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBET1dOTE9BRF9FWEVDVVRPUiwKKyAgICAgICAgICAgIGZha2VPQXV0aFRva2VuUHJvdmlkZXIsCisgICAgICAgICAgICBmYWtlRG93bmxvYWRNZXRhZGF0YVN0b3JlLAorICAgICAgICAgICAgRXhjZXB0aW9uSGFuZGxlci53aXRoRGVmYXVsdEhhbmRsaW5nKCksCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSk7CisKKyAgICB0ZXN0SHR0cFNlcnZlciA9IG5ldyBUZXN0SHR0cFNlcnZlcigpOworICAgIHRlc3RVcmxQcmVmaXggPSB0ZXN0SHR0cFNlcnZlci5zdGFydFNlcnZlcigpOworICB9CisKKyAgQEFmdGVyCisgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgeworICAgIHRlc3RIdHRwU2VydmVyLnN0b3BTZXJ2ZXIoKTsKKyAgICBmYWtlQ29ubmVjdGl2aXR5SGFuZGxlci5yZXNldCgpOworICAgIGZha2VEb3dubG9hZE1ldGFkYXRhU3RvcmUucmVzZXQoKTsKKyAgICBmYWtlT0F1dGhUb2tlblByb3ZpZGVyLnJlc2V0KCk7CisgICAgZmFrZVRyYWZmaWNTdGF0c1RhZ2dlci5yZXNldCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFN0YXJ0RG93bmxvYWRpbmdfZG93bmxvYWRDb25kaXRpb25zTnVsbF91c2VzV2lmaU9ubHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgZmlsZVVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBTdHJpbmcgdXJsVG9Eb3dubG9hZCA9IHRlc3RVcmxQcmVmaXgucGF0aChURVNUX0RBVEFfRU5EUE9JTlQpLnRvU3RyaW5nKCk7CisgICAgdGVzdEh0dHBTZXJ2ZXIucmVnaXN0ZXJUZXh0RmlsZShURVNUX0RBVEFfRU5EUE9JTlQsIFRFU1RfREFUQV9QQVRIKTsKKworICAgIC8vIFNldHVwIGN1c3RvbSBoYW5kbGVyIHRvIGVuc3VyZSBleHBlY3RlZCBjb25zdHJhaW50cy4KKyAgICBmYWtlQ29ubmVjdGl2aXR5SGFuZGxlci5jdXN0b21IYW5kbGVyID0KKyAgICAgICAgY29uc3RyYWludHMgLT4geworICAgICAgICAgIGFzc2VydFRoYXQoY29uc3RyYWludHMucmVxdWlyZVVubWV0ZXJlZE5ldHdvcmsoKSkuaXNUcnVlKCk7CisgICAgICAgICAgYXNzZXJ0VGhhdChjb25zdHJhaW50cy5yZXF1aXJlZE5ldHdvcmtUeXBlcygpKQorICAgICAgICAgICAgICAuY29udGFpbnNFeGFjdGx5KE5ldHdvcmtUeXBlLldJRkksIE5ldHdvcmtUeXBlLkVUSEVSTkVULCBOZXR3b3JrVHlwZS5CTFVFVE9PVEgpOworCisgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgfTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBmaWxlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKAorICAgICAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRGaWxlVXJpKGZpbGVVcmkpCisgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQodXJsVG9Eb3dubG9hZCkKKyAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cygKKyAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZENvbnN0cmFpbnRzCisgICAgICAgICAgICAgICAgICAgICAgICAuTk9ORSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICBkb3dubG9hZEZ1dHVyZS5nZXQoTUFYX0NPTk5FQ1RJT05fV0FJVF9TRUNTLCBTRUNPTkRTKTsKKworICAgIGFzc2VydFRoYXQoZmFrZUNvbm5lY3Rpdml0eUhhbmRsZXIuaW52b2tlZEN1c3RvbUhhbmRsZXIpLmlzVHJ1ZSgpOworCisgICAgLy8gQ2hlY2sgRG93bmxvYWRNZXRhZGF0YVN0b3JlIGNhbGxzCisgICAgYXNzZXJ0VGhhdChmYWtlRG93bmxvYWRNZXRhZGF0YVN0b3JlLnVwc2VydENhbGxzKS5jb250YWluc0tleShmaWxlVXJpKTsKKyAgICBhc3NlcnRUaGF0KGZha2VEb3dubG9hZE1ldGFkYXRhU3RvcmUuZGVsZXRlQ2FsbHMpLmNvbnRhaW5zKGZpbGVVcmkpOworICAgIGFzc2VydFRoYXQoZmFrZURvd25sb2FkTWV0YWRhdGFTdG9yZS5yZWFkKGZpbGVVcmkpLmdldChNQVhfQ09OTkVDVElPTl9XQUlUX1NFQ1MsIFNFQ09ORFMpKQorICAgICAgICAuaXNBYnNlbnQoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RTdGFydERvd25sb2FkaW5nX3dpZmkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgZmlsZVVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBTdHJpbmcgdXJsVG9Eb3dubG9hZCA9IHRlc3RVcmxQcmVmaXgucGF0aChURVNUX0RBVEFfRU5EUE9JTlQpLnRvU3RyaW5nKCk7CisgICAgdGVzdEh0dHBTZXJ2ZXIucmVnaXN0ZXJUZXh0RmlsZShURVNUX0RBVEFfRU5EUE9JTlQsIFRFU1RfREFUQV9QQVRIKTsKKworICAgIC8vIFNldHVwIGN1c3RvbSBoYW5kbGVyIHRvIGVuc3VyZSBleHBlY3RlZCBjb25zdHJhaW50cy4KKyAgICBmYWtlQ29ubmVjdGl2aXR5SGFuZGxlci5jdXN0b21IYW5kbGVyID0KKyAgICAgICAgY29uc3RyYWludHMgLT4geworICAgICAgICAgIGFzc2VydFRoYXQoY29uc3RyYWludHMucmVxdWlyZVVubWV0ZXJlZE5ldHdvcmsoKSkuaXNUcnVlKCk7CisgICAgICAgICAgYXNzZXJ0VGhhdChjb25zdHJhaW50cy5yZXF1aXJlZE5ldHdvcmtUeXBlcygpKQorICAgICAgICAgICAgICAuY29udGFpbnNFeGFjdGx5KE5ldHdvcmtUeXBlLldJRkksIE5ldHdvcmtUeXBlLkVUSEVSTkVULCBOZXR3b3JrVHlwZS5CTFVFVE9PVEgpOworCisgICAgICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgfTsKKworICAgIC8vIFNldHVwIGN1c3RvbSBoYW5kbGVyIHRvIGFkZCBhdXRob3JpemF0aW9uIHRva2VuCisgICAgZmFrZU9BdXRoVG9rZW5Qcm92aWRlci5jdXN0b21IYW5kbGVyID0gdW51c2VkIC0+IGltbWVkaWF0ZUZ1dHVyZSgiVEVTVF9UT0tFTiIpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIGZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoCisgICAgICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmkoZmlsZVVyaSkKKyAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCh1cmxUb0Rvd25sb2FkKQorICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKAorICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5ORVRXT1JLX1VOTUVURVJFRCkKKyAgICAgICAgICAgICAgICAuc2V0VHJhZmZpY1RhZyhUUkFGRklDX1RBRykKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICBkb3dubG9hZEZ1dHVyZS5nZXQoTUFYX0NPTk5FQ1RJT05fV0FJVF9TRUNTLCBTRUNPTkRTKTsKKworICAgIGFzc2VydFRoYXQodGVzdFVybEVuZ2luZS5zdG9yZWRSZXF1ZXN0cygpKS5oYXNTaXplKDEpOworICAgIFRlc3RVcmxSZXF1ZXN0IHJlcXVlc3QgPSB0ZXN0VXJsRW5naW5lLnN0b3JlZFJlcXVlc3RzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQocmVxdWVzdC50cmFmZmljVGFnKCkpLmlzRXF1YWxUbyhUUkFGRklDX1RBRyk7CisgICAgYXNzZXJ0VGhhdChyZXF1ZXN0LmhlYWRlcnMoKSkuY29udGFpbnNLZXkoSHR0cEhlYWRlcnMuQVVUSE9SSVpBVElPTik7CisgICAgYXNzZXJ0VGhhdChyZXF1ZXN0LmhlYWRlcnMoKSkKKyAgICAgICAgLnZhbHVlc0ZvcktleShIdHRwSGVhZGVycy5BVVRIT1JJWkFUSU9OKQorICAgICAgICAuY29udGFpbnMoIkJlYXJlciBURVNUX1RPS0VOIik7CisKKyAgICBhc3NlcnRUaGF0KGZha2VDb25uZWN0aXZpdHlIYW5kbGVyLmludm9rZWRDdXN0b21IYW5kbGVyKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGZha2VPQXV0aFRva2VuUHJvdmlkZXIuaW52b2tlZEN1c3RvbUhhbmRsZXIpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoZmFrZVRyYWZmaWNTdGF0c1RhZ2dlci5zdG9yZWRUcmFmZmljVGFncykuY29udGFpbnMoVFJBRkZJQ19UQUcpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFN0YXJ0RG93bmxvYWRpbmdfd2lmaV9ub3RTZXR0aW5nVHJhZmZpY1RhZygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSBmaWxlVXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIFN0cmluZyB1cmxUb0Rvd25sb2FkID0gdGVzdFVybFByZWZpeC5wYXRoKFRFU1RfREFUQV9FTkRQT0lOVCkudG9TdHJpbmcoKTsKKyAgICB0ZXN0SHR0cFNlcnZlci5yZWdpc3RlclRleHRGaWxlKFRFU1RfREFUQV9FTkRQT0lOVCwgVEVTVF9EQVRBX1BBVEgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIGZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoCisgICAgICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmkoZmlsZVVyaSkKKyAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCh1cmxUb0Rvd25sb2FkKQorICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKAorICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5ORVRXT1JLX1VOTUVURVJFRCkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICBkb3dubG9hZEZ1dHVyZS5nZXQoTUFYX0NPTk5FQ1RJT05fV0FJVF9TRUNTLCBTRUNPTkRTKTsKKworICAgIGFzc2VydFRoYXQodGVzdFVybEVuZ2luZS5zdG9yZWRSZXF1ZXN0cygpKS5oYXNTaXplKDEpOworICAgIFRlc3RVcmxSZXF1ZXN0IHJlcXVlc3QgPSB0ZXN0VXJsRW5naW5lLnN0b3JlZFJlcXVlc3RzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQocmVxdWVzdC50cmFmZmljVGFnKCkpLmlzRXF1YWxUbygwKTsKKworICAgIGFzc2VydFRoYXQoZmFrZVRyYWZmaWNTdGF0c1RhZ2dlci5zdG9yZWRUcmFmZmljVGFncykuZG9lc05vdENvbnRhaW4oVFJBRkZJQ19UQUcpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFN0YXJ0RG93bmxvYWRpbmdfZXh0cmFIdHRwSGVhZGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSBmaWxlVXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIFN0cmluZyB1cmxUb0Rvd25sb2FkID0gdGVzdFVybFByZWZpeC5wYXRoKFRFU1RfREFUQV9FTkRQT0lOVCkudG9TdHJpbmcoKTsKKyAgICB0ZXN0SHR0cFNlcnZlci5yZWdpc3RlclRleHRGaWxlKFRFU1RfREFUQV9FTkRQT0lOVCwgVEVTVF9EQVRBX1BBVEgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIGZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoCisgICAgICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmkoZmlsZVVyaSkKKyAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCh1cmxUb0Rvd25sb2FkKQorICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKAorICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5ORVRXT1JLX1VOTUVURVJFRCkKKyAgICAgICAgICAgICAgICAuc2V0VHJhZmZpY1RhZyhUUkFGRklDX1RBRykKKyAgICAgICAgICAgICAgICAuc2V0RXh0cmFIdHRwSGVhZGVycygKKyAgICAgICAgICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgICAgICAgICAgICAgIFBhaXIuY3JlYXRlKCJ1c2VyLWFnZW50IiwgIm1kZC1kb3dubG9hZGVyIiksCisgICAgICAgICAgICAgICAgICAgICAgICBQYWlyLmNyZWF0ZSgib3RoZXItaGVhZGVyIiwgImhlYWRlci12YWx1ZSIpKSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICBkb3dubG9hZEZ1dHVyZS5nZXQoTUFYX0NPTk5FQ1RJT05fV0FJVF9TRUNTLCBTRUNPTkRTKTsKKworICAgIGFzc2VydFRoYXQodGVzdFVybEVuZ2luZS5zdG9yZWRSZXF1ZXN0cygpKS5oYXNTaXplKDEpOworICAgIFRlc3RVcmxSZXF1ZXN0IHJlcXVlc3QgPSB0ZXN0VXJsRW5naW5lLnN0b3JlZFJlcXVlc3RzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQocmVxdWVzdC5oZWFkZXJzKCkua2V5U2V0KCkpLmNvbnRhaW5zRXhhY3RseSgidXNlci1hZ2VudCIsICJvdGhlci1oZWFkZXIiKTsKKyAgICBhc3NlcnRUaGF0KHJlcXVlc3QuaGVhZGVycygpKS52YWx1ZXNGb3JLZXkoInVzZXItYWdlbnQiKS5jb250YWlucygibWRkLWRvd25sb2FkZXIiKTsKKyAgICBhc3NlcnRUaGF0KHJlcXVlc3QuaGVhZGVycygpKS52YWx1ZXNGb3JLZXkoIm90aGVyLWhlYWRlciIpLmNvbnRhaW5zKCJoZWFkZXItdmFsdWUiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RTdGFydERvd25sb2FkaW5nX2NlbGx1bGFyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGZpbGVVcmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgU3RyaW5nIHVybFRvRG93bmxvYWQgPSB0ZXN0VXJsUHJlZml4LnBhdGgoVEVTVF9EQVRBX0VORFBPSU5UKS50b1N0cmluZygpOworICAgIHRlc3RIdHRwU2VydmVyLnJlZ2lzdGVyVGV4dEZpbGUoVEVTVF9EQVRBX0VORFBPSU5ULCBURVNUX0RBVEFfUEFUSCk7CisKKyAgICAvLyBTZXR1cCBjdXN0b20gaGFuZGxlciB0byBlbnN1cmUgZXhwZWN0ZWQgY29uc3RyYWludHMuCisgICAgZmFrZUNvbm5lY3Rpdml0eUhhbmRsZXIuY3VzdG9tSGFuZGxlciA9CisgICAgICAgIGNvbnN0cmFpbnRzIC0+IHsKKyAgICAgICAgICBhc3NlcnRUaGF0KGNvbnN0cmFpbnRzKS5pc0VxdWFsVG8oRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCk7CisKKyAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICB9OworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIGZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoCisgICAgICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmkoZmlsZVVyaSkKKyAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCh1cmxUb0Rvd25sb2FkKQorICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKAorICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5ORVRXT1JLX0NPTk5FQ1RFRCkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICBkb3dubG9hZEZ1dHVyZS5nZXQoTUFYX0NPTk5FQ1RJT05fV0FJVF9TRUNTLCBTRUNPTkRTKTsKKworICAgIGFzc2VydFRoYXQoZmFrZUNvbm5lY3Rpdml0eUhhbmRsZXIuaW52b2tlZEN1c3RvbUhhbmRsZXIpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFN0YXJ0RG93bmxvYWRpbmdfZmFpbGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGZpbGVVcmkgPSB0bXBVcmkubmV3VXJpKCk7CisKKyAgICAvLyBTaW11bGF0ZSBmYWlsdXJlIGR1ZSB0byBiYWQgdXJsOworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBmaWxlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKAorICAgICAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRGaWxlVXJpKGZpbGVVcmkpCisgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImh0dHBzOi8vQkFEVVJMIikKKyAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cygKKyAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZENvbnN0cmFpbnRzCisgICAgICAgICAgICAgICAgICAgICAgICAuTkVUV09SS19VTk1FVEVSRUQpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4Y2VwdGlvbiA9IGFzc2VydFRocm93cyhFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsIGRvd25sb2FkRnV0dXJlOjpnZXQpOworICAgIGFzc2VydFRoYXQoZXhjZXB0aW9uKS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworCisgICAgRG93bmxvYWRFeGNlcHRpb24gZGV4ID0gKERvd25sb2FkRXhjZXB0aW9uKSBleGNlcHRpb24uZ2V0Q2F1c2UoKTsKKyAgICBhc3NlcnRUaGF0KGRleC5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkuaXNFcXVhbFRvKERvd25sb2FkUmVzdWx0Q29kZS5VTktOT1dOX0VSUk9SKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RTdGFydERvd25sb2FkaW5nX3doZW5QYXJ0aWFsRmlsZV93aGVuTWV0YWRhdGFOb3RQcmVzZW50X2dldHNGdWxsRmlsZSgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgZmlsZVVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBTdHJpbmcgdXJsVG9Eb3dubG9hZCA9IHRlc3RVcmxQcmVmaXgucGF0aChURVNUX0RBVEFfRU5EUE9JTlQpLnRvU3RyaW5nKCk7CisgICAgdGVzdEh0dHBTZXJ2ZXIucmVnaXN0ZXJUZXh0RmlsZShURVNUX0RBVEFfRU5EUE9JTlQsIFRFU1RfREFUQV9QQVRIKTsKKworICAgIC8vIFdyaXRlIHBhcnRpYWwgY29udGVudCB0byBmaWxlIGJ1dCBkbyBfbm90XyB3cml0ZSBwYXJ0aWFsIG1ldGFkYXRhLgorICAgIHRyeSAoSW5wdXRTdHJlYW0gaW5TdHJlYW0gPQorICAgICAgICAgICAgZmlsZVN0b3JhZ2Uub3BlbigKKyAgICAgICAgICAgICAgICBVcmkucGFyc2UoImZpbGU6Ly8iICsgUEFSVElBTF9URVNUX0RBVEFfUEFUSCksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpOworICAgICAgICBPdXRwdXRTdHJlYW0gb3V0U3RyZWFtID0gZmlsZVN0b3JhZ2Uub3BlbihmaWxlVXJpLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIEJ5dGVTdHJlYW1zLmNvcHkoaW5TdHJlYW0sIG91dFN0cmVhbSk7CisgICAgfQorCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIGZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoCisgICAgICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmkoZmlsZVVyaSkKKyAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCh1cmxUb0Rvd25sb2FkKQorICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKAorICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHMKKyAgICAgICAgICAgICAgICAgICAgICAgIC5OT05FKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKworICAgIGRvd25sb2FkRnV0dXJlLmdldChNQVhfQ09OTkVDVElPTl9XQUlUX1NFQ1MsIFNFQ09ORFMpOworCisgICAgLy8gQ2hlY2sgdGhhdCBmdWxsIGZpbGUgaXMgcmVxdWVzdGVkIChubyBIVFRQIHJhbmdlIGhlYWRlcnMpCisgICAgYXNzZXJ0VGhhdCh0ZXN0VXJsRW5naW5lLnN0b3JlZFJlcXVlc3RzKCkuZ2V0KDApLmhlYWRlcnMoKSkKKyAgICAgICAgLmRvZXNOb3RDb250YWluS2V5KEh0dHBIZWFkZXJzLlJBTkdFKTsKKyAgICBhc3NlcnRUaGF0KHRlc3RVcmxFbmdpbmUuc3RvcmVkUmVxdWVzdHMoKS5nZXQoMCkuaGVhZGVycygpKQorICAgICAgICAuZG9lc05vdENvbnRhaW5LZXkoSHR0cEhlYWRlcnMuSUZfUkFOR0UpOworCisgICAgLy8gQ2hlY2sgRG93bmxvYWRNZXRhZGF0YVN0b3JlIGNhbGxzCisgICAgYXNzZXJ0VGhhdChmYWtlRG93bmxvYWRNZXRhZGF0YVN0b3JlLnJlYWRDYWxscykuY29udGFpbnMoZmlsZVVyaSk7CisgICAgYXNzZXJ0VGhhdChmYWtlRG93bmxvYWRNZXRhZGF0YVN0b3JlLnVwc2VydENhbGxzKS5jb250YWluc0tleShmaWxlVXJpKTsKKyAgICBhc3NlcnRUaGF0KGZha2VEb3dubG9hZE1ldGFkYXRhU3RvcmUuZGVsZXRlQ2FsbHMpLmNvbnRhaW5zKGZpbGVVcmkpOworICAgIGFzc2VydFRoYXQoZmFrZURvd25sb2FkTWV0YWRhdGFTdG9yZS5yZWFkKGZpbGVVcmkpLmdldChNQVhfQ09OTkVDVElPTl9XQUlUX1NFQ1MsIFNFQ09ORFMpKQorICAgICAgICAuaXNBYnNlbnQoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RTdGFydERvd25sb2FkaW5nX3doZW5QYXJ0aWFsRmlsZV93aGVuTWV0YWRhdGFQcmVzZW50X3JldXNlc1BhcnRpYWxGaWxlKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSBmaWxlVXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIFN0cmluZyB1cmxUb0Rvd25sb2FkID0gdGVzdFVybFByZWZpeC5wYXRoKFRFU1RfREFUQV9FTkRQT0lOVCkudG9TdHJpbmcoKTsKKyAgICB0ZXN0SHR0cFNlcnZlci5yZWdpc3RlclRleHRGaWxlKFRFU1RfREFUQV9FTkRQT0lOVCwgVEVTVF9EQVRBX1BBVEgpOworCisgICAgLy8gV3JpdGUgcGFydGlhbCBjb250ZW50IHRvIGZpbGUuCisgICAgdHJ5IChJbnB1dFN0cmVhbSBpblN0cmVhbSA9CisgICAgICAgICAgICBmaWxlU3RvcmFnZS5vcGVuKAorICAgICAgICAgICAgICAgIFVyaS5wYXJzZSgiZmlsZTovLyIgKyBQQVJUSUFMX1RFU1RfREFUQV9QQVRIKSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSk7CisgICAgICAgIE91dHB1dFN0cmVhbSBvdXRTdHJlYW0gPSBmaWxlU3RvcmFnZS5vcGVuKGZpbGVVcmksIFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgQnl0ZVN0cmVhbXMuY29weShpblN0cmVhbSwgb3V0U3RyZWFtKTsKKyAgICB9CisKKyAgICAvLyBXcml0ZSBleGlzdGluZyBtZXRhZGF0YSB0byBmaWxlLgorICAgIGZha2VEb3dubG9hZE1ldGFkYXRhU3RvcmUKKyAgICAgICAgLnVwc2VydChmaWxlVXJpLCBEb3dubG9hZE1ldGFkYXRhLmNyZWF0ZSgidGVzdCIsIDApKQorICAgICAgICAuZ2V0KE1BWF9DT05ORUNUSU9OX1dBSVRfU0VDUywgU0VDT05EUyk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgZmlsZURvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIERvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0RmlsZVVyaShmaWxlVXJpKQorICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKHVybFRvRG93bmxvYWQpCisgICAgICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoCisgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRDb25zdHJhaW50cworICAgICAgICAgICAgICAgICAgICAgICAgLk5PTkUpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworCisgICAgZG93bmxvYWRGdXR1cmUuZ2V0KE1BWF9DT05ORUNUSU9OX1dBSVRfU0VDUywgU0VDT05EUyk7CisKKyAgICAvLyBDaGVjayB0aGF0IGZ1bGwgZmlsZSBpcyByZXF1ZXN0ZWQgKG5vIEhUVFAgcmFuZ2UgaGVhZGVycykKKyAgICBhc3NlcnRUaGF0KHRlc3RVcmxFbmdpbmUuc3RvcmVkUmVxdWVzdHMoKS5nZXQoMCkuaGVhZGVycygpKS5jb250YWluc0tleShIdHRwSGVhZGVycy5SQU5HRSk7CisgICAgYXNzZXJ0VGhhdCh0ZXN0VXJsRW5naW5lLnN0b3JlZFJlcXVlc3RzKCkuZ2V0KDApLmhlYWRlcnMoKSkuY29udGFpbnNLZXkoSHR0cEhlYWRlcnMuSUZfUkFOR0UpOworCisgICAgLy8gQ2hlY2sgRG93bmxvYWRNZXRhZGF0YVN0b3JlIGNhbGxzCisgICAgYXNzZXJ0VGhhdChmYWtlRG93bmxvYWRNZXRhZGF0YVN0b3JlLnJlYWRDYWxscykuY29udGFpbnMoZmlsZVVyaSk7CisgICAgYXNzZXJ0VGhhdChmYWtlRG93bmxvYWRNZXRhZGF0YVN0b3JlLnVwc2VydENhbGxzKS5jb250YWluc0tleShmaWxlVXJpKTsKKyAgICBhc3NlcnRUaGF0KGZha2VEb3dubG9hZE1ldGFkYXRhU3RvcmUuZGVsZXRlQ2FsbHMpLmNvbnRhaW5zKGZpbGVVcmkpOworICAgIGFzc2VydFRoYXQoZmFrZURvd25sb2FkTWV0YWRhdGFTdG9yZS5yZWFkKGZpbGVVcmkpLmdldChNQVhfQ09OTkVDVElPTl9XQUlUX1NFQ1MsIFNFQ09ORFMpKQorICAgICAgICAuaXNBYnNlbnQoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RDYW5jZWxEb3dubG9hZF9ub3RGaW5pc2hlZEZ1dHVyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIEJ1aWxkIGEgZmlsZSB1cmkgc28gaXQncyBub3QgY3JlYXRlZCBieSBUZW1wb3JhcnlVcmkgLS0gd2UgY2FuIHRoZW4gbWFrZSBhc3NlcnRpb25zIG9uIHRoZQorICAgIC8vIGV4aXN0ZW5jZSBvZiB0aGUgZmlsZS4KKyAgICBVcmkgZmlsZVVyaSA9IHRtcFVyaS5uZXdVcmlCdWlsZGVyKCkuYXBwZW5kUGF0aCgidW5pcXVlIikuYnVpbGQoKTsKKworICAgIFN0cmluZyB1cmxUb0Rvd25sb2FkID0gdGVzdFVybFByZWZpeC5wYXRoKFRFU1RfREFUQV9FTkRQT0lOVCkudG9TdHJpbmcoKTsKKyAgICB0ZXN0SHR0cFNlcnZlci5yZWdpc3RlclRleHRGaWxlKFRFU1RfREFUQV9FTkRQT0lOVCwgVEVTVF9EQVRBX1BBVEgpOworCisgICAgLy8gQmxvY2sgZG93bmxvYWQgdXNpbmcgY29ubmVjdGl2aXR5IGNoZWNrCisgICAgQ291bnREb3duTGF0Y2ggYmxvY2tpbmdMYXRjaCA9IG5ldyBDb3VudERvd25MYXRjaCgxKTsKKyAgICBmYWtlQ29ubmVjdGl2aXR5SGFuZGxlci5jdXN0b21IYW5kbGVyID0KKyAgICAgICAgdW51c2VkIC0+CisgICAgICAgICAgICBQcm9wYWdhdGVkRnV0dXJlcy5zdWJtaXRBc3luYygKKyAgICAgICAgICAgICAgICAoKSAtPiB7CisgICAgICAgICAgICAgICAgICBibG9ja2luZ0xhdGNoLmF3YWl0KCk7CisgICAgICAgICAgICAgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgQ09OVFJPTF9FWEVDVVRPUik7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgZmlsZURvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIERvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0RmlsZVVyaShmaWxlVXJpKQorICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKHVybFRvRG93bmxvYWQpCisgICAgICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoCisgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRDb25zdHJhaW50cworICAgICAgICAgICAgICAgICAgICAgICAgLk5FVFdPUktfVU5NRVRFUkVEKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKworICAgIGFzc2VydFRoYXQoZG93bmxvYWRGdXR1cmUuaXNEb25lKCkpLmlzRmFsc2UoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhmaWxlVXJpKSkuaXNGYWxzZSgpOworCisgICAgZG93bmxvYWRGdXR1cmUuY2FuY2VsKHRydWUpOworCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZEZ1dHVyZS5pc0NhbmNlbGxlZCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhmaWxlVXJpKSkuaXNGYWxzZSgpOworCisgICAgLy8gY291bnQgZG93biBsYXRjaCB0byBjbGVhbiB1cCB0ZXN0LgorICAgIGJsb2NraW5nTGF0Y2guY291bnREb3duKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0Q2FuY2VsRG93bmxvYWRfb25BbHJlYWR5U3VjY2VlZGVkRnV0dXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQnVpbGQgYSBmaWxlIHVyaSBzbyBpdCdzIG5vdCBjcmVhdGVkIGJ5IFRlbXBvcmFyeVVyaSAtLSB3ZSBjYW4gdGhlbiBtYWtlIGFzc2VydGlvbnMgb24gdGhlCisgICAgLy8gZXhpc3RlbmNlIG9mIHRoZSBmaWxlLgorICAgIFVyaSBmaWxlVXJpID0gdG1wVXJpLmdldFJvb3RVcmlCdWlsZGVyKCkuYXBwZW5kUGF0aCgidW5pcXVlIikuYnVpbGQoKTsKKyAgICBTdHJpbmcgdXJsVG9Eb3dubG9hZCA9IHRlc3RVcmxQcmVmaXgucGF0aChURVNUX0RBVEFfRU5EUE9JTlQpLnRvU3RyaW5nKCk7CisgICAgdGVzdEh0dHBTZXJ2ZXIucmVnaXN0ZXJUZXh0RmlsZShURVNUX0RBVEFfRU5EUE9JTlQsIFRFU1RfREFUQV9QQVRIKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBmaWxlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKAorICAgICAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRGaWxlVXJpKGZpbGVVcmkpCisgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQodXJsVG9Eb3dubG9hZCkKKyAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cygKKyAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZENvbnN0cmFpbnRzCisgICAgICAgICAgICAgICAgICAgICAgICAuTkVUV09SS19VTk1FVEVSRUQpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworCisgICAgZG93bmxvYWRGdXR1cmUuZ2V0KE1BWF9DT05ORUNUSU9OX1dBSVRfU0VDUywgU0VDT05EUyk7CisKKyAgICAvLyBBc3NlcnQgdGhhdCBvbiBkZXZpY2UgZmlsZSBpcyBjcmVhdGVkIGFuZCByZW1haW5zIGV2ZW4gYWZ0ZXIgY2FuY2VsLgorICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKGZpbGVVcmkpKS5pc1RydWUoKTsKKworICAgIGRvd25sb2FkRnV0dXJlLmNhbmNlbCh0cnVlKTsKKworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKGZpbGVVcmkpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RDYW5jZWxEb3dubG9hZF9vbkFscmVhZHlGYWlsZWRGdXR1cmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBCdWlsZCBhIGZpbGUgdXJpIHNvIGl0J3Mgbm90IGNyZWF0ZWQgYnkgVGVtcG9yYXJ5VXJpIC0tIHdlIGNhbiB0aGVuIG1ha2UgYXNzZXJ0aW9ucyBvbiB0aGUKKyAgICAvLyBleGlzdGVuY2Ugb2YgdGhlIGZpbGUuCisgICAgVXJpIGZpbGVVcmkgPSB0bXBVcmkuZ2V0Um9vdFVyaUJ1aWxkZXIoKS5hcHBlbmRQYXRoKCJ1bmlxdWUiKS5idWlsZCgpOworCisgICAgLy8gU2ltdWxhdGUgZmFpbHVyZSBkdWUgdG8gYmFkIHVybDsKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgZmlsZURvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIERvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0RmlsZVVyaShmaWxlVXJpKQorICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJodHRwczovL0JBRFVSTCIpCisgICAgICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoCisgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRDb25zdHJhaW50cworICAgICAgICAgICAgICAgICAgICAgICAgLk5FVFdPUktfVU5NRVRFUkVEKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKworICAgIEV4Y2VwdGlvbiB1bnVzZWQgPSBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCBkb3dubG9hZEZ1dHVyZTo6Z2V0KTsKKworICAgIC8vIEFzc2VydCB0aGF0IG9uIGRldmljZSBmaWxlIGlzIG5vdCBjcmVhdGVkIGFuZCBkb2Vzbid0IGdldCBjcmVhdGVkIGFmdGVyIGNhbmNlbC4KKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhmaWxlVXJpKSkuaXNGYWxzZSgpOworCisgICAgZG93bmxvYWRGdXR1cmUuY2FuY2VsKHRydWUpOworCisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMoZmlsZVVyaSkpLmlzRmFsc2UoKTsKKyAgfQorCisgIC8qKiBDdXN0b20ge0BsaW5rIENvbm5lY3Rpdml0eUhhbmRsZXJ9IHRoYXQgYWxsb3dzIGN1c3RvbSBsb2dpYyB0byBiZSB1c2VkIGZvciBlYWNoIHRlc3QuICovCisgIHN0YXRpYyBmaW5hbCBjbGFzcyBGYWtlQ29ubmVjdGl2aXR5SGFuZGxlciBpbXBsZW1lbnRzIENvbm5lY3Rpdml0eUhhbmRsZXIgeworICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFzeW5jRnVuY3Rpb248RG93bmxvYWRDb25zdHJhaW50cywgVm9pZD4gREVGQVVMVF9IQU5ETEVSID0KKyAgICAgICAgdW51c2VkIC0+IGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKworICAgIHByaXZhdGUgQXN5bmNGdW5jdGlvbjxEb3dubG9hZENvbnN0cmFpbnRzLCBWb2lkPiBjdXN0b21IYW5kbGVyID0gREVGQVVMVF9IQU5ETEVSOworCisgICAgcHJpdmF0ZSBib29sZWFuIGludm9rZWRDdXN0b21IYW5kbGVyID0gZmFsc2U7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBjaGVja0Nvbm5lY3Rpdml0eShEb3dubG9hZENvbnN0cmFpbnRzIGNvbnN0cmFpbnRzKSB7CisgICAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHJldHVybkZ1dHVyZTsKKyAgICAgIHRyeSB7CisgICAgICAgIHJldHVybkZ1dHVyZSA9IGN1c3RvbUhhbmRsZXIuYXBwbHkoY29uc3RyYWludHMpOworICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgcmV0dXJuRnV0dXJlID0gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGUpOworICAgICAgfQorCisgICAgICBpbnZva2VkQ3VzdG9tSGFuZGxlciA9IHRydWU7CisgICAgICByZXR1cm4gcmV0dXJuRnV0dXJlOworICAgIH0KKworICAgIHB1YmxpYyBib29sZWFuIGludm9rZWRDdXN0b21IYW5kbGVyKCkgeworICAgICAgcmV0dXJuIGludm9rZWRDdXN0b21IYW5kbGVyOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0IGlubmVyIHN0YXRlIHRvIGluaXRpYWwgdmFsdWVzLgorICAgICAqCisgICAgICogPHA+VGhpcyBwcmV2ZW50cyBmYWlsdXJlcyBjYXVzZWQgYnkgY3Jvc3MgdGVzdCBwb2xsdXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgICBjdXN0b21IYW5kbGVyID0gREVGQVVMVF9IQU5ETEVSOworICAgICAgaW52b2tlZEN1c3RvbUhhbmRsZXIgPSBmYWxzZTsKKyAgICB9CisgIH0KKworICAvKiogQ3VzdG9tIHtAbGluayBPQXV0aFRva2VuUHJvdmlkZXJ9IHRoYXQgYWxsb3dzIGN1c3RvbSBsb2dpYyBmb3IgZWFjaCB0ZXN0LiAqLworICBzdGF0aWMgZmluYWwgY2xhc3MgRmFrZU9BdXRoVG9rZW5Qcm92aWRlciBpbXBsZW1lbnRzIE9BdXRoVG9rZW5Qcm92aWRlciB7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQXN5bmNGdW5jdGlvbjxVUkksIFN0cmluZz4gREVGQVVMVF9IQU5ETEVSID0KKyAgICAgICAgdW51c2VkIC0+IGltbWVkaWF0ZUZ1dHVyZShudWxsKTsKKworICAgIHByaXZhdGUgQXN5bmNGdW5jdGlvbjxVUkksIFN0cmluZz4gY3VzdG9tSGFuZGxlciA9IERFRkFVTFRfSEFORExFUjsKKworICAgIHByaXZhdGUgYm9vbGVhbiBpbnZva2VkQ3VzdG9tSGFuZGxlciA9IGZhbHNlOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8U3RyaW5nPiBwcm92aWRlT0F1dGhUb2tlbihVUkkgdXJpKSB7CisgICAgICBMaXN0ZW5hYmxlRnV0dXJlPFN0cmluZz4gcmV0dXJuRnV0dXJlOworICAgICAgdHJ5IHsKKyAgICAgICAgcmV0dXJuRnV0dXJlID0gY3VzdG9tSGFuZGxlci5hcHBseSh1cmkpOworICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgcmV0dXJuRnV0dXJlID0gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGUpOworICAgICAgfQorCisgICAgICBpbnZva2VkQ3VzdG9tSGFuZGxlciA9IHRydWU7CisgICAgICByZXR1cm4gcmV0dXJuRnV0dXJlOworICAgIH0KKworICAgIC8qKgorICAgICAqIFJlc2V0IGlubmVyIHN0YXRlIHRvIGluaXRpYWwgdmFsdWVzLgorICAgICAqCisgICAgICogPHA+VGhpcyBwcmV2ZW50cyBmYWlsdXJlcyBjYXVzZWQgYnkgY3Jvc3MgdGVzdCBwb2xsdXRpb24uCisgICAgICovCisgICAgcHVibGljIHZvaWQgcmVzZXQoKSB7CisgICAgICBjdXN0b21IYW5kbGVyID0gREVGQVVMVF9IQU5ETEVSOworICAgICAgaW52b2tlZEN1c3RvbUhhbmRsZXIgPSBmYWxzZTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGYWtlVHJhZmZpY1N0YXRzVGFnZ2VyCisgICAgICBpbXBsZW1lbnRzIFBsYXRmb3JtVXJsRW5naW5lLlRyYWZmaWNTdGF0c1RhZ2dlciB7CisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PEludGVnZXI+IHN0b3JlZFRyYWZmaWNUYWdzID0gbmV3IEFycmF5TGlzdDw+KCk7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgaW50IGdldEFuZFNldFRocmVhZFN0YXRzVGFnKGludCB0YWcpIHsKKyAgICAgIGludCBwcmV2VGFnID0gc3RvcmVkVHJhZmZpY1RhZ3MuaXNFbXB0eSgpID8gMCA6IEl0ZXJhYmxlcy5nZXRMYXN0KHN0b3JlZFRyYWZmaWNUYWdzKTsKKyAgICAgIHN0b3JlZFRyYWZmaWNUYWdzLmFkZCh0YWcpOworICAgICAgcmV0dXJuIHByZXZUYWc7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcmVzdG9yZVRocmVhZFN0YXRzVGFnKGludCB0YWcpIHsKKyAgICAgIHN0b3JlZFRyYWZmaWNUYWdzLmFkZCh0YWcpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIHJlc2V0KCkgeworICAgICAgc3RvcmVkVHJhZmZpY1RhZ3MuY2xlYXIoKTsKKyAgICB9CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGYWtlRG93bmxvYWRNZXRhZGF0YVN0b3JlIGltcGxlbWVudHMgRG93bmxvYWRNZXRhZGF0YVN0b3JlIHsKKworICAgIC8vIEJhY2tpbmcgc3RvcmFnZSBzdHJ1Y3R1cmUgZm9yIG1ldGFkYXRhLgorICAgIHByaXZhdGUgZmluYWwgTWFwPFVyaSwgRG93bmxvYWRNZXRhZGF0YT4gc3RvcmVkTWV0YWRhdGEgPSBuZXcgSGFzaE1hcDw+KCk7CisKKyAgICAvLyBUcmFja2luZyBvZiB3aGF0IGNhbGxzIGFyZSBtYWRlIG9uIHRoaXMgZmFrZS4KKyAgICBmaW5hbCBMaXN0PFVyaT4gcmVhZENhbGxzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgZmluYWwgTWFwPFVyaSwgTGlzdDxEb3dubG9hZE1ldGFkYXRhPj4gdXBzZXJ0Q2FsbHMgPSBuZXcgSGFzaE1hcDw+KCk7CisgICAgZmluYWwgTGlzdDxVcmk+IGRlbGV0ZUNhbGxzID0gbmV3IEFycmF5TGlzdDw+KCk7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxPcHRpb25hbDxEb3dubG9hZE1ldGFkYXRhPj4gcmVhZChVcmkgdXJpKSB7CisgICAgICByZWFkQ2FsbHMuYWRkKHVyaSk7CisKKyAgICAgIHJldHVybiBpbW1lZGlhdGVGdXR1cmUoT3B0aW9uYWwuZnJvbU51bGxhYmxlKHN0b3JlZE1ldGFkYXRhLmdldCh1cmkpKSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gdXBzZXJ0KFVyaSB1cmksIERvd25sb2FkTWV0YWRhdGEgZG93bmxvYWRNZXRhZGF0YSkgeworICAgICAgdXBzZXJ0Q2FsbHMucHV0SWZBYnNlbnQodXJpLCBuZXcgQXJyYXlMaXN0PD4oKSk7CisgICAgICB1cHNlcnRDYWxscy5nZXQodXJpKS5hZGQoZG93bmxvYWRNZXRhZGF0YSk7CisKKyAgICAgIHN0b3JlZE1ldGFkYXRhLnB1dCh1cmksIGRvd25sb2FkTWV0YWRhdGEpOworICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkZWxldGUoVXJpIHVyaSkgeworICAgICAgZGVsZXRlQ2FsbHMuYWRkKHVyaSk7CisKKyAgICAgIHN0b3JlZE1ldGFkYXRhLnJlbW92ZSh1cmkpOworICAgICAgcmV0dXJuIGltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICB9CisKKyAgICBwdWJsaWMgdm9pZCByZXNldCgpIHsKKyAgICAgIHN0b3JlZE1ldGFkYXRhLmNsZWFyKCk7CisKKyAgICAgIHJlYWRDYWxscy5jbGVhcigpOworICAgICAgdXBzZXJ0Q2FsbHMuY2xlYXIoKTsKKyAgICAgIGRlbGV0ZUNhbGxzLmNsZWFyKCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9BbmRyb2lkTWFuaWZlc3QueG1sIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvQW5kcm9pZE1hbmlmZXN0LnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMDhiNmY4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvQW5kcm9pZE1hbmlmZXN0LnhtbApAQCAtMCwwICsxLDMwIEBACis8IS0tCisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLS0+Cis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI/PgorPG1hbmlmZXN0IHhtbG5zOmFuZHJvaWQ9Imh0dHA6Ly9zY2hlbWFzLmFuZHJvaWQuY29tL2Fway9yZXMvYW5kcm9pZCIKKyAgcGFja2FnZT0iY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZSI+CisgICAgPHVzZXMtc2RrCisgICAgICAgICAgICBhbmRyb2lkOm1pblNka1ZlcnNpb249IjE1IgorICAgICAgICAgICAgYW5kcm9pZDp0YXJnZXRTZGtWZXJzaW9uPSIyMyIvPgorICAgIDxhcHBsaWNhdGlvbj4KKyAgICAgICAgPHVzZXMtbGlicmFyeSBhbmRyb2lkOm5hbWU9ImFuZHJvaWQudGVzdC5ydW5uZXIiIC8+CisgICAgPC9hcHBsaWNhdGlvbj4KKyAgICA8aW5zdHJ1bWVudGF0aW9uCisgICAgICAgIGFuZHJvaWQ6bmFtZT0iY29tLmdvb2dsZS5hbmRyb2lkLmFwcHMuY29tbW9uLnRlc3RpbmcudGVzdHJ1bm5lci5Hb29nbGUzSW5zdHJ1bWVudGF0aW9uVGVzdFJ1bm5lciIKKyAgICAgICAgYW5kcm9pZDp0YXJnZXRQYWNrYWdlPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlIiAvPgorPC9tYW5pZmVzdD4KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL0JVSUxEIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDAyZDRmMQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL0JVSUxECkBAIC0wLDAgKzEsNzMgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xvY2FsX3Rlc3QiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCisjIEV4cG9ydCBtYW5pZmVzdCBmaWxlIHRvIGF2b2lkIGNvcHktcGFzdGluZyBpbnRvIGV2ZXJ5IHRlc3QgZGlyZWN0b3J5CitleHBvcnRzX2ZpbGVzKHNyY3MgPSBbIkFuZHJvaWRNYW5pZmVzdC54bWwiXSkKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiTW9uaXRvcklucHV0U3RyZWFtVGVzdCIsCisgICAgc2l6ZSA9ICJzbWFsbCIsCisgICAgc3JjcyA9IFsiTW9uaXRvcklucHV0U3RyZWFtVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nOmV4dHJhcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJNb25pdG9yT3V0cHV0U3RyZWFtVGVzdCIsCisgICAgc2l6ZSA9ICJzbWFsbCIsCisgICAgc3JjcyA9IFsiTW9uaXRvck91dHB1dFN0cmVhbVRlc3QuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiU3luY2hyb25vdXNGaWxlU3RvcmFnZVRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIlN5bmNocm9ub3VzRmlsZVN0b3JhZ2VUZXN0LmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3Rpbmc6ZmlsZXN0b3JhZ2UiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3Rpbmc6bWF0Y2hlcnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6YnVmZmVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6Y29tcHJlc3MiLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvTW9uaXRvcklucHV0U3RyZWFtVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvTW9uaXRvcklucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNkMGJlYjAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9Nb25pdG9ySW5wdXRTdHJlYW1UZXN0LmphdmEKQEAgLTAsMCArMSwxMTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGU7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5tYWtlQXJyYXlPZkJ5dGVzQ29udGVudDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8uZG9UaHJvdzsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by5tb2NrOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnRpbWVzOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnZlcmlmeTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by53aGVuOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuQnVmZmVyaW5nTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5Nb25pdG9yOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKKy8qKiBUZXN0IHtAbGluayBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk1vbml0b3JJbnB1dFN0cmVhbX0uICovCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgY2xhc3MgTW9uaXRvcklucHV0U3RyZWFtVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFRFU1RfQ09OVEVOVCA9IG1ha2VBcnJheU9mQnl0ZXNDb250ZW50KCk7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbW9uaXRvclJlYWRfc2hvdWxkU2VlQWxsQnl0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCdWZmZXJpbmdNb25pdG9yIGJ1ZmZlciA9IG5ldyBCdWZmZXJpbmdNb25pdG9yKCk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiZm9vOiIpOworICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFRFU1RfQ09OVEVOVCk7CisgICAgTW9uaXRvcklucHV0U3RyZWFtIHN0cmVhbSA9IE1vbml0b3JJbnB1dFN0cmVhbS5uZXdJbnN0YW5jZShBcnJheXMuYXNMaXN0KGJ1ZmZlciksIHVyaSwgaW4pOworCisgICAgc3RyZWFtLnJlYWQoKTsKKyAgICBzdHJlYW0ucmVhZChuZXcgYnl0ZVs1XSk7CisgICAgc3RyZWFtLnJlYWQoKTsKKyAgICBzdHJlYW0ucmVhZChuZXcgYnl0ZVsxMF0sIDUsIDMpOworCisgICAgYXNzZXJ0VGhhdChidWZmZXIuYnl0ZXNSZWFkKCkpLmlzRXF1YWxUbyhBcnJheXMuY29weU9mKFRFU1RfQ09OVEVOVCwgMTApKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1vbml0b3JSZWFkX3dpdGhOdWxsSW5wdXRNb25pdG9yX3Nob3VsZFJldHVybk51bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNb25pdG9yIG1vY2tNb25pdG9yID0gbW9jayhNb25pdG9yLmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb25pdG9yLm1vbml0b3JSZWFkKGFueSgpKSkudGhlblJldHVybihudWxsKTsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJmb286Iik7CisgICAgSW5wdXRTdHJlYW0gaW4gPSBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oVEVTVF9DT05URU5UKTsKKworICAgIGFzc2VydFRoYXQoTW9uaXRvcklucHV0U3RyZWFtLm5ld0luc3RhbmNlKEFycmF5cy5hc0xpc3QobW9ja01vbml0b3IpLCB1cmksIGluKSkuaXNOdWxsKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtb25pdG9yUmVhZF9zaG91bGRDYWxsQ2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNb25pdG9yIG1vY2tNb25pdG9yID0gbW9jayhNb25pdG9yLmNsYXNzKTsKKyAgICBNb25pdG9yLklucHV0TW9uaXRvciBtb2NrSW5wdXRNb25pdG9yID0gbW9jayhNb25pdG9yLklucHV0TW9uaXRvci5jbGFzcyk7CisgICAgd2hlbihtb2NrTW9uaXRvci5tb25pdG9yUmVhZChhbnkoKSkpLnRoZW5SZXR1cm4obW9ja0lucHV0TW9uaXRvcik7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiZm9vOiIpOworICAgIElucHV0U3RyZWFtIGluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKFRFU1RfQ09OVEVOVCk7CisgICAgdHJ5IChNb25pdG9ySW5wdXRTdHJlYW0gc3RyZWFtID0KKyAgICAgICAgTW9uaXRvcklucHV0U3RyZWFtLm5ld0luc3RhbmNlKEFycmF5cy5hc0xpc3QobW9ja01vbml0b3IpLCB1cmksIGluKSkgeworICAgICAgc3RyZWFtLnJlYWQobmV3IGJ5dGVbVEVTVF9DT05URU5ULmxlbmd0aF0pOworICAgIH0KKyAgICB2ZXJpZnkobW9ja0lucHV0TW9uaXRvciwgdGltZXMoMSkpLmNsb3NlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtb25pdG9yUmVhZFdpdGhNb25pdG9yQ2xvc2VFeGNlcHRpb25fc2hvdWxkQ2FsbENsb3NlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTW9uaXRvciBtb2NrTW9uaXRvciA9IG1vY2soTW9uaXRvci5jbGFzcyk7CisgICAgTW9uaXRvci5JbnB1dE1vbml0b3IgbW9ja0lucHV0TW9uaXRvciA9IG1vY2soTW9uaXRvci5JbnB1dE1vbml0b3IuY2xhc3MpOworICAgIHdoZW4obW9ja01vbml0b3IubW9uaXRvclJlYWQoYW55KCkpKS50aGVuUmV0dXJuKG1vY2tJbnB1dE1vbml0b3IpOworICAgIGRvVGhyb3cobmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuY2hlY2tlZCIpKS53aGVuKG1vY2tJbnB1dE1vbml0b3IpLmNsb3NlKCk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiZm9vOiIpOworICAgIEZha2VJbnB1dFN0cmVhbSBmYWtlSW4gPSBuZXcgRmFrZUlucHV0U3RyZWFtKCk7CisgICAgdHJ5IChNb25pdG9ySW5wdXRTdHJlYW0gc3RyZWFtID0KKyAgICAgICAgTW9uaXRvcklucHV0U3RyZWFtLm5ld0luc3RhbmNlKEFycmF5cy5hc0xpc3QobW9ja01vbml0b3IpLCB1cmksIGZha2VJbikpIHsKKyAgICAgIHN0cmVhbS5yZWFkKG5ldyBieXRlW1RFU1RfQ09OVEVOVC5sZW5ndGhdKTsKKyAgICB9CisgICAgdmVyaWZ5KG1vY2tJbnB1dE1vbml0b3IsIHRpbWVzKDEpKS5jbG9zZSgpOworICAgIGFzc2VydFRoYXQoZmFrZUluLmJ5dGVzUmVhZCkuaXNFcXVhbFRvKFRFU1RfQ09OVEVOVC5sZW5ndGgpOworICAgIGFzc2VydFRoYXQoZmFrZUluLmNsb3NlZCkuaXNUcnVlKCk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBGYWtlSW5wdXRTdHJlYW0gZXh0ZW5kcyBJbnB1dFN0cmVhbSB7CisgICAgcHJpdmF0ZSBib29sZWFuIGNsb3NlZCA9IHRydWU7CisgICAgcHJpdmF0ZSBpbnQgYnl0ZXNSZWFkID0gMDsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgICBieXRlc1JlYWQgKz0gMTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGNsb3NlZCA9IHRydWU7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9Nb25pdG9yT3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvTW9uaXRvck91dHB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zY2U5NjQxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvTW9uaXRvck91dHB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDE0NyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZTsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLm1ha2VBcnJheU9mQnl0ZXNDb250ZW50OworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by5kb1Rocm93OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLm1vY2s7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udGltZXM7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLndoZW47CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5CdWZmZXJpbmdNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLk1vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS50aGlyZHBhcnR5LnJvYm9sZWN0cmljLkdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworCisvKiogVGVzdCB7QGxpbmsgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5Nb25pdG9yT3V0cHV0U3RyZWFtfS4gKi8KK0BSdW5XaXRoKEdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBNb25pdG9yT3V0cHV0U3RyZWFtVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIFRFU1RfQ09OVEVOVCA9IG1ha2VBcnJheU9mQnl0ZXNDb250ZW50KCk7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbW9uaXRvcldyaXRlX3Nob3VsZFNlZUFsbEJ5dGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQnVmZmVyaW5nTW9uaXRvciBidWZmZXIgPSBuZXcgQnVmZmVyaW5nTW9uaXRvcigpOworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImZvbzoiKTsKKyAgICBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIE1vbml0b3JPdXRwdXRTdHJlYW0gc3RyZWFtID0KKyAgICAgICAgTW9uaXRvck91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZUZvcldyaXRlKEFycmF5cy5hc0xpc3QoYnVmZmVyKSwgdXJpLCBvdXQpOworCisgICAgYnl0ZVtdIGNvbnRlbnQwID0gQXJyYXlzLmNvcHlPZihURVNUX0NPTlRFTlQsIDcpOworICAgIGJ5dGVbXSBjb250ZW50MSA9IEFycmF5cy5jb3B5T2ZSYW5nZShURVNUX0NPTlRFTlQsIDcsIDEwKTsKKyAgICBzdHJlYW0ud3JpdGUoY29udGVudDBbMF0pOworICAgIHN0cmVhbS53cml0ZShjb250ZW50MCwgMSwgNik7CisgICAgc3RyZWFtLndyaXRlKGNvbnRlbnQxKTsKKworICAgIGFzc2VydFRoYXQoYnVmZmVyLmJ5dGVzV3JpdHRlbigpKS5pc0VxdWFsVG8oQXJyYXlzLmNvcHlPZihURVNUX0NPTlRFTlQsIDEwKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtb25pdG9yQXBwZW5kX3Nob3VsZFNlZUFsbEJ5dGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQnVmZmVyaW5nTW9uaXRvciBidWZmZXIgPSBuZXcgQnVmZmVyaW5nTW9uaXRvcigpOworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImZvbzoiKTsKKyAgICBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIE1vbml0b3JPdXRwdXRTdHJlYW0gc3RyZWFtID0KKyAgICAgICAgTW9uaXRvck91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZUZvckFwcGVuZChBcnJheXMuYXNMaXN0KGJ1ZmZlciksIHVyaSwgb3V0KTsKKworICAgIGJ5dGVbXSBjb250ZW50MCA9IEFycmF5cy5jb3B5T2YoVEVTVF9DT05URU5ULCA3KTsKKyAgICBieXRlW10gY29udGVudDEgPSBBcnJheXMuY29weU9mUmFuZ2UoVEVTVF9DT05URU5ULCA3LCAxMCk7CisgICAgc3RyZWFtLndyaXRlKGNvbnRlbnQwWzBdKTsKKyAgICBzdHJlYW0ud3JpdGUoY29udGVudDAsIDEsIDYpOworICAgIHN0cmVhbS53cml0ZShjb250ZW50MSk7CisKKyAgICBhc3NlcnRUaGF0KGJ1ZmZlci5ieXRlc0FwcGVuZGVkKCkpLmlzRXF1YWxUbyhBcnJheXMuY29weU9mKFRFU1RfQ09OVEVOVCwgMTApKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1vbml0b3JXcml0ZV93aXRoTnVsbE91dHB1dE1vbml0b3Jfc2hvdWxkUmV0dXJuTnVsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIE1vbml0b3IgbW9ja01vbml0b3IgPSBtb2NrKE1vbml0b3IuY2xhc3MpOworICAgIHdoZW4obW9ja01vbml0b3IubW9uaXRvcldyaXRlKGFueSgpKSkudGhlblJldHVybihudWxsKTsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJmb286Iik7CisgICAgT3V0cHV0U3RyZWFtIG91dCA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKworICAgIGFzc2VydFRoYXQoTW9uaXRvck91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZUZvcldyaXRlKEFycmF5cy5hc0xpc3QobW9ja01vbml0b3IpLCB1cmksIG91dCkpCisgICAgICAgIC5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1vbml0b3JBcHBlbmRfd2l0aE51bGxPdXRwdXRNb25pdG9yX3Nob3VsZFJldHVybk51bGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNb25pdG9yIG1vY2tNb25pdG9yID0gbW9jayhNb25pdG9yLmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb25pdG9yLm1vbml0b3JBcHBlbmQoYW55KCkpKS50aGVuUmV0dXJuKG51bGwpOworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImZvbzoiKTsKKyAgICBPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworCisgICAgYXNzZXJ0VGhhdChNb25pdG9yT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlRm9yQXBwZW5kKEFycmF5cy5hc0xpc3QobW9ja01vbml0b3IpLCB1cmksIG91dCkpCisgICAgICAgIC5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1vbml0b3JXcml0ZV9zaG91bGRDYWxsQ2xvc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNb25pdG9yIG1vY2tNb25pdG9yID0gbW9jayhNb25pdG9yLmNsYXNzKTsKKyAgICBNb25pdG9yLk91dHB1dE1vbml0b3IgbW9ja091dHB1dE1vbml0b3IgPSBtb2NrKE1vbml0b3IuT3V0cHV0TW9uaXRvci5jbGFzcyk7CisgICAgd2hlbihtb2NrTW9uaXRvci5tb25pdG9yV3JpdGUoYW55KCkpKS50aGVuUmV0dXJuKG1vY2tPdXRwdXRNb25pdG9yKTsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJmb286Iik7CisgICAgRmFrZU91dHB1dFN0cmVhbSBmYWtlT3V0ID0gbmV3IEZha2VPdXRwdXRTdHJlYW0oKTsKKyAgICB0cnkgKE1vbml0b3JPdXRwdXRTdHJlYW0gc3RyZWFtID0KKyAgICAgICAgTW9uaXRvck91dHB1dFN0cmVhbS5uZXdJbnN0YW5jZUZvcldyaXRlKEFycmF5cy5hc0xpc3QobW9ja01vbml0b3IpLCB1cmksIGZha2VPdXQpKSB7CisgICAgICBzdHJlYW0ud3JpdGUoVEVTVF9DT05URU5UKTsKKyAgICB9CisgICAgdmVyaWZ5KG1vY2tPdXRwdXRNb25pdG9yLCB0aW1lcygxKSkuY2xvc2UoKTsKKyAgICBhc3NlcnRUaGF0KGZha2VPdXQuYnl0ZXNXcml0dGVuKS5pc0VxdWFsVG8oVEVTVF9DT05URU5ULmxlbmd0aCk7CisgICAgYXNzZXJ0VGhhdChmYWtlT3V0LmNsb3NlZCkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtb25pdG9yV3JpdGVXaXRoTW9uaXRvckNsb3NlRXhjZXB0aW9uX3Nob3VsZENhbGxDbG9zZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIE1vbml0b3IgbW9ja01vbml0b3IgPSBtb2NrKE1vbml0b3IuY2xhc3MpOworICAgIE1vbml0b3IuT3V0cHV0TW9uaXRvciBtb2NrT3V0cHV0TW9uaXRvciA9IG1vY2soTW9uaXRvci5PdXRwdXRNb25pdG9yLmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNb25pdG9yLm1vbml0b3JXcml0ZShhbnkoKSkpLnRoZW5SZXR1cm4obW9ja091dHB1dE1vbml0b3IpOworICAgIGRvVGhyb3cobmV3IFJ1bnRpbWVFeGNlcHRpb24oIlVuY2hlY2tlZCIpKS53aGVuKG1vY2tPdXRwdXRNb25pdG9yKS5jbG9zZSgpOworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImZvbzoiKTsKKyAgICBGYWtlT3V0cHV0U3RyZWFtIGZha2VPdXQgPSBuZXcgRmFrZU91dHB1dFN0cmVhbSgpOworICAgIHRyeSAoTW9uaXRvck91dHB1dFN0cmVhbSBzdHJlYW0gPQorICAgICAgICBNb25pdG9yT3V0cHV0U3RyZWFtLm5ld0luc3RhbmNlRm9yV3JpdGUoQXJyYXlzLmFzTGlzdChtb2NrTW9uaXRvciksIHVyaSwgZmFrZU91dCkpIHsKKyAgICAgIHN0cmVhbS53cml0ZShURVNUX0NPTlRFTlQpOworICAgIH0KKyAgICB2ZXJpZnkobW9ja091dHB1dE1vbml0b3IsIHRpbWVzKDEpKS5jbG9zZSgpOworICAgIGFzc2VydFRoYXQoZmFrZU91dC5ieXRlc1dyaXR0ZW4pLmlzRXF1YWxUbyhURVNUX0NPTlRFTlQubGVuZ3RoKTsKKyAgICBhc3NlcnRUaGF0KGZha2VPdXQuY2xvc2VkKS5pc1RydWUoKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIEZha2VPdXRwdXRTdHJlYW0gZXh0ZW5kcyBPdXRwdXRTdHJlYW0geworICAgIHByaXZhdGUgYm9vbGVhbiBjbG9zZWQgPSB0cnVlOworICAgIHByaXZhdGUgaW50IGJ5dGVzV3JpdHRlbiA9IDA7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCB3cml0ZShpbnQgYikgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGJ5dGVzV3JpdHRlbiArPSAxOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIGNsb3NlZCA9IHRydWU7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9TeW5jaHJvbm91c0ZpbGVTdG9yYWdlVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvU3luY2hyb25vdXNGaWxlU3RvcmFnZVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lM2RjMDE4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvU3luY2hyb25vdXNGaWxlU3RvcmFnZVRlc3QuamF2YQpAQCAtMCwwICsxLDQ4OSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZTsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkZyYWdtZW50UGFyYW1NYXRjaGVycy5lcVBhcmFtOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8uYXRMZWFzdDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by5kb1Rocm93OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLmVxOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLmluT3JkZXI7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ubmV2ZXI7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnZlcmlmeU5vTW9yZUludGVyYWN0aW9uczsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by53aGVuOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5HY1BhcmFtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5CdWZmZXJpbmdNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuRmlsZVN0b3JhZ2VUZXN0QmFzZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLk5vT3BNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5BcHBlbmRTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLlJlYWRTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLldyaXRlU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuRm9yd2FyZGluZ0JhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5CdWZmZXJUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLkNvbXByZXNzVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLkluT3JkZXI7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworLyoqCisgKiBUZXN0IHtAbGluayBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2V9LiBUaGVzZQorICogdGVzdHMgdXNlIG1vY2tzIGFuZCBiYXNpY2FsbHkganVzdCBlbnN1cmUgdGhhdCB0aGluZ3MgYXJlIGJlaW5nIGNhbGxlZCBpbiB0aGUgZXhwZWN0ZWQgb3JkZXIuCisgKi8KK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlVGVzdCBleHRlbmRzIEZpbGVTdG9yYWdlVGVzdEJhc2UgeworCisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCB2b2lkIGluaXRTdG9yYWdlKCkgeworICAgIHN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoZmlsZUJhY2tlbmQsIGNuc0JhY2tlbmQpLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihjb21wcmVzc1RyYW5zZm9ybSwgZW5jcnlwdFRyYW5zZm9ybSwgaWRlbnRpdHlUcmFuc2Zvcm0pLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihjb3VudGluZ01vbml0b3IpKTsKKyAgfQorCisgIC8vIEJhY2tlbmQgcmVnaXN0cmFyCisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVnaXN0ZXJlZEJhY2tlbmRzX3Nob3VsZE5vdFRocm93RXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyhmaWxlMVVyaSkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVucmVnaXN0ZXJlZEJhY2tlbmRzX3Nob3VsZFRocm93RXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVucmVnaXN0ZXJlZFVyaSA9IFVyaS5wYXJzZSgidW5yZWdpc3RlcmVkOi8vLyIpOworICAgIGFzc2VydFRocm93cyhVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLmV4aXN0cyh1bnJlZ2lzdGVyZWRVcmkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG51bGxVcmlTY2hlbWVfc2hvdWxkVGhyb3dFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgcmVsYXRpdmVVcmkgPSBVcmkucGFyc2UoIi9yZWxhdGl2ZS91cmkiKTsKKyAgICBhc3NlcnRUaHJvd3MoVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbi5jbGFzcywgKCkgLT4gc3RvcmFnZS5leGlzdHMocmVsYXRpdmVVcmkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGVtcHR5QmFja2VuZE5hbWVfc2hvdWxkQmVTaWxlbnRseVNraXBwZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBCYWNrZW5kIGVtcHR5TmFtZUJhY2tlbmQgPQorICAgICAgICBuZXcgRm9yd2FyZGluZ0JhY2tlbmQoKSB7CisgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgcHJvdGVjdGVkIEJhY2tlbmQgZGVsZWdhdGUoKSB7CisgICAgICAgICAgICByZXR1cm4gZmlsZUJhY2tlbmQ7CisgICAgICAgICAgfQorCisgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgcHVibGljIFN0cmluZyBuYW1lKCkgeworICAgICAgICAgICAgcmV0dXJuICIiOworICAgICAgICAgIH0KKyAgICAgICAgfTsKKyAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZShJbW11dGFibGVMaXN0Lm9mKGVtcHR5TmFtZUJhY2tlbmQpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvdWJsZVJlZ2lzdGVyaW5nQmFja2VuZE5hbWVfc2hvdWxkVGhyb3dFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IEphdmFGaWxlQmFja2VuZCgpLCBuZXcgSmF2YUZpbGVCYWNrZW5kKCkpKSk7CisgIH0KKworICAvLyBCYWNrZW5kIG9wZXJhdGlvbnMKKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVGaWxlX3Nob3VsZEludm9rZUJhY2tlbmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9yYWdlLmRlbGV0ZUZpbGUoZmlsZTFVcmkpOworICAgIHZlcmlmeShmaWxlQmFja2VuZCkuZGVsZXRlRmlsZShmaWxlMVVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVEaXJfc2hvdWxkSW52b2tlQmFja2VuZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN0b3JhZ2UuZGVsZXRlRGlyZWN0b3J5KGZpbGUxVXJpKTsKKyAgICB2ZXJpZnkoZmlsZUJhY2tlbmQpLmRlbGV0ZURpcmVjdG9yeShmaWxlMVVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVSZWN1cnNpdmVseV9zaG91bGRSZWN1cnNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGRpcjJVcmkgPSBkaXIxVXJpLmJ1aWxkVXBvbigpLmFwcGVuZFBhdGgoImRpcjIiKS5idWlsZCgpOworICAgIHdoZW4oZmlsZUJhY2tlbmQuZXhpc3RzKGRpcjFVcmkpKS50aGVuUmV0dXJuKHRydWUpOworICAgIHdoZW4oZmlsZUJhY2tlbmQuaXNEaXJlY3RvcnkoZGlyMVVyaSkpLnRoZW5SZXR1cm4odHJ1ZSk7CisgICAgd2hlbihmaWxlQmFja2VuZC5leGlzdHMoZGlyMlVyaSkpLnRoZW5SZXR1cm4odHJ1ZSk7CisgICAgd2hlbihmaWxlQmFja2VuZC5pc0RpcmVjdG9yeShkaXIyVXJpKSkudGhlblJldHVybih0cnVlKTsKKyAgICB3aGVuKGZpbGVCYWNrZW5kLmV4aXN0cyhmaWxlMVVyaSkpLnRoZW5SZXR1cm4odHJ1ZSk7CisgICAgd2hlbihmaWxlQmFja2VuZC5leGlzdHMoZmlsZTJVcmkpKS50aGVuUmV0dXJuKHRydWUpOworICAgIHdoZW4oZmlsZUJhY2tlbmQuY2hpbGRyZW4oZGlyMVVyaSkpLnRoZW5SZXR1cm4oSW1tdXRhYmxlTGlzdC5vZihmaWxlMVVyaSwgZmlsZTJVcmksIGRpcjJVcmkpKTsKKyAgICB3aGVuKGZpbGVCYWNrZW5kLmNoaWxkcmVuKGRpcjJVcmkpKS50aGVuUmV0dXJuKENvbGxlY3Rpb25zLmVtcHR5TGlzdCgpKTsKKworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5kZWxldGVSZWN1cnNpdmVseShkaXIxVXJpKSkuaXNUcnVlKCk7CisKKyAgICB2ZXJpZnkoZmlsZUJhY2tlbmQpLmRlbGV0ZUZpbGUoZmlsZTFVcmkpOworICAgIHZlcmlmeShmaWxlQmFja2VuZCkuZGVsZXRlRmlsZShmaWxlMlVyaSk7CisgICAgdmVyaWZ5KGZpbGVCYWNrZW5kKS5kZWxldGVEaXJlY3RvcnkoZGlyMlVyaSk7CisgICAgdmVyaWZ5KGZpbGVCYWNrZW5kKS5kZWxldGVEaXJlY3RvcnkoZGlyMVVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVSZWN1cnNpdmVseV9mYWlsc09uQWNjZXNzRXJyb3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKGZpbGVCYWNrZW5kLmV4aXN0cyhkaXIxVXJpKSkudGhlblJldHVybih0cnVlKTsKKyAgICB3aGVuKGZpbGVCYWNrZW5kLmlzRGlyZWN0b3J5KGRpcjFVcmkpKS50aGVuUmV0dXJuKHRydWUpOworICAgIHdoZW4oZmlsZUJhY2tlbmQuZXhpc3RzKGZpbGUxVXJpKSkudGhlblJldHVybih0cnVlKTsKKyAgICB3aGVuKGZpbGVCYWNrZW5kLmV4aXN0cyhmaWxlMlVyaSkpLnRoZW5SZXR1cm4odHJ1ZSk7CisgICAgd2hlbihmaWxlQmFja2VuZC5jaGlsZHJlbihkaXIxVXJpKSkudGhlblJldHVybihJbW11dGFibGVMaXN0Lm9mKGZpbGUxVXJpLCBmaWxlMlVyaSkpOworICAgIGRvVGhyb3coSU9FeGNlcHRpb24uY2xhc3MpLndoZW4oZmlsZUJhY2tlbmQpLmRlbGV0ZUZpbGUoZmlsZTJVcmkpOworCisgICAgYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLmRlbGV0ZVJlY3Vyc2l2ZWx5KGRpcjFVcmkpKTsKKworICAgIHZlcmlmeShmaWxlQmFja2VuZCkuZGVsZXRlRmlsZShmaWxlMVVyaSk7CisgICAgdmVyaWZ5KGZpbGVCYWNrZW5kKS5kZWxldGVGaWxlKGZpbGUyVXJpKTsKKyAgICB2ZXJpZnkoZmlsZUJhY2tlbmQsIG5ldmVyKCkpLmRlbGV0ZURpcmVjdG9yeShkaXIxVXJpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRlbGV0ZVJlY3Vyc2l2ZWx5X2ZpbGVEZWxldGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgd2hlbihmaWxlQmFja2VuZC5leGlzdHMoZmlsZTFVcmkpKS50aGVuUmV0dXJuKHRydWUpOworICAgIHdoZW4oZmlsZUJhY2tlbmQuaXNEaXJlY3RvcnkoZmlsZTFVcmkpKS50aGVuUmV0dXJuKGZhbHNlKTsKKworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5kZWxldGVSZWN1cnNpdmVseShmaWxlMVVyaSkpLmlzVHJ1ZSgpOworCisgICAgdmVyaWZ5KGZpbGVCYWNrZW5kKS5leGlzdHMoZmlsZTFVcmkpOworICAgIHZlcmlmeShmaWxlQmFja2VuZCkuZGVsZXRlRmlsZShmaWxlMVVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZWxldGVSZWN1cnNpdmVseV9maWxlTm90RXhpc3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKGZpbGVCYWNrZW5kLmV4aXN0cyhkaXIxVXJpKSkudGhlblJldHVybihmYWxzZSk7CisKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZGVsZXRlUmVjdXJzaXZlbHkoZGlyMVVyaSkpLmlzRmFsc2UoKTsKKworICAgIHZlcmlmeShmaWxlQmFja2VuZCkuZXhpc3RzKGRpcjFVcmkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVuYW1lX3Nob3VsZEludm9rZUJhY2tlbmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9yYWdlLnJlbmFtZShmaWxlMVVyaSwgZmlsZTJVcmkpOworICAgIHZlcmlmeShmaWxlQmFja2VuZCkucmVuYW1lKGZpbGUxVXJpLCBmaWxlMlVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZW5hbWVfY3Jvc3NpbmdCYWNrZW5kc1Nob3VsZFRocm93RXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhyb3dzKFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24uY2xhc3MsICgpIC0+IHN0b3JhZ2UucmVuYW1lKGZpbGUxVXJpLCBjbnNVcmkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGV4aXN0c19zaG91bGRJbnZva2VCYWNrZW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyhmaWxlMVVyaSkpLmlzRmFsc2UoKTsKKyAgICB2ZXJpZnkoZmlsZUJhY2tlbmQpLmV4aXN0cyhmaWxlMVVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpc0RpcmVjdG9yeV9zaG91bGRJbnZva2VCYWNrZW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmlzRGlyZWN0b3J5KGZpbGUxVXJpKSkuaXNGYWxzZSgpOworICAgIHZlcmlmeShmaWxlQmFja2VuZCkuaXNEaXJlY3RvcnkoZmlsZTFVcmkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY3JlYXRlRGlyZWN0b3J5c2hvdWxkSW52b2tlQmFja2VuZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN0b3JhZ2UuY3JlYXRlRGlyZWN0b3J5KGZpbGUxVXJpKTsKKyAgICB2ZXJpZnkoZmlsZUJhY2tlbmQpLmNyZWF0ZURpcmVjdG9yeShmaWxlMVVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBmaWxlU2l6ZV9zaG91bGRJbnZva2VCYWNrZW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmZpbGVTaXplKGZpbGUxVXJpKSkuaXNFcXVhbFRvKDBMKTsKKyAgICB2ZXJpZnkoZmlsZUJhY2tlbmQpLmZpbGVTaXplKGZpbGUxVXJpKTsKKyAgfQorCisgIC8vCisgIC8vIFRyYW5zZm9ybSBzdHVmZgorICAvLworCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlZ2lzdGVyZWRUcmFuc2Zvcm1zX3Nob3VsZE5vdFRocm93RXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyhmaWxlMUNvbXByZXNzVXJpKSkuaXNGYWxzZSgpOworICAgIHZlcmlmeShmaWxlQmFja2VuZCkuZXhpc3RzKGZpbGUxVXJpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVucmVnaXN0ZXJlZFRyYW5zZm9ybXNfc2hvdWxkVGhyb3dFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdW5yZWdpc3RlcmVkVXJpID0gVXJpLnBhcnNlKGZpbGUxVXJpICsgIiN0cmFuc2Zvcm09dW5yZWdpc3RlcmVkIik7CisgICAgYXNzZXJ0VGhyb3dzKFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24uY2xhc3MsICgpIC0+IHN0b3JhZ2UuZXhpc3RzKHVucmVnaXN0ZXJlZFVyaSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0RGVidWdJbmZvX3Nob3VsZEluY2x1ZGVSZWdpc3RlcmVkUGx1Z2lucygpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZGVidWdTdG9yYWdlID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKG5ldyBKYXZhRmlsZUJhY2tlbmQoKSwgQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuYnVpbGQoKSksCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKG5ldyBDb21wcmVzc1RyYW5zZm9ybSgpLCBuZXcgQnVmZmVyVHJhbnNmb3JtKCkpLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihuZXcgQnVmZmVyaW5nTW9uaXRvcigpLCBuZXcgTm9PcE1vbml0b3IoKSkpOworICAgIFN0cmluZyBkZWJ1Z1N0cmluZyA9IGRlYnVnU3RvcmFnZS5nZXREZWJ1Z0luZm8oKTsKKworICAgIGFzc2VydFRoYXQoZGVidWdTdHJpbmcpCisgICAgICAgIC5pc0VxdWFsVG8oCisgICAgICAgICAgICAiUmVnaXN0ZXJlZCBNb2JzdG9yZSBQbHVnaW5zOlxuIgorICAgICAgICAgICAgICAgICsgIlxuIgorICAgICAgICAgICAgICAgICsgIkJhY2tlbmRzOlxuIgorICAgICAgICAgICAgICAgICsgInByb3RvY29sOiBhbmRyb2lkLCBjbGFzczogQW5kcm9pZEZpbGVCYWNrZW5kLFxuIgorICAgICAgICAgICAgICAgICsgInByb3RvY29sOiBmaWxlLCBjbGFzczogSmF2YUZpbGVCYWNrZW5kXG4iCisgICAgICAgICAgICAgICAgKyAiXG4iCisgICAgICAgICAgICAgICAgKyAiVHJhbnNmb3JtczpcbiIKKyAgICAgICAgICAgICAgICArICJCdWZmZXJUcmFuc2Zvcm0sXG4iCisgICAgICAgICAgICAgICAgKyAiQ29tcHJlc3NUcmFuc2Zvcm1cbiIKKyAgICAgICAgICAgICAgICArICJcbiIKKyAgICAgICAgICAgICAgICArICJNb25pdG9yczpcbiIKKyAgICAgICAgICAgICAgICArICJCdWZmZXJpbmdNb25pdG9yLFxuIgorICAgICAgICAgICAgICAgICsgIk5vT3BNb25pdG9yIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBlbXB0eVRyYW5zZm9ybU5hbWVfc2hvdWxkQmVTaWxlbnRseVNraXBwZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUcmFuc2Zvcm0gZW1wdHlOYW1lVHJhbnNmb3JtID0KKyAgICAgICAgbmV3IFRyYW5zZm9ybSgpIHsKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgU3RyaW5nIG5hbWUoKSB7CisgICAgICAgICAgICByZXR1cm4gIiI7CisgICAgICAgICAgfQorICAgICAgICB9OworICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEltbXV0YWJsZUxpc3Qub2YoKSwgSW1tdXRhYmxlTGlzdC5vZihlbXB0eU5hbWVUcmFuc2Zvcm0pKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvdWJsZVJlZ2lzdGVyaW5nVHJhbnNmb3JtTmFtZV9zaG91bGRUaHJvd0V4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAoKSAtPgorICAgICAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigpLAorICAgICAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IENvbXByZXNzVHJhbnNmb3JtKCksIG5ldyBDb21wcmVzc1RyYW5zZm9ybSgpKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVhZF9zaG91bGRJbnZva2VUcmFuc2Zvcm1zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgd2hlbihjb21wcmVzc1RyYW5zZm9ybS53cmFwRm9yUmVhZChlcVBhcmFtKHVyaVdpdGhDb21wcmVzc1BhcmFtKSwgYW55KElucHV0U3RyZWFtLmNsYXNzKSkpCisgICAgICAgIC50aGVuUmV0dXJuKGNvbXByZXNzSW5wdXRTdHJlYW0pOworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBzdG9yYWdlLm9wZW4oZmlsZTFDb21wcmVzc1VyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIHZlcmlmeShjb21wcmVzc1RyYW5zZm9ybSkud3JhcEZvclJlYWQoZXFQYXJhbSh1cmlXaXRoQ29tcHJlc3NQYXJhbSksIGFueShJbnB1dFN0cmVhbS5jbGFzcykpOworICAgICAgdmVyaWZ5KGNvbXByZXNzVHJhbnNmb3JtKS5lbmNvZGUoZXFQYXJhbSh1cmlXaXRoQ29tcHJlc3NQYXJhbSksIGVxKGZpbGUxRmlsZW5hbWUpKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZWFkX3Nob3VsZEludm9rZVRyYW5zZm9ybXNXaXRoRW5jb2RlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHdoZW4oY29tcHJlc3NUcmFuc2Zvcm0ud3JhcEZvclJlYWQoCisgICAgICAgICAgICBlcVBhcmFtKHVyaVdpdGhDb21wcmVzc1BhcmFtV2l0aEVuY29kZWQpLCBhbnkoSW5wdXRTdHJlYW0uY2xhc3MpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oY29tcHJlc3NJbnB1dFN0cmVhbSk7CisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9IHN0b3JhZ2Uub3BlbihmaWxlMUNvbXByZXNzVXJpV2l0aEVuY29kZWQsIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICB2ZXJpZnkoY29tcHJlc3NUcmFuc2Zvcm0pCisgICAgICAgICAgLndyYXBGb3JSZWFkKGVxUGFyYW0odXJpV2l0aENvbXByZXNzUGFyYW1XaXRoRW5jb2RlZCksIGFueShJbnB1dFN0cmVhbS5jbGFzcykpOworICAgICAgdmVyaWZ5KGNvbXByZXNzVHJhbnNmb3JtKS5lbmNvZGUoZXFQYXJhbSh1cmlXaXRoQ29tcHJlc3NQYXJhbVdpdGhFbmNvZGVkKSwgZXEoZmlsZTFGaWxlbmFtZSkpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHdyaXRlX3Nob3VsZEludm9rZVRyYW5zZm9ybXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKGNvbXByZXNzVHJhbnNmb3JtLndyYXBGb3JXcml0ZShlcVBhcmFtKHVyaVdpdGhDb21wcmVzc1BhcmFtKSwgYW55KE91dHB1dFN0cmVhbS5jbGFzcykpKQorICAgICAgICAudGhlblJldHVybihjb21wcmVzc091dHB1dFN0cmVhbSk7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gc3RvcmFnZS5vcGVuKGZpbGUxQ29tcHJlc3NVcmksIFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgdmVyaWZ5KGNvbXByZXNzVHJhbnNmb3JtKQorICAgICAgICAgIC53cmFwRm9yV3JpdGUoZXFQYXJhbSh1cmlXaXRoQ29tcHJlc3NQYXJhbSksIGFueShPdXRwdXRTdHJlYW0uY2xhc3MpKTsKKyAgICAgIHZlcmlmeShjb21wcmVzc1RyYW5zZm9ybSkuZW5jb2RlKGVxUGFyYW0odXJpV2l0aENvbXByZXNzUGFyYW0pLCBlcShmaWxlMUZpbGVuYW1lKSk7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZGVsZXRlRmlsZV9zaG91bGRJbnZva2VUcmFuc2Zvcm1FbmNvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9yYWdlLmRlbGV0ZUZpbGUoZmlsZTFDb21wcmVzc1VyaSk7CisgICAgdmVyaWZ5KGNvbXByZXNzVHJhbnNmb3JtKS5lbmNvZGUoZXFQYXJhbSh1cmlXaXRoQ29tcHJlc3NQYXJhbSksIGVxKGZpbGUxRmlsZW5hbWUpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRlbGV0ZURpcmVjdG9yeV9zaG91bGROT1RJbnZva2VUcmFuc2Zvcm1FbmNvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9yYWdlLmRlbGV0ZURpcmVjdG9yeShmaWxlMUNvbXByZXNzVXJpKTsKKyAgICB2ZXJpZnkoY29tcHJlc3NUcmFuc2Zvcm0sIG5ldmVyKCkpLmVuY29kZShlcVBhcmFtKHVyaVdpdGhDb21wcmVzc1BhcmFtKSwgYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVuYW1lX3Nob3VsZEludm9rZVRyYW5zZm9ybUVuY29kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN0b3JhZ2UucmVuYW1lKGZpbGUxQ29tcHJlc3NVcmksIGZpbGUyQ29tcHJlc3NFbmNyeXB0VXJpKTsKKyAgICB2ZXJpZnkoY29tcHJlc3NUcmFuc2Zvcm0pLmVuY29kZShlcVBhcmFtKHVyaVdpdGhDb21wcmVzc1BhcmFtKSwgZXEoZmlsZTFGaWxlbmFtZSkpOworICAgIHZlcmlmeShlbmNyeXB0VHJhbnNmb3JtKS5lbmNvZGUoZXFQYXJhbSh1cmlXaXRoRW5jcnlwdFBhcmFtKSwgZXEoZmlsZTJGaWxlbmFtZSkpOworICAgIHZlcmlmeShjb21wcmVzc1RyYW5zZm9ybSkuZW5jb2RlKGVxUGFyYW0odXJpV2l0aENvbXByZXNzUGFyYW0pLCBlcShmaWxlMkZpbGVuYW1lKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZW5hbWVfc2hvdWxkTk9USW52b2tlVHJhbnNmb3JtRW5jb2RlT25EaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9yYWdlLnJlbmFtZShkaXIxVXJpLCBkaXIyQ29tcHJlc3NVcmkpOworICAgIHZlcmlmeShjb21wcmVzc1RyYW5zZm9ybSwgbmV2ZXIoKSkuZW5jb2RlKGVxUGFyYW0odXJpV2l0aENvbXByZXNzUGFyYW0pLCBhbnkoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBleGlzdHNfc2hvdWxkSW52b2tlVHJhbnNmb3JtRW5jb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyhmaWxlMUNvbXByZXNzVXJpKSkuaXNGYWxzZSgpOworICAgIHZlcmlmeShjb21wcmVzc1RyYW5zZm9ybSkuZW5jb2RlKGVxUGFyYW0odXJpV2l0aENvbXByZXNzUGFyYW0pLCBlcShmaWxlMUZpbGVuYW1lKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBleGlzdHNfc2hvdWxkTk9USW52b2tlVHJhbnNmb3JtRW5jb2RlT25EaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZXhpc3RzKGRpcjJDb21wcmVzc1VyaSkpLmlzRmFsc2UoKTsKKyAgICB2ZXJpZnkoY29tcHJlc3NUcmFuc2Zvcm0sIG5ldmVyKCkpLmVuY29kZShlcVBhcmFtKHVyaVdpdGhDb21wcmVzc1BhcmFtKSwgYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaXNEaXJlY3Rvcnlfc2hvdWxkTk9USW52b2tlVHJhbnNmb3JtRW5jb2RlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmlzRGlyZWN0b3J5KGZpbGUxQ29tcHJlc3NVcmkpKS5pc0ZhbHNlKCk7CisgICAgdmVyaWZ5KGNvbXByZXNzVHJhbnNmb3JtLCBuZXZlcigpKS5lbmNvZGUoZXFQYXJhbSh1cmlXaXRoQ29tcHJlc3NQYXJhbSksIGFueSgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNyZWF0ZURpcmVjdG9yeXNob3VsZE5PVEludm9rZVRyYW5zZm9ybUVuY29kZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN0b3JhZ2UuY3JlYXRlRGlyZWN0b3J5KGZpbGUxQ29tcHJlc3NVcmkpOworICAgIHZlcmlmeShjb21wcmVzc1RyYW5zZm9ybSwgbmV2ZXIoKSkuZW5jb2RlKGVxUGFyYW0odXJpV2l0aENvbXByZXNzUGFyYW0pLCBhbnkoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBmaWxlU2l6ZV9zaG91bGRJbnZva2VUcmFuc2Zvcm1FbmNvZGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZmlsZVNpemUoZmlsZTFDb21wcmVzc1VyaSkpLmlzRXF1YWxUbygwTCk7CisgICAgdmVyaWZ5KGNvbXByZXNzVHJhbnNmb3JtKS5lbmNvZGUoZXFQYXJhbSh1cmlXaXRoQ29tcHJlc3NQYXJhbSksIGVxKGZpbGUxRmlsZW5hbWUpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG11bHRpcGxlVHJhbnNmb3Jtc1Nob3VsZEJlRW5jb2RlZEZvcndhcmRBbmRDb21wb3NlZEluUmV2ZXJzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRoZSBzcGVjICJ0cmFuc2Zvcm09Y29tcHJlc3MrZW5jcnlwdCIgbWVhbnMgdGhlIGRhdGEgaXMgY29tcHJlc3NlZCBhbmQgdGhlbgorICAgIC8vIGVuY3J5cHRlZCBiZWZvcmUgc3RvcmVkLiBTaW5jZSB0cmFuc2Zvcm1zIGFyZSBpbXBsZW1lbnRlZCBieSB3cmFwcGluZyB0cmFuc2Zvcm1zLAorICAgIC8vIHRoZXkgbmVlZCB0byBiZSBpbnN0YW50aWF0ZWQgaW4gdGhlIHJldmVyc2Ugb3JkZXIuIFNvLCBpbiB0aGlzIGNhc2UsCisgICAgLy8gMS4gZW5jcnlwdCBpcyBpbnN0YW50aWF0ZWQKKyAgICAvLyAyLiBlbmNyeXB0IHdyYXBzIHRoZSBiYWNrZW5kIHN0cmVhbQorICAgIC8vIDMuIGNvbXByZXNzIGlzIGluc3RhbnRpYXRlZAorICAgIC8vIDQuIGNvbXByZXNzIHdyYXBzIHRoZSBlbmNyeXB0ZWQgc3RyZWFtCisgICAgLy8gNS4gdGhlIGNvbXByZXNzIHRyYW5zZm9ybXMgc3RyZWFtIGlzIHJldHVybmVkIHRvIHRoZSBjbGllbnQKKyAgICAvLyBJbiBjb250cmFzdCwgZW5jb2RlKCkgaXMgY2FsbGVkIGluIHRoZSBvcmRlciBpbiB3aGljaCB0cmFuc2Zvcm1zIGFwcGVhciBpbiB0aGUgZnJhZ21lbnQuCisKKyAgICB3aGVuKGVuY3J5cHRUcmFuc2Zvcm0ud3JhcEZvcldyaXRlKGVxUGFyYW0odXJpV2l0aEVuY3J5cHRQYXJhbSksIGFueShPdXRwdXRTdHJlYW0uY2xhc3MpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oZW5jcnlwdE91dHB1dFN0cmVhbSk7CisgICAgd2hlbihjb21wcmVzc1RyYW5zZm9ybS53cmFwRm9yV3JpdGUoZXFQYXJhbSh1cmlXaXRoQ29tcHJlc3NQYXJhbSksIGVxKGVuY3J5cHRPdXRwdXRTdHJlYW0pKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oY29tcHJlc3NPdXRwdXRTdHJlYW0pOworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IHN0b3JhZ2Uub3BlbihmaWxlMkNvbXByZXNzRW5jcnlwdFVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisKKyAgICAgIEluT3JkZXIgZm9yd2FyZCA9IGluT3JkZXIoY29tcHJlc3NUcmFuc2Zvcm0sIGVuY3J5cHRUcmFuc2Zvcm0pOworICAgICAgZm9yd2FyZC52ZXJpZnkoY29tcHJlc3NUcmFuc2Zvcm0pLmVuY29kZShlcVBhcmFtKHVyaVdpdGhDb21wcmVzc1BhcmFtKSwgZXEoZmlsZTJGaWxlbmFtZSkpOworICAgICAgZm9yd2FyZC52ZXJpZnkoZW5jcnlwdFRyYW5zZm9ybSkuZW5jb2RlKGVxUGFyYW0odXJpV2l0aEVuY3J5cHRQYXJhbSksIGVxKGZpbGUyRmlsZW5hbWUpKTsKKworICAgICAgSW5PcmRlciByZXZlcnNlID0gaW5PcmRlcihlbmNyeXB0VHJhbnNmb3JtLCBjb21wcmVzc1RyYW5zZm9ybSk7CisgICAgICByZXZlcnNlCisgICAgICAgICAgLnZlcmlmeShlbmNyeXB0VHJhbnNmb3JtKQorICAgICAgICAgIC53cmFwRm9yV3JpdGUoZXFQYXJhbSh1cmlXaXRoRW5jcnlwdFBhcmFtKSwgYW55KE91dHB1dFN0cmVhbS5jbGFzcykpOworICAgICAgcmV2ZXJzZQorICAgICAgICAgIC52ZXJpZnkoY29tcHJlc3NUcmFuc2Zvcm0pCisgICAgICAgICAgLndyYXBGb3JXcml0ZShlcVBhcmFtKHVyaVdpdGhDb21wcmVzc1BhcmFtKSwgZXEoZW5jcnlwdE91dHB1dFN0cmVhbSkpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNoaWxkcmVuX3Nob3VsZEludm9rZVRyYW5zZm9ybURlY29kZUluUmV2ZXJzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRoZSBzcGVjICJ0cmFuc2Zvcm09Y29tcHJlc3MrZW5jcnlwdCIgbWVhbnMgdGhlIGRhdGEgaXMgY29tcHJlc3NlZCBhbmQgdGhlbiBlbmNyeXB0ZWQuCisgICAgLy8gV2hlbiBsaXN0aW5nIGNoaWxkcmVuLCB0cmFuc2Zvcm0gZGVjb2RlcygpIGFyZSBpbnZva2VkIGluIHJldmVyc2UuCisKKyAgICB3aGVuKGZpbGVCYWNrZW5kLmNoaWxkcmVuKGVxKGZpbGUyVXJpKSkpLnRoZW5SZXR1cm4oQXJyYXlzLmFzTGlzdChVcmkucGFyc2UoImZpbGU6Ly8vY2hpbGQxIikpKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuY2hpbGRyZW4oZmlsZTJDb21wcmVzc0VuY3J5cHRVcmkpKS5pc05vdE51bGwoKTsKKworICAgIEluT3JkZXIgcmV2ZXJzZSA9IGluT3JkZXIoZW5jcnlwdFRyYW5zZm9ybSwgY29tcHJlc3NUcmFuc2Zvcm0pOworICAgIHJldmVyc2UudmVyaWZ5KGVuY3J5cHRUcmFuc2Zvcm0pLmRlY29kZShlcVBhcmFtKHVyaVdpdGhFbmNyeXB0UGFyYW0pLCBlcSgiY2hpbGQxIikpOworICAgIHJldmVyc2UudmVyaWZ5KGNvbXByZXNzVHJhbnNmb3JtKS5kZWNvZGUoZXFQYXJhbSh1cmlXaXRoQ29tcHJlc3NQYXJhbSksIGVxKCJjaGlsZDEiKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjaGlsZHJlbl90cmFuc2Zvcm1zU2hvdWxkTm90RGVjb2RlU3ViZGlyZWN0b3JpZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKGZpbGVCYWNrZW5kLmNoaWxkcmVuKGVxKGZpbGUxVXJpKSkpCisgICAgICAgIC50aGVuUmV0dXJuKAorICAgICAgICAgICAgQXJyYXlzLmFzTGlzdCgKKyAgICAgICAgICAgICAgICBVcmkucGFyc2UoImZpbGU6Ly8vZmlsZTEiKSwKKyAgICAgICAgICAgICAgICBVcmkucGFyc2UoImZpbGU6Ly8vZmlsZTIiKSwKKyAgICAgICAgICAgICAgICBVcmkucGFyc2UoImZpbGU6Ly8vZGlyMS8iKSkpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5jaGlsZHJlbihmaWxlMUNvbXByZXNzVXJpKSkuaXNOb3ROdWxsKCk7CisKKyAgICB2ZXJpZnkoY29tcHJlc3NUcmFuc2Zvcm0pLmRlY29kZShlcVBhcmFtKHVyaVdpdGhDb21wcmVzc1BhcmFtKSwgZXEoImZpbGUxIikpOworICAgIHZlcmlmeShjb21wcmVzc1RyYW5zZm9ybSkuZGVjb2RlKGVxUGFyYW0odXJpV2l0aENvbXByZXNzUGFyYW0pLCBlcSgiZmlsZTIiKSk7CisgICAgdmVyaWZ5KGNvbXByZXNzVHJhbnNmb3JtLCBuZXZlcigpKS5kZWNvZGUoZXFQYXJhbSh1cmlXaXRoQ29tcHJlc3NQYXJhbSksIGVxKCJkaXIxIikpOworICAgIHZlcmlmeShjb21wcmVzc1RyYW5zZm9ybSwgYXRMZWFzdCgxKSkubmFtZSgpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhjb21wcmVzc1RyYW5zZm9ybSk7CisgIH0KKworICAvLworICAvLyBNb25pdG9yIHN0dWZmCisgIC8vCisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVhZF9zaG91bGRNb25pdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9IHN0b3JhZ2Uub3BlbihmaWxlMVVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIHZlcmlmeShjb3VudGluZ01vbml0b3IpLm1vbml0b3JSZWFkKGZpbGUxVXJpKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB3cml0ZV9zaG91bGRNb25pdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gc3RvcmFnZS5vcGVuKGZpbGUxVXJpLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIHZlcmlmeShjb3VudGluZ01vbml0b3IpLm1vbml0b3JXcml0ZShmaWxlMVVyaSk7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYXBwZW5kX3Nob3VsZE1vbml0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB0cnkgKE91dHB1dFN0cmVhbSBvdXQgPSBzdG9yYWdlLm9wZW4oZmlsZTFVcmksIEFwcGVuZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIHZlcmlmeShjb3VudGluZ01vbml0b3IpLm1vbml0b3JBcHBlbmQoZmlsZTFVcmkpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlYWRXaXRoVHJhbnNmb3JtX3Nob3VsZEdldE9yaWdpbmFsVXJpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9IHN0b3JhZ2Uub3BlbihmaWxlMUNvbXByZXNzVXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgdmVyaWZ5KGNvdW50aW5nTW9uaXRvcikubW9uaXRvclJlYWQoZmlsZTFDb21wcmVzc1VyaSk7CisgICAgfQorICB9CisKKyAgLy8KKyAgLy8gTW9iU3RvcmVHYyBzdHVmZgorICAvLworCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdjTWV0aG9kc19zaG91bGRJbnZva2VDb3JyZXNwb25kaW5nQmFja2VuZE1ldGhvZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBHY1BhcmFtIHBhcmFtID0gR2NQYXJhbS5leHBpcmVzQXQobmV3IERhdGUoMUwpKTsKKyAgICBzdG9yYWdlLnNldEdjUGFyYW0oZmlsZTFVcmksIHBhcmFtKTsKKyAgICB2ZXJpZnkoZmlsZUJhY2tlbmQpLnNldEdjUGFyYW0oZXEoZmlsZTFVcmkpLCBlcShwYXJhbSkpOworICAgIHN0b3JhZ2UuZ2V0R2NQYXJhbShmaWxlMVVyaSk7CisgICAgdmVyaWZ5KGZpbGVCYWNrZW5kKS5nZXRHY1BhcmFtKGVxKGZpbGUxVXJpKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FjY291bnRTZXJpYWxpemF0aW9uVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQWNjb3VudFNlcmlhbGl6YXRpb25UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGVkMzA4NQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FjY291bnRTZXJpYWxpemF0aW9uVGVzdC5qYXZhCkBAIC0wLDAgKzEsODEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLmFjY291bnRzLkFjY291bnQ7CitpbXBvcnQgY29tLmdvb2dsZS50aGlyZHBhcnR5LnJvYm9sZWN0cmljLkdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CisKK0BSdW5XaXRoKEdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBBY2NvdW50U2VyaWFsaXphdGlvblRlc3QgeworCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHNoYXJlZEFjY291bnRfaXNTZXJpYWxpemVkQXNTaGFyZWQoKSB7CisgICAgU3RyaW5nIGFjY291bnRTdHIgPSBBY2NvdW50U2VyaWFsaXphdGlvbi5zZXJpYWxpemUoQWNjb3VudFNlcmlhbGl6YXRpb24uU0hBUkVEX0FDQ09VTlQpOworICAgIGFzc2VydFRoYXQoYWNjb3VudFN0cikuaXNFcXVhbFRvKCJzaGFyZWQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHNoYXJlZF9pc0Rlc2VyaWFsaXplZEFzU2hhcmVkQWNjb3VudCgpIHsKKyAgICBBY2NvdW50IGFjY291bnQgPSBBY2NvdW50U2VyaWFsaXphdGlvbi5kZXNlcmlhbGl6ZSgic2hhcmVkIik7CisgICAgYXNzZXJ0VGhhdChhY2NvdW50KS5pc0VxdWFsVG8oQWNjb3VudFNlcmlhbGl6YXRpb24uU0hBUkVEX0FDQ09VTlQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZGVzZXJpYWxpemVfd2l0aEVtcHR5QWNjb3VudE5hbWUoKSB7CisgICAgU3RyaW5nIGFjY291bnRTdHIgPSAiZ29vZ2xlLmNvbToiOworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBY2NvdW50U2VyaWFsaXphdGlvbi5kZXNlcmlhbGl6ZShhY2NvdW50U3RyKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZXNlcmlhbGl6ZV93aXRoRW1wdHlBY2NvdW50VHlwZSgpIHsKKyAgICBTdHJpbmcgYWNjb3VudFN0ciA9ICI6PGludGVybmFsPkBnbWFpbC5jb20iOworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBY2NvdW50U2VyaWFsaXphdGlvbi5kZXNlcmlhbGl6ZShhY2NvdW50U3RyKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkZXNlcmlhbGl6ZV93aXRoTWFsZm9ybWVkQWNjb3VudCgpIHsKKyAgICBTdHJpbmcgYWNjb3VudFN0ciA9ICJNQUxGT1JNRUQiOworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBY2NvdW50U2VyaWFsaXphdGlvbi5kZXNlcmlhbGl6ZShhY2NvdW50U3RyKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzZXJpYWxpemVfdmFsaWRhdGVzQWNjb3VudCgpIHsKKyAgICBBY2NvdW50U2VyaWFsaXphdGlvbi5zZXJpYWxpemUoQWNjb3VudFNlcmlhbGl6YXRpb24uU0hBUkVEX0FDQ09VTlQpOworICAgIEFjY291bnRTZXJpYWxpemF0aW9uLnNlcmlhbGl6ZShuZXcgQWNjb3VudCgiPGludGVybmFsPkBnbWFpbC5jb20iLCAiZ29vZ2xlLmNvbSIpKTsKKworICAgIC8vIEFuZHJvaWQgYWNjb3VudCBhbHJlYWR5IGRvZXMgc29tZSB2YWxpZGF0aW9uCisgICAgYXNzZXJ0VGhyb3dzKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gbmV3IEFjY291bnQoIiIsICIiKSk7CisgICAgYXNzZXJ0VGhyb3dzKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gbmV3IEFjY291bnQoIiIsICJnb29nbGUuY29tIikpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IG5ldyBBY2NvdW50KCI8aW50ZXJuYWw+QGdtYWlsLmNvbSIsICIiKSk7CisgICAgQWNjb3VudCB0eXBlV2l0aENvbG9uID0gbmV3IEFjY291bnQoIjxpbnRlcm5hbD5AZ21haWwuY29tIiwgInR5cGU6Iik7CisgICAgQWNjb3VudCB0eXBlV2l0aFNsYXNoID0gbmV3IEFjY291bnQoIjxpbnRlcm5hbD5AZ21haWwuY29tIiwgInR5cGUvIik7CisgICAgQWNjb3VudCBuYW1lV2l0aFNsYXNoID0gbmV3IEFjY291bnQoInlvdS9lbWFpbC5jb20iLCAiZ29vZ2xlLmNvbSIpOworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBY2NvdW50U2VyaWFsaXphdGlvbi5zZXJpYWxpemUodHlwZVdpdGhDb2xvbikpOworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBY2NvdW50U2VyaWFsaXphdGlvbi5zZXJpYWxpemUodHlwZVdpdGhTbGFzaCkpOworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBY2NvdW50U2VyaWFsaXphdGlvbi5zZXJpYWxpemUobmFtZVdpdGhTbGFzaCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BbmRyb2lkRmlsZUJhY2tlbmRUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BbmRyb2lkRmlsZUJhY2tlbmRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjFjODkxMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FuZHJvaWRGaWxlQmFja2VuZFRlc3QuamF2YQpAQCAtMCwwICsxLDI3NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLmNyZWF0ZUZpbGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMubWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQ7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMucmVhZEZpbGVJbkJ5dGVzOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ubW9jazsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ud2hlbjsKKworaW1wb3J0IGFuZHJvaWQuYWNjb3VudHMuQWNjb3VudDsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZDsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkZpbGVTdG9yYWdlVW5hdmFpbGFibGVFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uTG9ja1Njb3BlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLk1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkJhY2tlbmRUZXN0QmFzZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuTmF0aXZlUmVhZE9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuUmVhZFN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5CYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuYW5ub3RhdGlvbi5Db25maWc7CisKKy8qKiBUZXN0cyBmb3Ige0BsaW5rIEFuZHJvaWRGaWxlQmFja2VuZH0gKi8KK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK0BDb25maWcoc2RrID0gQnVpbGQuVkVSU0lPTl9DT0RFUy5OKQorcHVibGljIGNsYXNzIEFuZHJvaWRGaWxlQmFja2VuZFRlc3QgZXh0ZW5kcyBCYWNrZW5kVGVzdEJhc2UgeworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKyAgcHJpdmF0ZSBmaW5hbCBCYWNrZW5kIGJhY2tlbmQgPSBBbmRyb2lkRmlsZUJhY2tlbmQuYnVpbGRlcihjb250ZXh0KS5idWlsZCgpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBieXRlW10gVEVTVF9DT05URU5UID0gbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoKTsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIEJhY2tlbmQgYmFja2VuZCgpIHsKKyAgICByZXR1cm4gYmFja2VuZDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgVXJpIGxlZ2FsVXJpQmFzZSgpIHsKKyAgICByZXR1cm4gVXJpLnBhcnNlKCJhbmRyb2lkOi8vIiArIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSArICIvZmlsZXMvY29tbW9uL3NoYXJlZC8iKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgTGlzdDxVcmk+IGlsbGVnYWxVcmlzVG9SZWFkKCkgeworICAgIHJldHVybiBJbW11dGFibGVMaXN0Lm9mKAorICAgICAgICBVcmkucGFyc2UobGVnYWxVcmlCYXNlKCkgKyAidXJpV2l0aFF1ZXJ5P3E9YSIpLAorICAgICAgICBVcmkucGFyc2UoImFuZHJvaWQ6Ly8vbnVsbC91cmlXaXRoSW52YWxpZExvZ2ljYWxMb2NhdGlvbiIpLAorICAgICAgICBVcmkucGFyc2UoImFuZHJvaWQ6Ly8iICsgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKSwKKyAgICAgICAgVXJpLnBhcnNlKCJhbmRyb2lkOi8vIiArIGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBMaXN0PFVyaT4gaWxsZWdhbFVyaXNUb1dyaXRlKCkgeworICAgIHJldHVybiBJbW11dGFibGVMaXN0Lm9mKAorICAgICAgICBVcmkucGFyc2UoImFuZHJvaWQ6Ly9jb20udGhpcmRwYXJ0eS5hcHAvZmlsZXMvY29tbW9uL3NoYXJlZC91cmlBY3Jvc3NBdXRob3JpdHkiKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIExpc3Q8VXJpPiBpbGxlZ2FsVXJpc1RvQXBwZW5kKCkgeworICAgIHJldHVybiBpbGxlZ2FsVXJpc1RvV3JpdGUoKTsKKyAgfQorCisgIC8qKiBNaW5pbWFsIHRlc3RzIHZlcmlmeWluZyBkZWZhdWx0IGJ1aWxkZXIgYmVoYXZpb3IgKi8KKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl93aXRoTnVsbENvbnRleHRfc2hvdWxkVGhyb3dFeGNlcHRpb24oKSB7CisgICAgYXNzZXJ0VGhyb3dzKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIobnVsbCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9yZW1vdGVCYWNrZW5kX2lzTnVsbEJ5RGVmYXVsdCgpIHsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJhbmRyb2lkOi8vY29tLnRoaXJkcGFydHkuYXBwL2ZpbGVzL2NvbW1vbi9zaGFyZWQvZmlsZSIpOworICAgIEFuZHJvaWRGaWxlQmFja2VuZCBiYWNrZW5kID0gQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuYnVpbGQoKTsKKyAgICBhc3NlcnRUaHJvd3MoRmlsZVN0b3JhZ2VVbmF2YWlsYWJsZUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gYmFja2VuZC5vcGVuRm9yUmVhZCh1cmkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfYWNjb3VudE1hbmFnZXJfaXNOdWxsQnlEZWZhdWx0KCkgeworICAgIEFjY291bnQgYWNjb3VudCA9IG5ldyBBY2NvdW50KCI8aW50ZXJuYWw+QGdtYWlsLmNvbSIsICJnb29nbGUuY29tIik7CisgICAgVXJpIHVyaSA9IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRNYW5hZ2VkTG9jYXRpb24oKS5zZXRBY2NvdW50KGFjY291bnQpLmJ1aWxkKCk7CisgICAgQW5kcm9pZEZpbGVCYWNrZW5kIGJhY2tlbmQgPSBBbmRyb2lkRmlsZUJhY2tlbmQuYnVpbGRlcihjb250ZXh0KS5idWlsZCgpOworICAgIGFzc2VydFRocm93cyhNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsICgpIC0+IGJhY2tlbmQub3BlbkZvclJlYWQodXJpKSk7CisgIH0KKworICAvKiogVGVzdHMgdmVyaWZ5aW5nIGJhY2tlbmQgYmVoYXZpb3IgKi8KKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkZvcldyaXRlX3Nob3VsZFVzZUNvbnRleHRBdXRob3JpdHlJZldpdGhvdXRBdXRob3JpdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBVcmkgdXJpID0gVXJpLnBhcnNlKCJhbmRyb2lkOi8vL2ZpbGVzL3dyaXRpbmcvc2hhcmVkL21pc3NpbmdBdXRob3JpdHkiKTsKKworICAgIGFzc2VydFRoYXQoc3RvcmFnZSgpLmV4aXN0cyh1cmkpKS5pc0ZhbHNlKCk7CisKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UoKSwgdXJpLCBURVNUX0NPTlRFTlQpOworCisgICAgYXNzZXJ0VGhhdChzdG9yYWdlKCkuZXhpc3RzKHVyaSkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVJbkJ5dGVzKHN0b3JhZ2UoKSwgdXJpKSkuaXNFcXVhbFRvKFRFU1RfQ09OVEVOVCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZW5hbWVfc2hvdWxkTm90UmVuYW1lQWNyb3NzQXV0aG9yaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmluYWwgVXJpIGZyb20gPQorICAgICAgICBVcmkucGFyc2UoImFuZHJvaWQ6Ly8iICsgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpICsgIi9maWxlcy9sb2NhbGZyb20vc2hhcmVkL2ZpbGUiKTsKKyAgICBmaW5hbCBVcmkgdG8gPSBVcmkucGFyc2UoImFuZHJvaWQ6Ly9jb20udGhpcmRwYXJ0eS5hcHAvZmlsZXMvcmVtb3RldG8vc2hhcmVkL2ZpbGUiKTsKKworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSgpLCBmcm9tLCBURVNUX0NPTlRFTlQpOworCisgICAgYXNzZXJ0VGhhdChzdG9yYWdlKCkuZXhpc3RzKGZyb20pKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaHJvd3MoTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlKCkucmVuYW1lKGZyb20sIHRvKSk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlKCkuZXhpc3RzKGZyb20pKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlSW5CeXRlcyhzdG9yYWdlKCksIGZyb20pKS5pc0VxdWFsVG8oVEVTVF9DT05URU5UKTsKKyAgfQorCisgIEBUZXN0CisgIEBDb25maWcoc2RrID0gQnVpbGQuVkVSU0lPTl9DT0RFUy5OKQorICBwdWJsaWMgdm9pZCBvcGVuRm9yUmVhZF9kaXJlY3RCb290RmlsZXNPbk5TaG91bGRVc2VEZXZpY2VQcm90ZWN0ZWRTdG9yYWdlQ29udGV4dCgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0KKyAgICAgICAgQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpCisgICAgICAgICAgICAuc2V0RGlyZWN0Qm9vdEZpbGVzTG9jYXRpb24oKQorICAgICAgICAgICAgLnNldE1vZHVsZSgidGVzdGJvb3QiKQorICAgICAgICAgICAgLnNldFJlbGF0aXZlUGF0aCgiaW5EaXJlY3RCb290LnR4dCIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBGaWxlIGRpcmVjdEJvb3RGaWxlID0KKyAgICAgICAgbmV3IEZpbGUoCisgICAgICAgICAgICBjb250ZXh0LmNyZWF0ZURldmljZVByb3RlY3RlZFN0b3JhZ2VDb250ZXh0KCkuZ2V0RmlsZXNEaXIoKSwKKyAgICAgICAgICAgICJ0ZXN0Ym9vdC9zaGFyZWQvaW5EaXJlY3RCb290LnR4dCIpOworICAgIEZpbGUgZmlsZXNGaWxlID0gbmV3IEZpbGUoY29udGV4dC5nZXRGaWxlc0RpcigpLCAidGVzdGJvb3Qvc2hhcmVkL2luRGlyZWN0Qm9vdC50eHQiKTsKKworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSgpLCB1cmksIFRFU1RfQ09OVEVOVCk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVzRmlsZS5leGlzdHMoKSkuaXNGYWxzZSgpOworICAgIGFzc2VydFRoYXQoZGlyZWN0Qm9vdEZpbGUuZXhpc3RzKCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVJbkJ5dGVzKHN0b3JhZ2UoKSwgdXJpKSkuaXNFcXVhbFRvKFRFU1RfQ09OVEVOVCk7CisgIH0KKworICBAVGVzdAorICBAQ29uZmlnKHNkayA9IEJ1aWxkLlZFUlNJT05fQ09ERVMuTikKKyAgcHVibGljIHZvaWQgb3BlbkZvclJlYWRfZGlyZWN0Qm9vdENhY2hlT25OU2hvdWxkVXNlRGV2aWNlUHJvdGVjdGVkU3RvcmFnZUNvbnRleHQoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9CisgICAgICAgIEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KQorICAgICAgICAgICAgLnNldERpcmVjdEJvb3RDYWNoZUxvY2F0aW9uKCkKKyAgICAgICAgICAgIC5zZXRNb2R1bGUoInRlc3Rib290IikKKyAgICAgICAgICAgIC5zZXRSZWxhdGl2ZVBhdGgoImluRGlyZWN0Qm9vdC50eHQiKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgRmlsZSBkaXJlY3RCb290RmlsZSA9CisgICAgICAgIG5ldyBGaWxlKAorICAgICAgICAgICAgY29udGV4dC5jcmVhdGVEZXZpY2VQcm90ZWN0ZWRTdG9yYWdlQ29udGV4dCgpLmdldENhY2hlRGlyKCksCisgICAgICAgICAgICAidGVzdGJvb3Qvc2hhcmVkL2luRGlyZWN0Qm9vdC50eHQiKTsKKyAgICBGaWxlIGNhY2hlRmlsZSA9IG5ldyBGaWxlKGNvbnRleHQuZ2V0Q2FjaGVEaXIoKSwgInRlc3Rib290L3NoYXJlZC9pbkRpcmVjdEJvb3QudHh0Iik7CisKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UoKSwgdXJpLCBURVNUX0NPTlRFTlQpOworCisgICAgYXNzZXJ0VGhhdChjYWNoZUZpbGUuZXhpc3RzKCkpLmlzRmFsc2UoKTsKKyAgICBhc3NlcnRUaGF0KGRpcmVjdEJvb3RGaWxlLmV4aXN0cygpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlSW5CeXRlcyhzdG9yYWdlKCksIHVyaSkpLmlzRXF1YWxUbyhURVNUX0NPTlRFTlQpOworICB9CisKKyAgQFRlc3QKKyAgQENvbmZpZyhzZGsgPSBCdWlsZC5WRVJTSU9OX0NPREVTLk0pCisgIHB1YmxpYyB2b2lkIG9wZW5Gb3JSZWFkX2RpcmVjdEJvb3RGaWxlc0JlZm9yZU5TaG91bGRUaHJvd0V4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPQorICAgICAgICBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkKKyAgICAgICAgICAgIC5zZXREaXJlY3RCb290RmlsZXNMb2NhdGlvbigpCisgICAgICAgICAgICAuc2V0TW9kdWxlKCJ0ZXN0Ym9vdCIpCisgICAgICAgICAgICAuc2V0UmVsYXRpdmVQYXRoKCJpbkRpcmVjdEJvb3QudHh0IikKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0VGhyb3dzKE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc3RvcmFnZSgpLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSk7CisgIH0KKworICBAVGVzdAorICBAQ29uZmlnKHNkayA9IEJ1aWxkLlZFUlNJT05fQ09ERVMuTSkKKyAgcHVibGljIHZvaWQgb3BlbkZvclJlYWRfZGlyZWN0Qm9vdENhY2hlQmVmb3JlTlNob3VsZFRocm93RXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9CisgICAgICAgIEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KQorICAgICAgICAgICAgLnNldERpcmVjdEJvb3RDYWNoZUxvY2F0aW9uKCkKKyAgICAgICAgICAgIC5zZXRNb2R1bGUoInRlc3Rib290IikKKyAgICAgICAgICAgIC5zZXRSZWxhdGl2ZVBhdGgoImluRGlyZWN0Qm9vdC50eHQiKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaHJvd3MoTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlKCkub3Blbih1cmksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5Gb3JSZWFkX3JlbW90ZUF1dGhvcml0eVNob3VsZFVzZVJlbW90ZUJhY2tlbmQoKQorICAgICAgdGhyb3dzIElPRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBCYWNrZW5kIHJlbW90ZUJhY2tlbmQgPSBtb2NrKEJhY2tlbmQuY2xhc3MpOworICAgIHdoZW4ocmVtb3RlQmFja2VuZC5vcGVuRm9yUmVhZChhbnkoVXJpLmNsYXNzKSkpCisgICAgICAgIC50aGVuUmV0dXJuKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSkpOworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgcmVtb3RlU3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgICAgICBBbmRyb2lkRmlsZUJhY2tlbmQuYnVpbGRlcihjb250ZXh0KS5zZXRSZW1vdGVCYWNrZW5kKHJlbW90ZUJhY2tlbmQpLmJ1aWxkKCkpKTsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJhbmRyb2lkOi8vY29tLnRoaXJkcGFydHkuYXBwL2ZpbGVzL3JlYWRpbmcvZmlsZSIpOworCisgICAgQ2xvc2VhYmxlIHVudXNlZCA9IHJlbW90ZVN0b3JhZ2Uub3Blbih1cmksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpOworCisgICAgdmVyaWZ5KHJlbW90ZUJhY2tlbmQpLm9wZW5Gb3JSZWFkKHVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRm9yTmF0aXZlUmVhZF9yZW1vdGVBdXRob3JpdHlTaG91bGRVc2VSZW1vdGVCYWNrZW5kKCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgQmFja2VuZCByZW1vdGVCYWNrZW5kID0gbW9jayhCYWNrZW5kLmNsYXNzKTsKKyAgICB3aGVuKHJlbW90ZUJhY2tlbmQub3BlbkZvck5hdGl2ZVJlYWQoYW55KFVyaS5jbGFzcykpKQorICAgICAgICAudGhlblJldHVybihQYWlyLmNyZWF0ZShVcmkucGFyc2UoImZkOjEyMyIpLCAoQ2xvc2VhYmxlKSBudWxsKSk7CisgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSByZW1vdGVTdG9yYWdlID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKAorICAgICAgICAgICAgICAgIEFuZHJvaWRGaWxlQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLnNldFJlbW90ZUJhY2tlbmQocmVtb3RlQmFja2VuZCkuYnVpbGQoKSkpOworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImFuZHJvaWQ6Ly9jb20udGhpcmRwYXJ0eS5hcHAvZmlsZXMvcmVhZGluZy9maWxlIik7CisKKyAgICBDbG9zZWFibGUgdW51c2VkID0gcmVtb3RlU3RvcmFnZS5vcGVuKHVyaSwgTmF0aXZlUmVhZE9wZW5lci5jcmVhdGUoKSk7CisKKyAgICB2ZXJpZnkocmVtb3RlQmFja2VuZCkub3BlbkZvck5hdGl2ZVJlYWQodXJpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGV4aXN0c19yZW1vdGVBdXRob3JpdHlTaG91bGRVc2VSZW1vdGVCYWNrZW5kKCkKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgQmFja2VuZCByZW1vdGVCYWNrZW5kID0gbW9jayhCYWNrZW5kLmNsYXNzKTsKKyAgICB3aGVuKHJlbW90ZUJhY2tlbmQuZXhpc3RzKGFueShVcmkuY2xhc3MpKSkudGhlblJldHVybih0cnVlKTsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHJlbW90ZVN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoCisgICAgICAgICAgICAgICAgQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuc2V0UmVtb3RlQmFja2VuZChyZW1vdGVCYWNrZW5kKS5idWlsZCgpKSk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiYW5kcm9pZDovL2NvbS50aGlyZHBhcnR5LmFwcC9maWxlcy9yZWFkaW5nL2ZpbGUiKTsKKworICAgIGFzc2VydFRoYXQocmVtb3RlU3RvcmFnZS5leGlzdHModXJpKSkuaXNUcnVlKCk7CisKKyAgICB2ZXJpZnkocmVtb3RlQmFja2VuZCkuZXhpc3RzKHVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBsb2NrU2NvcGVfcmV0dXJuc05vbk51bGxMb2NrU2NvcGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGFzc2VydFRoYXQoYmFja2VuZC5sb2NrU2NvcGUoKSkuaXNOb3ROdWxsKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBsb2NrU2NvcGVfY2FuQmVPdmVycmlkZGVuKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBMb2NrU2NvcGUgbG9ja1Njb3BlID0gbmV3IExvY2tTY29wZSgpOworICAgIEFuZHJvaWRGaWxlQmFja2VuZCBiYWNrZW5kID0KKyAgICAgICAgQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuc2V0TG9ja1Njb3BlKGxvY2tTY29wZSkuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGJhY2tlbmQubG9ja1Njb3BlKCkpLmlzU2FtZUluc3RhbmNlQXMobG9ja1Njb3BlKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQW5kcm9pZFVyaUFkYXB0ZXJUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BbmRyb2lkVXJpQWRhcHRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kN2YzZWM5Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQW5kcm9pZFVyaUFkYXB0ZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxNjIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ubW9jazsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by53aGVuOworCitpbXBvcnQgYW5kcm9pZC5hY2NvdW50cy5BY2NvdW50OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uTWFsZm9ybWVkVXJpRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUudGhpcmRwYXJ0eS5yb2JvbGVjdHJpYy5Hb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKKworLyoqIFRlc3Qge0BsaW5rIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuQW5kcm9pZFVyaUFkYXB0ZXJ9LiAqLworQFJ1bldpdGgoR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIEFuZHJvaWRVcmlBZGFwdGVyVGVzdCB7CisKKyAgcHJpdmF0ZSBBbmRyb2lkVXJpQWRhcHRlciBhZGFwdGVyID0KKyAgICAgIEFuZHJvaWRVcmlBZGFwdGVyLmZvckNvbnRleHQoQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKSk7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2hvdWxkR2VuZXJhdGVGaWxlRnJvbVVyaSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGUgZmlsZSA9IGFkYXB0ZXIudG9GaWxlKFVyaS5wYXJzZSgiYW5kcm9pZDovL3BhY2thZ2UvZmlsZXMvY29tbW9uL3NoYXJlZC9wYXRoIikpOworICAgIGFzc2VydFRoYXQoZmlsZS5nZXRQYXRoKCkpLmVuZHNXaXRoKCIvZmlsZXMvY29tbW9uL3NoYXJlZC9wYXRoIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzaG91bGRHZW5lcmF0ZUNhY2hlRnJvbVVyaSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGUgZmlsZSA9IGFkYXB0ZXIudG9GaWxlKFVyaS5wYXJzZSgiYW5kcm9pZDovL3BhY2thZ2UvY2FjaGUvY29tbW9uL3NoYXJlZC9wYXRoIikpOworICAgIGFzc2VydFRoYXQoZmlsZS5nZXRQYXRoKCkpLmVuZHNXaXRoKCIvY2FjaGUvY29tbW9uL3NoYXJlZC9wYXRoIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzaG91bGRHZW5lcmF0ZUZpbGVGcm9tRXh0ZXJuYWxMb2NhdGlvblVyaSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGUgZmlsZSA9IGFkYXB0ZXIudG9GaWxlKFVyaS5wYXJzZSgiYW5kcm9pZDovL3BhY2thZ2UvZXh0ZXJuYWwvY29tbW9uL3NoYXJlZC9wYXRoIikpOworICAgIGFzc2VydFRoYXQoZmlsZS5nZXRQYXRoKCkpLmVuZHNXaXRoKCIvZXh0ZXJuYWwtZmlsZXMvY29tbW9uL3NoYXJlZC9wYXRoIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtYW5hZ2VkTG9jYXRpb25fd2l0aFNoYXJlZEFjY291bnRfZG9lc05vdFJlcXVpcmVBY2NvdW50TWFuYWdlcigpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGUgZmlsZSA9IGFkYXB0ZXIudG9GaWxlKFVyaS5wYXJzZSgiYW5kcm9pZDovL3BhY2thZ2UvbWFuYWdlZC9jb21tb24vc2hhcmVkL3BhdGgiKSk7CisgICAgYXNzZXJ0VGhhdChmaWxlLmdldFBhdGgoKSkuZW5kc1dpdGgoIi9maWxlcy9tYW5hZ2VkL2NvbW1vbi9zaGFyZWQvcGF0aCIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbWFuYWdlZExvY2F0aW9uX3dpdGhBY2NvdW50X3JlcXVpcmVzQWNjb3VudE1hbmFnZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgKCkgLT4KKyAgICAgICAgICAgIGFkYXB0ZXIudG9GaWxlKAorICAgICAgICAgICAgICAgIFVyaS5wYXJzZSgiYW5kcm9pZDovL3BhY2thZ2UvbWFuYWdlZC9jb21tb24vZ29vZ2xlLmNvbSUzQXlvdSU0MGdtYWlsLmNvbS9wYXRoIikpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1hbmFnZWRMb2NhdGlvbl92YWxpZGF0ZXNBY2NvdW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQWNjb3VudE1hbmFnZXIgbW9ja01hbmFnZXIgPSBtb2NrKEFjY291bnRNYW5hZ2VyLmNsYXNzKTsKKyAgICBhZGFwdGVyID0KKyAgICAgICAgQW5kcm9pZFVyaUFkYXB0ZXIuZm9yQ29udGV4dChBcHBsaWNhdGlvblByb3ZpZGVyLmdldEFwcGxpY2F0aW9uQ29udGV4dCgpLCBtb2NrTWFuYWdlcik7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgKCkgLT4gYWRhcHRlci50b0ZpbGUoVXJpLnBhcnNlKCJhbmRyb2lkOi8vcGFja2FnZS9tYW5hZ2VkL2NvbW1vbi9pbnZhbGlkLWFjY291bnQvcGF0aCIpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtYW5hZ2VkTG9jYXRpb25fZG9lc05vdFJlcXVpcmVBY2NvdW50U2VnbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEFjY291bnRNYW5hZ2VyIG1vY2tNYW5hZ2VyID0gbW9jayhBY2NvdW50TWFuYWdlci5jbGFzcyk7CisgICAgYWRhcHRlciA9CisgICAgICAgIEFuZHJvaWRVcmlBZGFwdGVyLmZvckNvbnRleHQoQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKSwgbW9ja01hbmFnZXIpOworCisgICAgRmlsZSBmaWxlID0gYWRhcHRlci50b0ZpbGUoVXJpLnBhcnNlKCJhbmRyb2lkOi8vcGFja2FnZS9tYW5hZ2VkL2NvbW1vbi8iKSk7CisgICAgYXNzZXJ0VGhhdChmaWxlLmdldFBhdGgoKSkuZW5kc1dpdGgoIi9maWxlcy9tYW5hZ2VkL2NvbW1vbiIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbWFuYWdlZExvY2F0aW9uX29iZnVzY2F0ZXNBY2NvdW50U2VnbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEFjY291bnQgYWNjb3VudCA9IG5ldyBBY2NvdW50KCI8aW50ZXJuYWw+QGdtYWlsLmNvbSIsICJnb29nbGUuY29tIik7CisgICAgQWNjb3VudE1hbmFnZXIgbW9ja01hbmFnZXIgPSBtb2NrKEFjY291bnRNYW5hZ2VyLmNsYXNzKTsKKyAgICB3aGVuKG1vY2tNYW5hZ2VyLmdldEFjY291bnRJZChhY2NvdW50KSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSgxMjMpKTsKKworICAgIGFkYXB0ZXIgPQorICAgICAgICBBbmRyb2lkVXJpQWRhcHRlci5mb3JDb250ZXh0KEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCksIG1vY2tNYW5hZ2VyKTsKKworICAgIEZpbGUgZmlsZSA9CisgICAgICAgIGFkYXB0ZXIudG9GaWxlKAorICAgICAgICAgICAgVXJpLnBhcnNlKCJhbmRyb2lkOi8vcGFja2FnZS9tYW5hZ2VkL2NvbW1vbi9nb29nbGUuY29tJTNBeW91JTQwZ21haWwuY29tL3BhdGgiKSk7CisgICAgYXNzZXJ0VGhhdChmaWxlLmdldFBhdGgoKSkuZW5kc1dpdGgoIi9maWxlcy9tYW5hZ2VkL2NvbW1vbi8xMjMvcGF0aCIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaWdub3Jlc0ZyYWdtZW50QXRDYWxsZXJzUGVyaWwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZpbGUgPSBhZGFwdGVyLnRvRmlsZShVcmkucGFyc2UoImFuZHJvaWQ6Ly9wYWNrYWdlL2ZpbGVzL2NvbW1vbi9zaGFyZWQvcGF0aCNmcmFnbWVudCIpKTsKKyAgICBhc3NlcnRUaGF0KGZpbGUuZ2V0UGF0aCgpKS5lbmRzV2l0aCgiL2ZpbGVzL2NvbW1vbi9zaGFyZWQvcGF0aCIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVxdWlyZXNBbmRyb2lkU2NoZW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICgpIC0+CisgICAgICAgICAgICBBbmRyb2lkVXJpQWRhcHRlci52YWxpZGF0ZShVcmkucGFyc2UoIm5vdGFuZHJvaWQ6Ly9wYWNrYWdlL2ZpbGVzL2NvbW1vbi9zaGFyZWQvcGF0aCIpKSk7CisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICgpIC0+IGFkYXB0ZXIudG9GaWxlKFVyaS5wYXJzZSgibm90YW5kcm9pZDovL3BhY2thZ2UvZmlsZXMvY29tbW9uL3NoYXJlZC9wYXRoIikpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlcXVpcmVzUGF0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBbmRyb2lkVXJpQWRhcHRlci52YWxpZGF0ZShVcmkucGFyc2UoImFuZHJvaWQ6Ly8vIikpKTsKKyAgICBhc3NlcnRUaHJvd3MoTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBhZGFwdGVyLnRvRmlsZShVcmkucGFyc2UoImFuZHJvaWQ6Ly9wYWNrYWdlIikpKTsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gYWRhcHRlci50b0ZpbGUoVXJpLnBhcnNlKCJhbmRyb2lkOi8vcGFja2FnZS8iKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVxdWlyZXNWYWxpZExvZ2ljYWxMb2NhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAoKSAtPiBhZGFwdGVyLnRvRmlsZShVcmkucGFyc2UoImFuZHJvaWQ6Ly9wYWNrYWdlL2ludmFsaWQvY29tbW9uL3NoYXJlZC9wYXRoIikpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlcXVpcmVzRW1wdHlRdWVyeSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAoKSAtPgorICAgICAgICAgICAgQW5kcm9pZFVyaUFkYXB0ZXIudmFsaWRhdGUoCisgICAgICAgICAgICAgICAgVXJpLnBhcnNlKCJhbmRyb2lkOi8vcGFja2FnZS9maWxlcy9jb21tb24vc2hhcmVkL3BhdGg/cXVlcnkiKSkpOworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAoKSAtPiBhZGFwdGVyLnRvRmlsZShVcmkucGFyc2UoImFuZHJvaWQ6Ly9wYWNrYWdlL2ZpbGVzL2NvbW1vbi9zaGFyZWQvcGF0aD9xdWVyeSIpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzaG91bGREZWNvZGVQYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9CisgICAgICAgIFVyaS5wYXJzZSgKKyAgICAgICAgICAgICJhbmRyb2lkOi8vb3JnLnJvYm9sZWN0cmljLmRlZmF1bHQvZmlsZXMvY29tbW9uL2dvb2dsZS5jb20lM0F5b3UlNDBnbWFpbC5jb20vcGF0aCIpOworICAgIEZpbGUgZmlsZSA9IGFkYXB0ZXIudG9GaWxlKHVyaSk7CisgICAgYXNzZXJ0VGhhdChmaWxlLmdldFBhdGgoKSkuZW5kc1dpdGgoIi9maWxlcy9jb21tb24vZ29vZ2xlLmNvbTo8aW50ZXJuYWw+QGdtYWlsLmNvbS9wYXRoIik7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0FuZHJvaWRVcmlUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BbmRyb2lkVXJpVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0YTIzYTMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9BbmRyb2lkVXJpVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzMyIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLm1vY2s7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ud2hlbjsKKworaW1wb3J0IGFuZHJvaWQuYWNjb3VudHMuQWNjb3VudDsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZDsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkLlZFUlNJT05fQ09ERVM7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUudGhpcmRwYXJ0eS5yb2JvbGVjdHJpYy5Hb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuYW5ub3RhdGlvbi5Db25maWc7CisKKy8qKiBUZXN0IHtAbGluayBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRVcml9LiAqLworQFJ1bldpdGgoR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorQENvbmZpZygKKyAgICBzZGsgPSB7VkVSU0lPTl9DT0RFUy5NLCBWRVJTSU9OX0NPREVTLk4sIFZFUlNJT05fQ09ERVMuT30sCisgICAgc2hhZG93cyA9IHt9KQorcHVibGljIGZpbmFsIGNsYXNzIEFuZHJvaWRVcmlUZXN0IHsKKworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl91bnN1cHBvcnRlZExvY2F0aW9uU3VjaEFzQ2FjaGVfdGhyb3dzRXhjZXB0aW9uKCkgeworICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKGNvbnRleHQuZ2V0Q2FjaGVEaXIoKSwgImZpbGUiKTsKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuZnJvbUZpbGUoZmlsZSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9taXNzaW5nQWNjb3VudERpcmVjdG9yeV90aHJvd3NFeGNlcHRpb24oKSB7CisgICAgRmlsZSBmaWxlID0gbmV3IEZpbGUoQW5kcm9pZEZpbGVFbnZpcm9ubWVudC5nZXRGaWxlc0RpcldpdGhQcmVOV29ya2Fyb3VuZChjb250ZXh0KSwgIm1vZHVsZS8iKTsKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuZnJvbUZpbGUoZmlsZSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9maWxlc0xvY2F0aW9uKCkgeworICAgIFN0cmluZyBmaWxlUGF0aCA9ICJtb2R1bGUvc2hhcmVkL2RpcmVjdG9yeS9maWxlIjsKKyAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShBbmRyb2lkRmlsZUVudmlyb25tZW50LmdldEZpbGVzRGlyV2l0aFByZU5Xb3JrYXJvdW5kKGNvbnRleHQpLCBmaWxlUGF0aCk7CisKKyAgICBVcmkgdXJpID0gQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLmZyb21GaWxlKGZpbGUpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdCh1cmkuZ2V0U2NoZW1lKCkpLmlzRXF1YWxUbygiYW5kcm9pZCIpOworICAgIGFzc2VydFRoYXQodXJpLmdldEF1dGhvcml0eSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KHVyaS5nZXRQYXRoKCkpLmlzRXF1YWxUbygiL2ZpbGVzLyIgKyBmaWxlUGF0aCk7CisgICAgYXNzZXJ0VGhhdCh1cmkudG9TdHJpbmcoKSkKKyAgICAgICAgLmlzRXF1YWxUbygiYW5kcm9pZDovLyIgKyBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkgKyAiL2ZpbGVzLyIgKyBmaWxlUGF0aCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZGVyX2NhY2hlTG9jYXRpb24oKSB7CisgICAgU3RyaW5nIGZpbGVQYXRoID0gIm1vZHVsZS9zaGFyZWQvZGlyZWN0b3J5L2ZpbGUiOworICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKGNvbnRleHQuZ2V0Q2FjaGVEaXIoKSwgZmlsZVBhdGgpOworCisgICAgVXJpIHVyaSA9IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5mcm9tRmlsZShmaWxlKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQodXJpLmdldFNjaGVtZSgpKS5pc0VxdWFsVG8oImFuZHJvaWQiKTsKKyAgICBhc3NlcnRUaGF0KHVyaS5nZXRBdXRob3JpdHkoKSkuaXNFcXVhbFRvKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgYXNzZXJ0VGhhdCh1cmkuZ2V0UGF0aCgpKS5pc0VxdWFsVG8oIi9jYWNoZS8iICsgZmlsZVBhdGgpOworICAgIGFzc2VydFRoYXQodXJpLnRvU3RyaW5nKCkpCisgICAgICAgIC5pc0VxdWFsVG8oImFuZHJvaWQ6Ly8iICsgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpICsgIi9jYWNoZS8iICsgZmlsZVBhdGgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9maWxlc0xvY2F0aW9uX3dpdGhFbWFpbEFjY291bnQoKSB7CisgICAgU3RyaW5nIGZpbGVQYXRoID0gIm1vZHVsZS9nb29nbGUuY29tOjxpbnRlcm5hbD5AZ21haWwuY29tL2RpcmVjdG9yeS9maWxlIjsKKyAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShBbmRyb2lkRmlsZUVudmlyb25tZW50LmdldEZpbGVzRGlyV2l0aFByZU5Xb3JrYXJvdW5kKGNvbnRleHQpLCBmaWxlUGF0aCk7CisKKyAgICBVcmkgdXJpID0gQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLmZyb21GaWxlKGZpbGUpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdCh1cmkuZ2V0U2NoZW1lKCkpLmlzRXF1YWxUbygiYW5kcm9pZCIpOworICAgIGFzc2VydFRoYXQodXJpLmdldEF1dGhvcml0eSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KHVyaS5nZXRQYXRoKCkpLmlzRXF1YWxUbygiL2ZpbGVzLyIgKyBmaWxlUGF0aCk7CisgICAgYXNzZXJ0VGhhdCh1cmkudG9TdHJpbmcoKSkKKyAgICAgICAgLmlzRXF1YWxUbygiYW5kcm9pZDovLyIgKyBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkgKyAiL2ZpbGVzLyIgKyBVcmkuZW5jb2RlKGZpbGVQYXRoLCAiLyIpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfZmlsZXNMb2NhdGlvbl93aXRoRW1wdHlBY2NvdW50TmFtZSgpIHsKKyAgICBTdHJpbmcgZmlsZVBhdGggPSAibW9kdWxlL2dvb2dsZS5jb206L2RpcmVjdG9yeS9maWxlIjsKKyAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShBbmRyb2lkRmlsZUVudmlyb25tZW50LmdldEZpbGVzRGlyV2l0aFByZU5Xb3JrYXJvdW5kKGNvbnRleHQpLCBmaWxlUGF0aCk7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLmZyb21GaWxlKGZpbGUpLmJ1aWxkKCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9maWxlc0xvY2F0aW9uX3dpdGhFbXB0eUFjY291bnRUeXBlKCkgeworICAgIFN0cmluZyBmaWxlUGF0aCA9ICJtb2R1bGUvOjxpbnRlcm5hbD5AZ21haWwuY29tL2RpcmVjdG9yeS9maWxlIjsKKyAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShBbmRyb2lkRmlsZUVudmlyb25tZW50LmdldEZpbGVzRGlyV2l0aFByZU5Xb3JrYXJvdW5kKGNvbnRleHQpLCBmaWxlUGF0aCk7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLmZyb21GaWxlKGZpbGUpLmJ1aWxkKCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9maWxlc0xvY2F0aW9uX3dpdGhNYWxmb3JtZWRBY2NvdW50KCkgeworICAgIFN0cmluZyBmaWxlUGF0aCA9ICJtb2R1bGUvTUFMRk9STUVEL2RpcmVjdG9yeS9maWxlIjsKKyAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShBbmRyb2lkRmlsZUVudmlyb25tZW50LmdldEZpbGVzRGlyV2l0aFByZU5Xb3JrYXJvdW5kKGNvbnRleHQpLCBmaWxlUGF0aCk7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLmZyb21GaWxlKGZpbGUpLmJ1aWxkKCkpOworICB9CisKKyAgQFRlc3QKKyAgQENvbmZpZyhzZGsgPSBCdWlsZC5WRVJTSU9OX0NPREVTLk4pCisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfZGlyZWN0Qm9vdEZpbGVzRGlyZWN0b3J5KCkgeworICAgIFN0cmluZyBmaWxlUGF0aCA9ICJtb2R1bGUvc2hhcmVkL2RpcmVjdG9yeS9maWxlIjsKKyAgICBGaWxlIHJvb3QgPSBuZXcgRmlsZShBbmRyb2lkRmlsZUVudmlyb25tZW50LmdldERldmljZVByb3RlY3RlZERhdGFEaXIoY29udGV4dCksICJmaWxlcyIpOworICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKHJvb3QsIGZpbGVQYXRoKTsKKworICAgIFVyaSB1cmkgPSBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuZnJvbUZpbGUoZmlsZSkuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KHVyaS5nZXRTY2hlbWUoKSkuaXNFcXVhbFRvKCJhbmRyb2lkIik7CisgICAgYXNzZXJ0VGhhdCh1cmkuZ2V0QXV0aG9yaXR5KCkpLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIGFzc2VydFRoYXQodXJpLmdldFBhdGgoKSkuaXNFcXVhbFRvKCIvZGlyZWN0Ym9vdC1maWxlcy8iICsgZmlsZVBhdGgpOworICAgIGFzc2VydFRoYXQodXJpLnRvU3RyaW5nKCkpCisgICAgICAgIC5pc0VxdWFsVG8oImFuZHJvaWQ6Ly8iICsgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpICsgIi9kaXJlY3Rib290LWZpbGVzLyIgKyBmaWxlUGF0aCk7CisgIH0KKworICBAVGVzdAorICBAQ29uZmlnKHNkayA9IEJ1aWxkLlZFUlNJT05fQ09ERVMuTikKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9kaXJlY3RCb290Q2FjaGVEaXJlY3RvcnkoKSB7CisgICAgU3RyaW5nIGZpbGVQYXRoID0gIm1vZHVsZS9zaGFyZWQvZGlyZWN0b3J5L2ZpbGUiOworICAgIEZpbGUgcm9vdCA9IG5ldyBGaWxlKEFuZHJvaWRGaWxlRW52aXJvbm1lbnQuZ2V0RGV2aWNlUHJvdGVjdGVkRGF0YURpcihjb250ZXh0KSwgImNhY2hlIik7CisgICAgRmlsZSBmaWxlID0gbmV3IEZpbGUocm9vdCwgZmlsZVBhdGgpOworCisgICAgVXJpIHVyaSA9IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5mcm9tRmlsZShmaWxlKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQodXJpLmdldFNjaGVtZSgpKS5pc0VxdWFsVG8oImFuZHJvaWQiKTsKKyAgICBhc3NlcnRUaGF0KHVyaS5nZXRBdXRob3JpdHkoKSkuaXNFcXVhbFRvKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgYXNzZXJ0VGhhdCh1cmkuZ2V0UGF0aCgpKS5pc0VxdWFsVG8oIi9kaXJlY3Rib290LWNhY2hlLyIgKyBmaWxlUGF0aCk7CisgICAgYXNzZXJ0VGhhdCh1cmkudG9TdHJpbmcoKSkKKyAgICAgICAgLmlzRXF1YWxUbygiYW5kcm9pZDovLyIgKyBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkgKyAiL2RpcmVjdGJvb3QtY2FjaGUvIiArIGZpbGVQYXRoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfYWxsb3dzRW1wdHlSZWxhdGl2ZVBhdGgoKSB7CisgICAgU3RyaW5nIGZpbGVQYXRoID0gIm1vZHVsZS9zaGFyZWQvIjsKKyAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShBbmRyb2lkRmlsZUVudmlyb25tZW50LmdldEZpbGVzRGlyV2l0aFByZU5Xb3JrYXJvdW5kKGNvbnRleHQpLCBmaWxlUGF0aCk7CisgICAgVXJpIHVyaSA9IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5mcm9tRmlsZShmaWxlKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQodXJpLmdldFBhdGgoKSkuaXNFcXVhbFRvKCIvZmlsZXMvIiArIGZpbGVQYXRoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfdW5zdXBwb3J0ZWRNb2R1bGVfdGhyb3dzRXhjZXB0aW9uKCkgeworICAgIFN0cmluZyBmaWxlUGF0aCA9ICJzaGFyZWQvc2hhcmVkL2ZpbGUiOworICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKEFuZHJvaWRGaWxlRW52aXJvbm1lbnQuZ2V0RmlsZXNEaXJXaXRoUHJlTldvcmthcm91bmQoY29udGV4dCksIGZpbGVQYXRoKTsKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuZnJvbUZpbGUoZmlsZSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9mcm9tTWFuYWdlZFNoYXJlZEZpbGVfZG9lc05vdFJlcXVpcmVBY2NvdW50TWFuYWdlcigpIHsKKyAgICBTdHJpbmcgZmlsZVBhdGggPSAiL21hbmFnZWQvbW9kdWxlL3NoYXJlZC9maWxlIjsKKyAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShBbmRyb2lkRmlsZUVudmlyb25tZW50LmdldEZpbGVzRGlyV2l0aFByZU5Xb3JrYXJvdW5kKGNvbnRleHQpLCBmaWxlUGF0aCk7CisgICAgVXJpIHVyaSA9IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5mcm9tRmlsZShmaWxlKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQodXJpLmdldFBhdGgoKSkuaXNFcXVhbFRvKGZpbGVQYXRoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfZnJvbU1hbmFnZWRBY2NvdW50RmlsZV9yZXF1aXJlc0FjY291bnRNYW5hZ2VyKCkgeworICAgIFN0cmluZyBmaWxlUGF0aCA9ICIvbWFuYWdlZC9tb2R1bGUvMC9maWxlIjsKKyAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShBbmRyb2lkRmlsZUVudmlyb25tZW50LmdldEZpbGVzRGlyV2l0aFByZU5Xb3JrYXJvdW5kKGNvbnRleHQpLCBmaWxlUGF0aCk7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLmZyb21GaWxlKGZpbGUpLmJ1aWxkKCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9mcm9tTWFuYWdlZEZpbGVfcmVhZHNGcm9tQWNjb3VudE1hbmFnZXIoKSB7CisgICAgQWNjb3VudCBhY2NvdW50ID0gbmV3IEFjY291bnQoIjxpbnRlcm5hbD5AZ21haWwuY29tIiwgImdvb2dsZS5jb20iKTsKKyAgICBBY2NvdW50TWFuYWdlciBtb2NrTWFuYWdlciA9IG1vY2soQWNjb3VudE1hbmFnZXIuY2xhc3MpOworICAgIHdoZW4obW9ja01hbmFnZXIuZ2V0QWNjb3VudCgxMjMpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGFjY291bnQpKTsKKworICAgIFN0cmluZyBmaWxlUGF0aCA9ICIvbWFuYWdlZC9tb2R1bGUvMTIzL2ZpbGUiOworICAgIEZpbGUgZmlsZSA9IG5ldyBGaWxlKEFuZHJvaWRGaWxlRW52aXJvbm1lbnQuZ2V0RmlsZXNEaXJXaXRoUHJlTldvcmthcm91bmQoY29udGV4dCksIGZpbGVQYXRoKTsKKworICAgIFVyaSB1cmkgPSBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuZnJvbUZpbGUoZmlsZSwgbW9ja01hbmFnZXIpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChnZXRQYXRoRnJhZ21lbnQodXJpLCAyKSkuaXNFcXVhbFRvKCJnb29nbGUuY29tOjxpbnRlcm5hbD5AZ21haWwuY29tIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZGVyX2NvbXBvbmVudHNBcmVTZXRCeURlZmF1bHQoKSB7CisgICAgVXJpIHVyaSA9IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5idWlsZCgpOworICAgIGFzc2VydFRoYXQodXJpLmdldFNjaGVtZSgpKS5pc0VxdWFsVG8oImFuZHJvaWQiKTsKKyAgICBhc3NlcnRUaGF0KHVyaS5nZXRBdXRob3JpdHkoKSkuaXNFcXVhbFRvKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgYXNzZXJ0VGhhdCh1cmkuZ2V0UGF0aCgpKS5pc0VxdWFsVG8oIi9maWxlcy9jb21tb24vc2hhcmVkLyIpOworICAgIGFzc2VydFRoYXQodXJpLnRvU3RyaW5nKCkpCisgICAgICAgIC5pc0VxdWFsVG8oImFuZHJvaWQ6Ly8iICsgY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpICsgIi9maWxlcy9jb21tb24vc2hhcmVkLyIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9zZXRMb2NhdGlvbl9leHBlY3RlZFVzYWdlKCkgeworICAgIFVyaSB1cmkgPSBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0SW50ZXJuYWxMb2NhdGlvbigpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChnZXRQYXRoRnJhZ21lbnQodXJpLCAwKSkuaXNFcXVhbFRvKCJmaWxlcyIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9zZXRMb2NhdGlvbl9leHRlcm5hbExvY2F0aW9uKCkgeworICAgIFVyaSB1cmkgPSBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0RXh0ZXJuYWxMb2NhdGlvbigpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChnZXRQYXRoRnJhZ21lbnQodXJpLCAwKSkuaXNFcXVhbFRvKCJleHRlcm5hbCIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9zZXRMb2NhdGlvbl9tYW5hZ2VkKCkgeworICAgIFVyaSB1cmkgPSBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0TWFuYWdlZExvY2F0aW9uKCkuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGdldFBhdGhGcmFnbWVudCh1cmksIDApKS5pc0VxdWFsVG8oIm1hbmFnZWQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfc2V0TW9kdWxlX2V4cGVjdGVkVXNhZ2UoKSB7CisgICAgVXJpIHVyaSA9IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRNb2R1bGUoInRlc3Rtb2R1bGUiKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZ2V0UGF0aEZyYWdtZW50KHVyaSwgMSkpLmlzRXF1YWxUbygidGVzdG1vZHVsZSIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9zZXRNb2R1bGVfaXNWYWxpZGF0ZWQoKSB7CisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRNb2R1bGUoIiIpLmJ1aWxkKCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9zZXRNb2R1bGVfZG9lc05vdENvbGxpZGVXaXRoTWFuYWdlZExvY2F0aW9uKCkgeworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAoKSAtPiBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0TW9kdWxlKCJtYW5hZ2VkIikuYnVpbGQoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZGVyX3NoYXJlZEFjY291bnRfaXNTZXJpYWxpemVkQXNTaGFyZWQoKSB7CisgICAgVXJpIHVyaSA9IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRBY2NvdW50KEFuZHJvaWRVcmkuU0hBUkVEX0FDQ09VTlQpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChnZXRQYXRoRnJhZ21lbnQodXJpLCAyKSkuaXNFcXVhbFRvKCJzaGFyZWQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfc2V0QWNjb3VudF9pc1ZhbGlkYXRlZCgpIHsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgKCkgLT4gQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLnNldEFjY291bnQobmV3IEFjY291bnQoIiIsICIiKSkuYnVpbGQoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZGVyX3NldFJlbGF0aXZlUGF0aF9leHBlY3RlZFVzYWdlKCkgeworICAgIFVyaSB1cmkgPSBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0UmVsYXRpdmVQYXRoKCJ0ZXN0ZmlsZSIpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChnZXRQYXRoRnJhZ21lbnQodXJpLCAzKSkuaXNFcXVhbFRvKCJ0ZXN0ZmlsZSIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdmFsaWRhdGVMb2NhdGlvbl9vbmx5QWxsb3dzUGVybWl0dGVkTG9jYXRpb25zKCkgeworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVMb2NhdGlvbigiZmlsZXMiKTsKKyAgICBBbmRyb2lkVXJpLnZhbGlkYXRlTG9jYXRpb24oImNhY2hlIik7CisgICAgQW5kcm9pZFVyaS52YWxpZGF0ZUxvY2F0aW9uKCJleHRlcm5hbCIpOworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVMb2NhdGlvbigiZGlyZWN0Ym9vdC1maWxlcyIpOworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVMb2NhdGlvbigiZGlyZWN0Ym9vdC1jYWNoZSIpOworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVMb2NhdGlvbigibWFuYWdlZCIpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEFuZHJvaWRVcmkudmFsaWRhdGVMb2NhdGlvbigiIikpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEFuZHJvaWRVcmkudmFsaWRhdGVMb2NhdGlvbigib3RoZXIiKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB2YWxpZGF0ZU1vZHVsZV9kaXNhbGxvd3NSZXNlcnZlZE1vZHVsZXMoKSB7CisgICAgYXNzZXJ0VGhyb3dzKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQW5kcm9pZFVyaS52YWxpZGF0ZU1vZHVsZSgicmVzZXJ2ZWQiKSk7CisgICAgYXNzZXJ0VGhyb3dzKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQW5kcm9pZFVyaS52YWxpZGF0ZU1vZHVsZSgiUkVTRVJWRUQiKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB2YWxpZGF0ZU1vZHVsZV9hbGxvd3NOb25FbXB0eUxvd2VyY2FzZUxldHRlcnMoKSB7CisgICAgQW5kcm9pZFVyaS52YWxpZGF0ZU1vZHVsZSgiYSIpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEFuZHJvaWRVcmkudmFsaWRhdGVNb2R1bGUoIiIpKTsKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBbmRyb2lkVXJpLnZhbGlkYXRlTW9kdWxlKCJBIikpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEFuZHJvaWRVcmkudmFsaWRhdGVNb2R1bGUoIkFhIikpOworCisgICAgYXNzZXJ0VGhyb3dzKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQW5kcm9pZFVyaS52YWxpZGF0ZU1vZHVsZSgibXltb2R1bGUwIikpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEFuZHJvaWRVcmkudmFsaWRhdGVNb2R1bGUoIm15TW9kdWxlIikpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdmFsaWRhdGVNb2R1bGVfYWxsb3dzSW50ZXJsZWF2ZWRVbmRlcnNjb3JlcygpIHsKKyAgICBBbmRyb2lkVXJpLnZhbGlkYXRlTW9kdWxlKCJteW1vZHVsZSIpOworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVNb2R1bGUoIm15X21vZHVsZSIpOworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVNb2R1bGUoIm15X21vZHVsZV90d28iKTsKKworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEFuZHJvaWRVcmkudmFsaWRhdGVNb2R1bGUoIm15IG1vZHVsZSIpKTsKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBbmRyb2lkVXJpLnZhbGlkYXRlTW9kdWxlKCJteS1tb2R1bGUiKSk7CisKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBbmRyb2lkVXJpLnZhbGlkYXRlTW9kdWxlKCJteW1vZHVsZV8iKSk7CisgICAgYXNzZXJ0VGhyb3dzKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQW5kcm9pZFVyaS52YWxpZGF0ZU1vZHVsZSgiX215bW9kdWxlIikpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEFuZHJvaWRVcmkudmFsaWRhdGVNb2R1bGUoIm15X21vZHVsZV8iKSk7CisgICAgYXNzZXJ0VGhyb3dzKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQW5kcm9pZFVyaS52YWxpZGF0ZU1vZHVsZSgiX215X21vZHVsZSIpKTsKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBBbmRyb2lkVXJpLnZhbGlkYXRlTW9kdWxlKCJteV9fbW9kdWxlIikpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdmFsaWRhdGVSZWxhdGl2ZVBhdGhfaXNOb09wKCkgeworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVSZWxhdGl2ZVBhdGgoIiIpOworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVSZWxhdGl2ZVBhdGgoIm15RmlsZSIpOworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVSZWxhdGl2ZVBhdGgoIm15RGlyL215RmlsZSIpOworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVSZWxhdGl2ZVBhdGgoIm15RGlyLy4uL215RmlsZSIpOworICAgIEFuZHJvaWRVcmkudmFsaWRhdGVSZWxhdGl2ZVBhdGgoIi9teURpci9teUZpbGUiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfc2V0UGFja2FnZV9leHBlY3RlZFVzYWdlKCkgeworICAgIFVyaSB1cmkgPSBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0UGFja2FnZSgidGVzdHBhY2thZ2UiKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQodXJpLmdldEF1dGhvcml0eSgpKS5pc0VxdWFsVG8oInRlc3RwYWNrYWdlIik7CisgIH0KKworICAvKioKKyAgICogVXRpbGl0eSBtZXRob2QgdG8gZ2V0IHRoZSBpJ3RoIHBhdGggZnJhZ21lbnQgb2Yge0Bjb2RlIFVSSX0uIE1heSB0aHJvdyBleGNlcHRpb24gaWYgdGhlIFVSSSBpcworICAgKiBudWxsLCBpdHMgcGF0aCBpcyBudWxsLCBvciBpdCBkb2VzIG5vdCBoYXZlIHtAY29kZSBpbmRleH0gcGF0aCBmcmFnbWVudHMuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0UGF0aEZyYWdtZW50KFVyaSB1cmksIGludCBpbmRleCkgeworICAgIC8vIEEgdmFsaWQgcGF0aCBiZWdpbnMgd2l0aCAiLyIsIHNvICsxIGlzIHJlcXVpcmVkIHRvIG9mZnNldCB0aGUgZmlyc3Qgc3BsaXQgZWxlbWVudCAoIiIpCisgICAgcmV0dXJuIHVyaS5nZXRQYXRoKCkuc3BsaXQoIi8iKVtpbmRleCArIDFdOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9Bc3NldEZpbGVCYWNrZW5kVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQXNzZXRGaWxlQmFja2VuZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNmU1MjI0Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQXNzZXRGaWxlQmFja2VuZFRlc3QuamF2YQpAQCAtMCwwICsxLDc5IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuTmF0aXZlUmVhZE9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuUmVhZFN0cmluZ09wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuSlVuaXQ0OworCitAUnVuV2l0aChKVW5pdDQuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgQXNzZXRGaWxlQmFja2VuZFRlc3QgeworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHsKKyAgICBBc3NldEZpbGVCYWNrZW5kIGJhY2tlbmQgPSBBc3NldEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuYnVpbGQoKTsKKyAgICBzdG9yYWdlID0gbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoSW1tdXRhYmxlTGlzdC5vZihiYWNrZW5kKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRm9yUmVhZF9vcGVuc0VtYmVkZGVkRmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgcGF0aCA9IFVyaS5wYXJzZSgiYXNzZXQ6L0Fzc2V0RmlsZUJhY2tlbmRUZXN0LmphdmEiKTsKKyAgICBTdHJpbmcgY29udGVudHMgPSBzdG9yYWdlLm9wZW4ocGF0aCwgUmVhZFN0cmluZ09wZW5lci5jcmVhdGUoKSk7CisgICAgYXNzZXJ0VGhhdChjb250ZW50cykuY29udGFpbnMoIkFzc2V0RmlsZUJhY2tlbmRUZXN0Iik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBmaWxlU2l6ZV9vcGVuc0VtYmVkZGVkRmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgcGF0aCA9IFVyaS5wYXJzZSgiYXNzZXQ6L0Fzc2V0RmlsZUJhY2tlbmRUZXN0LmphdmEiKTsKKyAgICBMb25nIHNpemUgPSBzdG9yYWdlLmZpbGVTaXplKHBhdGgpOworICAgIGFzc2VydFRoYXQoc2l6ZSkuaXNHcmVhdGVyVGhhbigwKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5Gb3JSZWFkX2hhbmRsZXNNaXNzaW5nQXNzZXRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHBhdGggPSBVcmkucGFyc2UoImFzc2V0Oi9ET0VTX05PVF9FWElTVCIpOworICAgIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc3RvcmFnZS5vcGVuKHBhdGgsIFJlYWRTdHJpbmdPcGVuZXIuY3JlYXRlKCkpKTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNNZXNzYWdlVGhhdCgpLmlzRXF1YWxUbygiRE9FU19OT1RfRVhJU1QiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5Gb3JOYXRpdmVSZWFkX2lzVW5zdXBwb3J0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgcGF0aCA9IFVyaS5wYXJzZSgiYXNzZXQ6L0Fzc2V0RmlsZUJhY2tlbmRUZXN0LmphdmEiKTsKKyAgICBVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uIGV4ID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+IHN0b3JhZ2Uub3BlbihwYXRoLCBOYXRpdmVSZWFkT3BlbmVyLmNyZWF0ZSgpKSk7CisgICAgYXNzZXJ0VGhhdChleCkuaGFzTWVzc2FnZVRoYXQoKS5pc0VxdWFsVG8oIk5hdGl2ZSByZWFkIG5vdCBzdXBwb3J0ZWQgKGIvMjEwNTQ2NDczKSIpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiZjMwYzQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9CVUlMRApAQCAtMCwwICsxLDI3NSBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfYmluYXJ5IiwgImFuZHJvaWRfaW5zdHJ1bWVudGF0aW9uX3Rlc3QiLCAiYW5kcm9pZF9sb2NhbF90ZXN0IikKK2xvYWQoIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nOmJ1aWxkX2RlZnMuYnpsIiwgImFuZHJvaWRfdGVzdF9tdWx0aV9hcGkiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJBY2NvdW50U2VyaWFsaXphdGlvblRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkFjY291bnRTZXJpYWxpemF0aW9uVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFjY291bnRfc2VyaWFsaXphdGlvbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpyb2JvbGVjdHJpYyIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkFuZHJvaWRGaWxlQmFja2VuZFRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkFuZHJvaWRGaWxlQmFja2VuZFRlc3QuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczphY2NvdW50X21hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpuYXRpdmUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2RpcmVjdGJvb3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX3Rlc3RfbXVsdGlfYXBpKAorICAgIG5hbWUgPSAiQXNzZXRGaWxlQmFja2VuZFRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkFzc2V0RmlsZUJhY2tlbmRUZXN0LmphdmEiXSwKKyAgICBhc3NldHMgPSBbIjp0ZXN0X2Fzc2V0cyJdLAorICAgIGFzc2V0c19kaXIgPSAiYXNzZXRzIiwKKyAgICBtYW5pZmVzdCA9ICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlOkFuZHJvaWRNYW5pZmVzdC54bWwiLAorICAgIG11bHRpZGV4ID0gImxlZ2FjeSIsCisgICAgbm9jb21wcmVzc19leHRlbnNpb25zID0gWyJqYXZhIl0sCisgICAgdGFyZ2V0X2FwaXMgPSBbCisgICAgICAgICIyMyIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YXNzZXQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6bmF0aXZlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyaW5nIiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBqdW5pdCIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK0ZpbGVzZXQoCisgICAgbmFtZSA9ICJ0ZXN0X2Fzc2V0cyIsCisgICAgb3V0ID0gImFzc2V0cyIsCisgICAgZW50cmllcyA9IFsKKyAgICAgICAgRmlsZXNldEVudHJ5KGZpbGVzID0gWworICAgICAgICAgICAgIkFzc2V0RmlsZUJhY2tlbmRUZXN0LmphdmEiLAorICAgICAgICBdKSwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJBbmRyb2lkVXJpQWRhcHRlclRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkFuZHJvaWRVcmlBZGFwdGVyVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFjY291bnRfbWFuYWdlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczphbmRyb2lkX2FkYXB0ZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiQW5kcm9pZFVyaVRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkFuZHJvaWRVcmlUZXN0LmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YWNjb3VudF9tYW5hZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFuZHJvaWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZF9maWxlX2Vudmlyb25tZW50IiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9iaW5hcnkoCisgICAgbmFtZSA9ICJCbG9iU2hhcmluZ0JhY2tlbmRUZXN0X2FwcCIsCisgICAgdGVzdG9ubHkgPSAxLAorICAgIHNyY3MgPSBbIkJsb2JTdG9yZUJhY2tlbmRUZXN0LmphdmEiXSwKKyAgICBtYW5pZmVzdCA9ICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlOkFuZHJvaWRNYW5pZmVzdC54bWwiLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpibG9iX3VyaSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpibG9ic3RvcmVfYmFja2VuZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlX2Rlc2NyaXB0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpjaGFyc2V0cyIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9hbmRyb2lkX3Rlc3RpbmcvLzp0ZXN0cnVubmVyIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBqdW5pdCIsCisgICAgICAgICJAdHJ1dGgiLAorICAgICAgICAiQHViX3VpYXV0b21hdG9yIiwKKyAgICBdLAorKQorCithbmRyb2lkX2luc3RydW1lbnRhdGlvbl90ZXN0KAorICAgIG5hbWUgPSAiQmxvYlN0b3JlQmFja2VuZFRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHRpbWVvdXQgPSAibG9uZyIsCisgICAgc2hhcmRfY291bnQgPSAyLAorICAgIHRhcmdldF9kZXZpY2UgPSAiLy90b29scy9hbmRyb2lkL2VtdWxhdGVkX2RldmljZXMvZ2VuZXJpY19waG9uZTpnb29nbGVfMzBfeDg2IiwgICMgQmxvYiBTaGFyaW5nIGF2YWlsYWJsZSBpbiBSKworICAgIHRlc3RfYXBwID0gIjpCbG9iU2hhcmluZ0JhY2tlbmRUZXN0X2FwcCIsCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkJsb2JVcmlUZXN0IiwKKyAgICBzaXplID0gInNtYWxsIiwKKyAgICBzcmNzID0gWyJCbG9iVXJpVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmJsb2JfdXJpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkNvbnRlbnRSZXNvbHZlckJhY2tlbmRUZXN0IiwKKyAgICBzaXplID0gInNtYWxsIiwKKyAgICBzcmNzID0gWyJDb250ZW50UmVzb2x2ZXJCYWNrZW5kVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmNvbnRlbnRfcmVzb2x2ZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nOnJvYm9sZWN0cmljIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyZWFtIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF90ZXN0X211bHRpX2FwaSgKKyAgICBuYW1lID0gIkZpbGVEZXNjcmlwdG9yVXJpQW5kcm9pZFRlc3QiLAorICAgIHNpemUgPSAibGFyZ2UiLAorICAgIHNyY3MgPSBbIkZpbGVEZXNjcmlwdG9yVXJpQW5kcm9pZFRlc3QuamF2YSJdLAorICAgIG1hbmlmZXN0ID0gIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGU6QW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgdGFyZ2V0X2FwaXMgPSBbCisgICAgICAgICIyMyIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZV9kZXNjcmlwdG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICJAanVuaXQiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJGaWxlVXJpQWRhcHRlclRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkZpbGVVcmlBZGFwdGVyVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGVfYWRhcHRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJGaWxlVXJpVGVzdCIsCisgICAgc2l6ZSA9ICJzbWFsbCIsCisgICAgc3JjcyA9IFsiRmlsZVVyaVRlc3QuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiR2VuZXJpY1VyaUFkYXB0ZXJUZXN0IiwKKyAgICBzaXplID0gInNtYWxsIiwKKyAgICBzcmNzID0gWyJHZW5lcmljVXJpQWRhcHRlclRlc3QuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlX2FkYXB0ZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6Z2VuZXJpY19hZGFwdGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIk1lbW9yeUJhY2tlbmRUZXN0IiwKKyAgICBzaXplID0gInNtYWxsIiwKKyAgICBzcmNzID0gWyJNZW1vcnlCYWNrZW5kVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOm1lbW9yeSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJNZW1vcnlVcmlUZXN0IiwKKyAgICBzaXplID0gInNtYWxsIiwKKyAgICBzcmNzID0gWyJNZW1vcnlVcmlUZXN0LmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6bWVtb3J5IiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkphdmFGaWxlQmFja2VuZFRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkphdmFGaWxlQmFja2VuZFRlc3QuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJVcmlOb3JtYWxpemVyVGVzdCIsCisgICAgc2l6ZSA9ICJzbWFsbCIsCisgICAgc3JjcyA9IFsiVXJpTm9ybWFsaXplclRlc3QuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczp1cmlfbm9ybWFsaXplciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpyb2JvbGVjdHJpYyIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9CbG9iU3RvcmVCYWNrZW5kVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQmxvYlN0b3JlQmFja2VuZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMTcyMjA1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQmxvYlN0b3JlQmFja2VuZFRlc3QuamF2YQpAQCAtMCwwICsxLDI5NCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kczsKKworaW1wb3J0IHN0YXRpYyBhbmRyb2lkeC50ZXN0LnBsYXRmb3JtLmFwcC5JbnN0cnVtZW50YXRpb25SZWdpc3RyeS5nZXRJbnN0cnVtZW50YXRpb247CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsLkNoYXJzZXRzLlVURl84OworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKKworaW1wb3J0IGFuZHJvaWQuYXBwLmJsb2IuQmxvYlN0b3JlTWFuYWdlcjsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5QYXJjZWxGaWxlRGVzY3JpcHRvcjsKK2ltcG9ydCBhbmRyb2lkLnN1cHBvcnQudGVzdC51aWF1dG9tYXRvci5VaURldmljZTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5MaW1pdEV4Y2VlZGVkRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmlvLkJhc2VFbmNvZGluZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5CeXRlU3RyZWFtczsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLkZpbGVJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5zZWN1cml0eS5NZXNzYWdlRGlnZXN0OworaW1wb3J0IGphdmEudXRpbC5SYW5kb207CitpbXBvcnQgb3JnLmp1bml0LkFmdGVyOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLkpVbml0NDsKKworQFJ1bldpdGgoSlVuaXQ0LmNsYXNzKQorcHVibGljIGNsYXNzIEJsb2JTdG9yZUJhY2tlbmRUZXN0IHsKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIkJsb2JTdG9yZUJhY2tlbmRUZXN0IjsKKworICBwcml2YXRlIENvbnRleHQgY29udGV4dDsKKyAgcHJpdmF0ZSBCbG9iU3RvcmVCYWNrZW5kIGJhY2tlbmQ7CisgIHByaXZhdGUgQmxvYlN0b3JlTWFuYWdlciBibG9iU3RvcmVNYW5hZ2VyOworCisgIEBCZWZvcmUKKyAgcHVibGljIGZpbmFsIHZvaWQgc2V0VXBTdG9yYWdlKCkgeworICAgIGNvbnRleHQgPSBBcHBsaWNhdGlvblByb3ZpZGVyLmdldEFwcGxpY2F0aW9uQ29udGV4dCgpOworICAgIGJhY2tlbmQgPSBuZXcgQmxvYlN0b3JlQmFja2VuZChjb250ZXh0KTsKKyAgICBibG9iU3RvcmVNYW5hZ2VyID0gKEJsb2JTdG9yZU1hbmFnZXIpIGNvbnRleHQuZ2V0U3lzdGVtU2VydmljZShDb250ZXh0LkJMT0JfU1RPUkVfU0VSVklDRSk7CisgIH0KKworICBAQWZ0ZXIKKyAgcHVibGljIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDb21tYW5kcyB0byBjbGVhbiB1cCB0aGUgYmxvYiBzdG9yYWdlLgorICAgIHJ1blNoZWxsQ21kKCJjbWQgYmxvYl9zdG9yZSBjbGVhci1hbGwtc2Vzc2lvbnMiKTsKKyAgICBydW5TaGVsbENtZCgiY21kIGJsb2Jfc3RvcmUgY2xlYXItYWxsLWJsb2JzIik7CisgICAgY29udGV4dC5nZXRGaWxlc0RpcigpLmRlbGV0ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbmF0aXZlUmVhZEFmdGVyV3JpdGVfc3VjY2VlZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBieXRlW10gY29udGVudCA9ICJuYXRpdmVSZWFkQWZ0ZXJXcml0ZV9zdWNjZWVkcyIuZ2V0Qnl0ZXMoVVRGXzgpOworICAgIFN0cmluZyBjaGVja3N1bSA9IGNvbXB1dGVEaWdlc3QoY29udGVudCk7CisgICAgVXJpIHVyaSA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRCbG9iUGFyYW1ldGVycyhjaGVja3N1bSkuYnVpbGQoKTsKKyAgICBpbnQgbnVtT2ZMZWFzZXMgPSBibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkuc2l6ZSgpOworCisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gYmFja2VuZC5vcGVuRm9yV3JpdGUodXJpKSkgeworICAgICAgYXNzZXJ0VGhhdChvdXQpLmlzTm90TnVsbCgpOworICAgICAgb3V0LndyaXRlKGNvbnRlbnQpOworICAgIH0KKyAgICBhc3NlcnRUaGF0KGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKSkuaGFzU2l6ZShudW1PZkxlYXNlcyk7CisKKyAgICBVcmkgdXJpRm9yUmVhZCA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRCbG9iUGFyYW1ldGVycyhjaGVja3N1bSkuYnVpbGQoKTsKKyAgICBQYWlyPFVyaSwgQ2xvc2VhYmxlPiBjbG9zZWFibGVVcmkgPSBiYWNrZW5kLm9wZW5Gb3JOYXRpdmVSZWFkKHVyaUZvclJlYWQpOworICAgIGFzc2VydFRoYXQoY2xvc2VhYmxlVXJpLnNlY29uZCkuaXNOb3ROdWxsKCk7CisgICAgaW50IG5hdGl2ZUZkID0gRmlsZURlc2NyaXB0b3JVcmkuZ2V0RmQoY2xvc2VhYmxlVXJpLmZpcnN0KTsKKyAgICB0cnkgKElucHV0U3RyZWFtIGluID0KKyAgICAgICAgICAgIG5ldyBGaWxlSW5wdXRTdHJlYW0oUGFyY2VsRmlsZURlc2NyaXB0b3IuZnJvbUZkKG5hdGl2ZUZkKS5nZXRGaWxlRGVzY3JpcHRvcigpKTsKKyAgICAgICAgQ2xvc2VhYmxlIGMgPSBjbG9zZWFibGVVcmkuc2Vjb25kKSB7CisgICAgICBhc3NlcnRUaGF0KEJ5dGVTdHJlYW1zLnRvQnl0ZUFycmF5KGluKSkuaXNFcXVhbFRvKGNvbnRlbnQpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlYWRBZnRlcldyaXRlX3N1Y2NlZWRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIGNvbnRlbnQgPSAicmVhZEFmdGVyV3JpdGVfc3VjY2VlZHMiLmdldEJ5dGVzKFVURl84KTsKKyAgICBTdHJpbmcgY2hlY2tzdW0gPSBjb21wdXRlRGlnZXN0KGNvbnRlbnQpOworICAgIFVyaSB1cmkgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0QmxvYlBhcmFtZXRlcnMoY2hlY2tzdW0pLmJ1aWxkKCk7CisgICAgaW50IG51bU9mTGVhc2VzID0gYmxvYlN0b3JlTWFuYWdlci5nZXRMZWFzZWRCbG9icygpLnNpemUoKTsKKworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IGJhY2tlbmQub3BlbkZvcldyaXRlKHVyaSkpIHsKKyAgICAgIGFzc2VydFRoYXQob3V0KS5pc05vdE51bGwoKTsKKyAgICAgIG91dC53cml0ZShjb250ZW50KTsKKyAgICB9CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkpLmhhc1NpemUobnVtT2ZMZWFzZXMpOworCisgICAgVXJpIHVyaUZvclJlYWQgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0QmxvYlBhcmFtZXRlcnMoY2hlY2tzdW0pLmJ1aWxkKCk7CisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9IGJhY2tlbmQub3BlbkZvclJlYWQodXJpRm9yUmVhZCkpIHsKKyAgICAgIGFzc2VydFRoYXQoaW4pLmlzTm90TnVsbCgpOworICAgICAgYXNzZXJ0VGhhdChCeXRlU3RyZWFtcy50b0J5dGVBcnJheShpbikpLmlzRXF1YWxUbyhjb250ZW50KTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBleGlzdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBieXRlW10gY29udGVudCA9ICJleGlzdHMiLmdldEJ5dGVzKFVURl84KTsKKyAgICBTdHJpbmcgY2hlY2tzdW0gPSBjb21wdXRlRGlnZXN0KGNvbnRlbnQpOworICAgIFVyaSB1cmkgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0QmxvYlBhcmFtZXRlcnMoY2hlY2tzdW0pLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaGF0KGJhY2tlbmQuZXhpc3RzKHVyaSkpLmlzRmFsc2UoKTsKKworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IGJhY2tlbmQub3BlbkZvcldyaXRlKHVyaSkpIHsKKyAgICAgIGFzc2VydFRoYXQob3V0KS5pc05vdE51bGwoKTsKKyAgICAgIG91dC53cml0ZShjb250ZW50KTsKKyAgICB9CisKKyAgICBhc3NlcnRUaGF0KGJhY2tlbmQuZXhpc3RzKHVyaSkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd3JpdGVMZWFzZV9zdWNjZWVkcygpIHRocm93cyBFeGNlcHRpb24geworICAgIGJ5dGVbXSBjb250ZW50ID0gIndyaXRlTGVhc2Vfc3VjY2VlZHMiLmdldEJ5dGVzKFVURl84KTsKKyAgICBTdHJpbmcgY2hlY2tzdW0gPSBjb21wdXRlRGlnZXN0KGNvbnRlbnQpOworICAgIFVyaSBibG9iVXJpID0gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEJsb2JQYXJhbWV0ZXJzKGNoZWNrc3VtKS5idWlsZCgpOworICAgIGludCBudW1PZkxlYXNlcyA9IGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKS5zaXplKCk7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gYmFja2VuZC5vcGVuRm9yV3JpdGUoYmxvYlVyaSkpIHsKKyAgICAgIGFzc2VydFRoYXQob3V0KS5pc05vdE51bGwoKTsKKyAgICAgIG91dC53cml0ZShjb250ZW50KTsKKyAgICB9CisKKyAgICBVcmkgbGVhc2VVcmkgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0TGVhc2VQYXJhbWV0ZXJzKGNoZWNrc3VtLCAwKS5idWlsZCgpOworCisgICAgT3V0cHV0U3RyZWFtIG91dCA9IGJhY2tlbmQub3BlbkZvcldyaXRlKGxlYXNlVXJpKTsKKyAgICBhc3NlcnRUaGF0KG91dCkuaXNOdWxsKCk7CisKKyAgICBhc3NlcnRUaGF0KGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKSkuaGFzU2l6ZShudW1PZkxlYXNlcyArIDEpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd3JpdGVMZWFzZU5vbkV4aXN0ZW50RmlsZV9zaG91bGRUaHJvdygpIHRocm93cyBFeGNlcHRpb24geworICAgIGJ5dGVbXSBjb250ZW50ID0gIndyaXRlTGVhc2VOb25FeGlzdGVudEZpbGVfc2hvdWxkVGhyb3ciLmdldEJ5dGVzKFVURl84KTsKKyAgICBTdHJpbmcgY2hlY2tzdW0gPSBjb21wdXRlRGlnZXN0KGNvbnRlbnQpOworCisgICAgVXJpIHVyaSA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRMZWFzZVBhcmFtZXRlcnMoY2hlY2tzdW0sIDApLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaHJvd3MoU2VjdXJpdHlFeGNlcHRpb24uY2xhc3MsICgpIC0+IGJhY2tlbmQub3BlbkZvcldyaXRlKHVyaSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZGVsZXRlX3N1Y2NlZWRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYnl0ZVtdIGNvbnRlbnQgPSAiZGVsZXRlX3N1Y2NlZWRzIi5nZXRCeXRlcyhVVEZfOCk7CisgICAgU3RyaW5nIGNoZWNrc3VtID0gY29tcHV0ZURpZ2VzdChjb250ZW50KTsKKyAgICBVcmkgYmxvYlVyaSA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRCbG9iUGFyYW1ldGVycyhjaGVja3N1bSkuYnVpbGQoKTsKKyAgICBpbnQgbnVtT2ZMZWFzZXMgPSBibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkuc2l6ZSgpOworCisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gYmFja2VuZC5vcGVuRm9yV3JpdGUoYmxvYlVyaSkpIHsKKyAgICAgIGFzc2VydFRoYXQob3V0KS5pc05vdE51bGwoKTsKKyAgICAgIG91dC53cml0ZShjb250ZW50KTsKKyAgICB9CisKKyAgICBVcmkgbGVhc2VVcmkgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0TGVhc2VQYXJhbWV0ZXJzKGNoZWNrc3VtLCAwKS5idWlsZCgpOworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IGJhY2tlbmQub3BlbkZvcldyaXRlKGxlYXNlVXJpKSkgeworICAgICAgYXNzZXJ0VGhhdChvdXQpLmlzTnVsbCgpOworICAgIH0KKyAgICBhc3NlcnRUaGF0KGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKSkuaGFzU2l6ZShudW1PZkxlYXNlcyArIDEpOworCisgICAgYmFja2VuZC5kZWxldGVGaWxlKGxlYXNlVXJpKTsKKworICAgIGFzc2VydFRoYXQoYmxvYlN0b3JlTWFuYWdlci5nZXRMZWFzZWRCbG9icygpKS5oYXNTaXplKG51bU9mTGVhc2VzKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlbGVhc2VBbGxMZWFzZXNfc3VjY2VlZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSBhbmQgYWNxdWlyZSBsZWFzZSBvbiBmaXJzdCBmaWxlCisgICAgYnl0ZVtdIGNvbnRlbnQgPSAicmVsZWFzZUFsbExlYXNlc19zdWNjZWVkc18xIi5nZXRCeXRlcyhVVEZfOCk7CisgICAgU3RyaW5nIGNoZWNrc3VtID0gY29tcHV0ZURpZ2VzdChjb250ZW50KTsKKyAgICBVcmkgYmxvYlVyaSA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRCbG9iUGFyYW1ldGVycyhjaGVja3N1bSkuYnVpbGQoKTsKKyAgICBpbnQgbnVtT2ZMZWFzZXMgPSBibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkuc2l6ZSgpOworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IGJhY2tlbmQub3BlbkZvcldyaXRlKGJsb2JVcmkpKSB7CisgICAgICBhc3NlcnRUaGF0KG91dCkuaXNOb3ROdWxsKCk7CisgICAgICBvdXQud3JpdGUoY29udGVudCk7CisgICAgfQorICAgIFVyaSBsZWFzZVVyaSA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRMZWFzZVBhcmFtZXRlcnMoY2hlY2tzdW0sIDApLmJ1aWxkKCk7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gYmFja2VuZC5vcGVuRm9yV3JpdGUobGVhc2VVcmkpKSB7CisgICAgICBhc3NlcnRUaGF0KG91dCkuaXNOdWxsKCk7CisgICAgfQorICAgIGFzc2VydFRoYXQoYmxvYlN0b3JlTWFuYWdlci5nZXRMZWFzZWRCbG9icygpKS5oYXNTaXplKG51bU9mTGVhc2VzICsgMSk7CisKKyAgICAvLyBXcml0ZSBhbmQgYWNxdWlyZSBsZWFzZSBvbiBzZWNvbmQgZmlsZQorICAgIGNvbnRlbnQgPSAicmVsZWFzZUFsbExlYXNlc19zdWNjZWVkc18yIi5nZXRCeXRlcyhVVEZfOCk7CisgICAgY2hlY2tzdW0gPSBjb21wdXRlRGlnZXN0KGNvbnRlbnQpOworICAgIGJsb2JVcmkgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0QmxvYlBhcmFtZXRlcnMoY2hlY2tzdW0pLmJ1aWxkKCk7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0ID0gYmFja2VuZC5vcGVuRm9yV3JpdGUoYmxvYlVyaSkpIHsKKyAgICAgIGFzc2VydFRoYXQob3V0KS5pc05vdE51bGwoKTsKKyAgICAgIG91dC53cml0ZShjb250ZW50KTsKKyAgICB9CisgICAgbGVhc2VVcmkgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0TGVhc2VQYXJhbWV0ZXJzKGNoZWNrc3VtLCAwKS5idWlsZCgpOworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IGJhY2tlbmQub3BlbkZvcldyaXRlKGxlYXNlVXJpKSkgeworICAgICAgYXNzZXJ0VGhhdChvdXQpLmlzTnVsbCgpOworICAgIH0KKyAgICBhc3NlcnRUaGF0KGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKSkuaGFzU2l6ZShudW1PZkxlYXNlcyArIDIpOworCisgICAgLy8gUmVsZWFzZSBhbGwgbGVhc2VzCisgICAgVXJpIGFsbExlYXNlcyA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRBbGxMZWFzZXNQYXJhbWV0ZXJzKCkuYnVpbGQoKTsKKworICAgIGJhY2tlbmQuZGVsZXRlRmlsZShhbGxMZWFzZXMpOworCisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVNYW5hZ2VyLmdldExlYXNlZEJsb2JzKCkpLmlzRW1wdHkoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRlbGV0ZU5vbkV4aXN0ZW50RmlsZV9zaG91bGRUaHJvdygpIHRocm93cyBFeGNlcHRpb24geworICAgIEJsb2JTdG9yZUJhY2tlbmQgYmFja2VuZCA9IG5ldyBCbG9iU3RvcmVCYWNrZW5kKGNvbnRleHQpOworICAgIGJ5dGVbXSBjb250ZW50ID0gImRlbGV0ZU5vbkV4aXN0ZW50RmlsZV9zaG91bGRUaHJvdyIuZ2V0Qnl0ZXMoVVRGXzgpOworICAgIFN0cmluZyBjaGVja3N1bSA9IGNvbXB1dGVEaWdlc3QoY29udGVudCk7CisKKyAgICBVcmkgdXJpID0gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEJsb2JQYXJhbWV0ZXJzKGNoZWNrc3VtKS5idWlsZCgpOworCisgICAgYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBiYWNrZW5kLmRlbGV0ZUZpbGUodXJpKSk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgY29tcHV0ZURpZ2VzdChieXRlW10gYnl0ZUNvbnRlbnQpIHRocm93cyBFeGNlcHRpb24geworICAgIE1lc3NhZ2VEaWdlc3QgbWVzc2FnZURpZ2VzdCA9IE1lc3NhZ2VEaWdlc3QuZ2V0SW5zdGFuY2UoIlNIQS0yNTYiKTsKKyAgICBpZiAobWVzc2FnZURpZ2VzdCA9PSBudWxsKSB7CisgICAgICByZXR1cm4gIiI7CisgICAgfQorICAgIHJldHVybiBCYXNlRW5jb2RpbmcuYmFzZTE2KCkubG93ZXJDYXNlKCkuZW5jb2RlKG1lc3NhZ2VEaWdlc3QuZGlnZXN0KGJ5dGVDb250ZW50KSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB3cml0ZUxlYXNlRXhjZWVkc0xpbWl0X3Nob3VsZFRocm93KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgbG9uZyBpbml0aWFsUmVtYWluaW5nUXVvdGEgPSBibG9iU3RvcmVNYW5hZ2VyLmdldFJlbWFpbmluZ0xlYXNlUXVvdGFCeXRlcygpOworICAgIGludCBudW1PZkxlYXNlcyA9IGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKS5zaXplKCk7CisgICAgaW50IG51bWJlck9mRmlsZXMgPSAyMDsKKyAgICBpbnQgc2luZ2xlRmlsZVNpemUgPSAoaW50KSBpbml0aWFsUmVtYWluaW5nUXVvdGEgLyBudW1iZXJPZkZpbGVzOworICAgIGxvbmcgZXhwZWN0ZWRSZW1haW5pbmdRdW90YSA9IGluaXRpYWxSZW1haW5pbmdRdW90YSAtIHNpbmdsZUZpbGVTaXplICogbnVtYmVyT2ZGaWxlczsKKworICAgIC8vIENyZWF0ZSBzbWFsbCBmaWxlcyByYXRoZXIgdGhhbiBvbmUgYmlnIGZpbGUgdG8gYXZvaWQgT3V0T2ZNZW1vcnlFcnJvcgorICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtYmVyT2ZGaWxlczsgaSsrKSB7CisgICAgICBieXRlW10gY29udGVudCA9IGdlbmVyYXRlUmFuZG9tQnl0ZXMoc2luZ2xlRmlsZVNpemUpOworICAgICAgU3RyaW5nIGNoZWNrc3VtID0gY29tcHV0ZURpZ2VzdChjb250ZW50KTsKKyAgICAgIFVyaSBibG9iVXJpID0gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEJsb2JQYXJhbWV0ZXJzKGNoZWNrc3VtKS5idWlsZCgpOworCisgICAgICB0cnkgKE91dHB1dFN0cmVhbSBvdXQgPSBiYWNrZW5kLm9wZW5Gb3JXcml0ZShibG9iVXJpKSkgeworICAgICAgICBhc3NlcnRUaGF0KG91dCkuaXNOb3ROdWxsKCk7CisgICAgICAgIG91dC53cml0ZShjb250ZW50KTsKKyAgICAgIH0KKyAgICAgIFVyaSBsZWFzZVVyaSA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRMZWFzZVBhcmFtZXRlcnMoY2hlY2tzdW0sIDApLmJ1aWxkKCk7CisgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gYmFja2VuZC5vcGVuRm9yV3JpdGUobGVhc2VVcmkpOworICAgICAgYXNzZXJ0VGhhdChvdXQpLmlzTnVsbCgpOworICAgIH0KKyAgICBhc3NlcnRUaGF0KGJsb2JTdG9yZU1hbmFnZXIuZ2V0TGVhc2VkQmxvYnMoKSkuaGFzU2l6ZShudW1PZkxlYXNlcyArIG51bWJlck9mRmlsZXMpOworICAgIGFzc2VydFRoYXQoYmxvYlN0b3JlTWFuYWdlci5nZXRSZW1haW5pbmdMZWFzZVF1b3RhQnl0ZXMoKSkuaXNFcXVhbFRvKGV4cGVjdGVkUmVtYWluaW5nUXVvdGEpOworCisgICAgLy8gV3JpdGUgb25lIG1vcmUgZmlsZSBiaWdnZXIgdGhhbiBhdmFpbGFibGUgcXVvdGEuIEFjcXVpcmluZyB0aGUgbGVhc2Ugb24gaXQgd2lsbCB0aHJvdworICAgIC8vIExpbWl0RXhjZWVkZWRFeGNlcHRpb24uCisgICAgYnl0ZVtdIGNvbnRlbnQgPSBnZW5lcmF0ZVJhbmRvbUJ5dGVzKChpbnQpIGV4cGVjdGVkUmVtYWluaW5nUXVvdGEgKyAxKTsKKyAgICBTdHJpbmcgY2hlY2tzdW0gPSBjb21wdXRlRGlnZXN0KGNvbnRlbnQpOworICAgIFVyaSBibG9iVXJpID0gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEJsb2JQYXJhbWV0ZXJzKGNoZWNrc3VtKS5idWlsZCgpOworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IGJhY2tlbmQub3BlbkZvcldyaXRlKGJsb2JVcmkpKSB7CisgICAgICBhc3NlcnRUaGF0KG91dCkuaXNOb3ROdWxsKCk7CisgICAgICBvdXQud3JpdGUoY29udGVudCk7CisgICAgfQorICAgIFVyaSBleGNlZWRpbmdMZWFzZVVyaSA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRMZWFzZVBhcmFtZXRlcnMoY2hlY2tzdW0sIDApLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaHJvd3MoTGltaXRFeGNlZWRlZEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gYmFja2VuZC5vcGVuRm9yV3JpdGUoZXhjZWVkaW5nTGVhc2VVcmkpKTsKKworICAgIGFzc2VydFRoYXQoYmxvYlN0b3JlTWFuYWdlci5nZXRMZWFzZWRCbG9icygpKS5oYXNTaXplKG51bU9mTGVhc2VzICsgbnVtYmVyT2ZGaWxlcyk7CisgICAgYXNzZXJ0VGhhdChibG9iU3RvcmVNYW5hZ2VyLmdldFJlbWFpbmluZ0xlYXNlUXVvdGFCeXRlcygpKS5pc0VxdWFsVG8oZXhwZWN0ZWRSZW1haW5pbmdRdW90YSk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBieXRlW10gZ2VuZXJhdGVSYW5kb21CeXRlcyhpbnQgbGVuZ3RoKSB7CisgICAgYnl0ZVtdIGNvbnRlbnQgPSBuZXcgYnl0ZVtsZW5ndGhdOworICAgIG5ldyBSYW5kb20oKS5uZXh0Qnl0ZXMoY29udGVudCk7CisgICAgcmV0dXJuIGNvbnRlbnQ7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgcnVuU2hlbGxDbWQoU3RyaW5nIGNtZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBVaURldmljZSB1aURldmljZSA9IFVpRGV2aWNlLmdldEluc3RhbmNlKGdldEluc3RydW1lbnRhdGlvbigpKTsKKyAgICBmaW5hbCBTdHJpbmcgcmVzdWx0ID0gdWlEZXZpY2UuZXhlY3V0ZVNoZWxsQ29tbWFuZChjbWQpLnRyaW0oKTsKKyAgICBMb2cuaShUQUcsICJPdXRwdXQgb2YgJyIgKyBjbWQgKyAiJzogJyIgKyByZXN1bHQgKyAiJyIpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0Jsb2JVcmlUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9CbG9iVXJpVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ5N2FlY2IKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9CbG9iVXJpVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTQxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5NYWxmb3JtZWRVcmlFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uaW8uQmFzZUVuY29kaW5nOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgQmxvYlVyaVRlc3QgeworCisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZGVyX3NldENvcnJlY3RzUGFyYW1ldGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSBibG9iVXJpID0gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEJsb2JQYXJhbWV0ZXJzKCIxMjM0IikuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQoYmxvYlVyaS5nZXRTY2hlbWUoKSkuaXNFcXVhbFRvKCJibG9ic3RvcmUiKTsKKyAgICBhc3NlcnRUaGF0KGJsb2JVcmkuZ2V0QXV0aG9yaXR5KCkpLmlzRXF1YWxUbyhjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIGFzc2VydFRoYXQoYmxvYlVyaS5nZXRQYXRoKCkpLmlzRXF1YWxUbygiLzEyMzQiKTsKKyAgICBhc3NlcnRUaGF0KGJsb2JVcmkudG9TdHJpbmcoKSkKKyAgICAgICAgLmlzRXF1YWxUbygKKyAgICAgICAgICAgICJibG9ic3RvcmU6Ly9jb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLzEyMzQiKTsKKworICAgIFVyaSBsZWFzZVVyaSA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRBbGxMZWFzZXNQYXJhbWV0ZXJzKCkuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQobGVhc2VVcmkuZ2V0U2NoZW1lKCkpLmlzRXF1YWxUbygiYmxvYnN0b3JlIik7CisgICAgYXNzZXJ0VGhhdChsZWFzZVVyaS5nZXRBdXRob3JpdHkoKSkuaXNFcXVhbFRvKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgYXNzZXJ0VGhhdChsZWFzZVVyaS5nZXRQYXRoKCkpLmlzRXF1YWxUbygiLyoubGVhc2UiKTsKKyAgICBhc3NlcnRUaGF0KGxlYXNlVXJpLnRvU3RyaW5nKCkpCisgICAgICAgIC5pc0VxdWFsVG8oCisgICAgICAgICAgICAiYmxvYnN0b3JlOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy8qLmxlYXNlIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZGVyX2VtcHR5Q2hlY2tzdW1fc2hvdWxkVGhyb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldEJsb2JQYXJhbWV0ZXJzKCIiKS5idWlsZCgpKTsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgKCkgLT4gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldExlYXNlUGFyYW1ldGVycygiIiwgMSkuYnVpbGQoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB2YWxpZGF0ZVVyaV93cm9uZ051bWJlck9mU2VnbWVudHNfc2hvdWxkVGhyb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgaW52YWxpZFVyaSA9CisgICAgICAgIEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KQorICAgICAgICAgICAgLnNldEJsb2JQYXJhbWV0ZXJzKCIxMjM0IikKKyAgICAgICAgICAgIC5idWlsZCgpCisgICAgICAgICAgICAuYnVpbGRVcG9uKCkKKyAgICAgICAgICAgIC5hcHBlbmRQYXRoKCJuZXdTZWdtZW50IikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRocm93cyhNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsICgpIC0+IEJsb2JVcmkudmFsaWRhdGVVcmkoaW52YWxpZFVyaSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdmFsaWRhdGVVcmlfYWxsb3dPbmx5UGVybWl0dGVkQ2hlY2tzdW1FeHRlbnNpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGJsb2JVcmkgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0QmxvYlBhcmFtZXRlcnMoIjEyMzQiKS5idWlsZCgpOworICAgIFVyaSBsZWFzZVVyaSA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRMZWFzZVBhcmFtZXRlcnMoIjEyMzQiLCAxKS5idWlsZCgpOworICAgIEJsb2JVcmkudmFsaWRhdGVVcmkoYmxvYlVyaSk7CisgICAgQmxvYlVyaS52YWxpZGF0ZVVyaShsZWFzZVVyaSk7CisKKyAgICBVcmkgd3JvbmdFeHRlbnNpb25VcmkgPSBibG9iVXJpLmJ1aWxkVXBvbigpLnBhdGgoIjEyMzQuZXh0cyIpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhyb3dzKE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQmxvYlVyaS52YWxpZGF0ZVVyaSh3cm9uZ0V4dGVuc2lvblVyaSkpOworICAgIFVyaSBlbXB0eUNoZWNrc3VtID0gYmxvYlVyaS5idWlsZFVwb24oKS5wYXRoKCIubGVhc2UiKS5idWlsZCgpOworICAgIGFzc2VydFRocm93cyhNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsICgpIC0+IEJsb2JVcmkudmFsaWRhdGVVcmkoZW1wdHlDaGVja3N1bSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdmFsaWRhdGVVcmlfYWxsb3dPbmx5UGVybWl0dGVkUXVlcnlQYXJhbWV0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGVtcHR5UXVlcnlVcmkgPSBuZXcgVXJpLkJ1aWxkZXIoKS5wYXRoKCIxMjM0IikuYnVpbGQoKTsKKyAgICBCbG9iVXJpLnZhbGlkYXRlVXJpKGVtcHR5UXVlcnlVcmkpOworICAgIFVyaSBxdWVyeVdpdGhFeHBpcnlEYXRlVXJpID0KKyAgICAgICAgbmV3IFVyaS5CdWlsZGVyKCkucGF0aCgiMTIzNCIpLmFwcGVuZFF1ZXJ5UGFyYW1ldGVyKCJleHBpcnlEYXRlU2VjcyIsICIxIikuYnVpbGQoKTsKKyAgICBCbG9iVXJpLnZhbGlkYXRlVXJpKHF1ZXJ5V2l0aEV4cGlyeURhdGVVcmkpOworCisgICAgVXJpIHF1ZXJ5VG9vTG9uZ1VyaSA9CisgICAgICAgIG5ldyBVcmkuQnVpbGRlcigpCisgICAgICAgICAgICAucGF0aCgiMTIzNCIpCisgICAgICAgICAgICAuYXBwZW5kUXVlcnlQYXJhbWV0ZXIoImZpbGVTaXplIiwgIjEiKQorICAgICAgICAgICAgLmFwcGVuZFF1ZXJ5UGFyYW1ldGVyKCJleHBpcnlEYXRlIiwgIjEiKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhyb3dzKE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQmxvYlVyaS52YWxpZGF0ZVVyaShxdWVyeVRvb0xvbmdVcmkpKTsKKworICAgIFVyaSBxdWVyeVdpdGhVbmV4cGVjdGVkUGFyYW1ldGVyVXJpID0KKyAgICAgICAgbmV3IFVyaS5CdWlsZGVyKCkucGF0aCgiMTIzNCIpLmFwcGVuZFF1ZXJ5UGFyYW1ldGVyKCJ3cm9uZ1BhcmFtZXRlciIsICIxIikuYnVpbGQoKTsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gQmxvYlVyaS52YWxpZGF0ZVVyaShxdWVyeVdpdGhVbmV4cGVjdGVkUGFyYW1ldGVyVXJpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpc0xlYXNlVXJpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGxlYXNlVXJpID0gQmxvYlVyaS5idWlsZGVyKGNvbnRleHQpLnNldExlYXNlUGFyYW1ldGVycygiMTIzNCIsIDEpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChCbG9iVXJpLmlzTGVhc2VVcmkobGVhc2VVcmkuZ2V0UGF0aCgpKSkuaXNUcnVlKCk7CisKKyAgICBVcmkgbm9uTGVhc2VVcmkgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0QmxvYlBhcmFtZXRlcnMoIjEyMzQiKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoQmxvYlVyaS5pc0xlYXNlVXJpKG5vbkxlYXNlVXJpLmdldFBhdGgoKSkpLmlzRmFsc2UoKTsKKyAgICBub25MZWFzZVVyaSA9IG5ldyBVcmkuQnVpbGRlcigpLnBhdGgoIjEyMzQuZXh0cyIpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChCbG9iVXJpLmlzTGVhc2VVcmkobm9uTGVhc2VVcmkuZ2V0UGF0aCgpKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0RXhwaXJ5RGF0ZVNlY3Nfc2hvdWxkU3VjY2VlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSBsZWFzZVVyaSA9IEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRMZWFzZVBhcmFtZXRlcnMoIjEyMzQiLCAxKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoQmxvYlVyaS5nZXRFeHBpcnlEYXRlU2VjcyhsZWFzZVVyaSkpLmlzRXF1YWxUbygxKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdldEV4cGlyeURhdGVTZWNzX2VtcHR5UXVlcnlfc2hvdWxkVGhyb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgbGVhc2VVcmkgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0QmxvYlBhcmFtZXRlcnMoIjEyMzQiKS5idWlsZCgpOworICAgIGFzc2VydFRocm93cyhNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsICgpIC0+IEJsb2JVcmkuZ2V0RXhwaXJ5RGF0ZVNlY3MobGVhc2VVcmkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdldENoZWNrc3VtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGJsb2JVcmkgPSBCbG9iVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0QmxvYlBhcmFtZXRlcnMoIjEyMzQiKS5idWlsZCgpOworICAgIGJ5dGVbXSBleHBlY3RlZEJ5dGVzID0gQmFzZUVuY29kaW5nLmJhc2UxNigpLmxvd2VyQ2FzZSgpLmRlY29kZSgiMTIzNCIpOworICAgIGFzc2VydFRoYXQoQmxvYlVyaS5nZXRDaGVja3N1bShibG9iVXJpLmdldFBhdGgoKSkpLmlzRXF1YWxUbyhleHBlY3RlZEJ5dGVzKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvQ29udGVudFJlc29sdmVyQmFja2VuZFRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0NvbnRlbnRSZXNvbHZlckJhY2tlbmRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDEyOWIwZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0NvbnRlbnRSZXNvbHZlckJhY2tlbmRUZXN0LmphdmEKQEAgLTAsMCArMSwxMjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24uYmFzZS5DaGFyc2V0cy5VVEZfODsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGVudFJlc29sdmVyOworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLk1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5VbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5BcHBlbmRTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLlJlYWRTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLldyaXRlU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5CeXRlU3RyZWFtczsKK2ltcG9ydCBjb20uZ29vZ2xlLnRoaXJkcGFydHkucm9ib2xlY3RyaWMuR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuU2hhZG93czsKKworQFJ1bldpdGgoR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGNsYXNzIENvbnRlbnRSZXNvbHZlckJhY2tlbmRUZXN0IHsKKworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworICBwcml2YXRlIENvbnRlbnRSZXNvbHZlciBjb250ZW50UmVzb2x2ZXI7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgZmluYWwgdm9pZCBzZXRVcFN0b3JhZ2UoKSB7CisgICAgQ29udGVudFJlc29sdmVyQmFja2VuZCBiYWNrZW5kID0gQ29udGVudFJlc29sdmVyQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLmJ1aWxkKCk7CisgICAgc3RvcmFnZSA9IG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEltbXV0YWJsZUxpc3Qub2YoYmFja2VuZCkpOworICAgIGNvbnRlbnRSZXNvbHZlciA9IGNvbnRleHQuZ2V0Q29udGVudFJlc29sdmVyKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRm9yUmVhZF9yZWFkcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImNvbnRlbnQ6Ly90ZXN0L29wZW5Gb3JSZWFkX3JlYWRzIik7CisgICAgU3RyaW5nIGV4cGVjdGVkID0gImV4cGVjdGVkIGNvbnRlbnQiOworICAgIFNoYWRvd3Muc2hhZG93T2YoY29udGVudFJlc29sdmVyKQorICAgICAgICAucmVnaXN0ZXJJbnB1dFN0cmVhbSh1cmksIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShleHBlY3RlZC5nZXRCeXRlcyhVVEZfOCkpKTsKKworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgU3RyaW5nIGFjdHVhbCA9IG5ldyBTdHJpbmcoQnl0ZVN0cmVhbXMudG9CeXRlQXJyYXkoaW4pLCBVVEZfOCk7CisgICAgICBhc3NlcnRUaGF0KGFjdHVhbCkuaXNFcXVhbFRvKGV4cGVjdGVkKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRm9yUmVhZF9taXNzaW5nRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImNvbnRlbnQ6Ly90ZXN0L29wZW5Gb3JSZWFkX21pc3NpbmdGaWxlIik7CisKKyAgICB0cnkgKElucHV0U3RyZWFtIGluID0gc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIC8vIFRoZSBzaGFkb3cgaXMgd2VpcmQ6IGl0IHJldHVybnMgYSBzdHJlYW0gZXZlbiBpZiBub3QgcmVnaXN0ZXJlZCwgYnV0IHRoYXQgc3RyZWFtIHRocm93cworICAgICAgLy8gd2hlbiB5b3UgdHJ5IHRvIHVzZSBpdC4KKyAgICAgIGFzc2VydFRocm93cyhVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gaW4ucmVhZCgpKTsKKyAgICB9CisgIH0KKworICAvLyBUT0RPKGIvMTEwNDkzMTk3KTogQWRkIHRlc3QgZm9yIG5hdGl2ZSByZWFkLiBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGxhY2tzCisgIC8vIHJlZ2lzdGVyRmlsZURlc2NyaXB0b3IuCisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkZvcldyaXRlX25vdEltcGxlbWVudGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiY29udGVudDovL3Rlc3Qvb3BlbkZvcldyaXRlX25vdEltcGxlbWVudGVkIik7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24uY2xhc3MsICgpIC0+IHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRm9yQXBwZW5kX25vdEltcGxlbWVudGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiY29udGVudDovL3Rlc3Qvb2siKTsKKworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbi5jbGFzcywKKyAgICAgICAgKCkgLT4gc3RvcmFnZS5vcGVuKHVyaSwgQXBwZW5kU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBub25FbWJlZGRlZF9jaGVja3NTY2hlbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDb250ZW50UmVzb2x2ZXJCYWNrZW5kIG5vbkVtYmVkZGVkID0gQ29udGVudFJlc29sdmVyQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLmJ1aWxkKCk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiV1JPTkc6Ly90ZXN0L25vbkVtYmVkZGVkX2NoZWNrc1NjaGVtZSIpOworCisgICAgYXNzZXJ0VGhyb3dzKE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gbm9uRW1iZWRkZWQub3BlbkZvclJlYWQodXJpKSk7CisgICAgYXNzZXJ0VGhhdChub25FbWJlZGRlZC5uYW1lKCkpLmlzRXF1YWxUbygiY29udGVudCIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZW1iZWRkZWRfcmV3cml0ZXNTY2hlbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDb250ZW50UmVzb2x2ZXJCYWNrZW5kIGVtYmVkZGVkID0KKyAgICAgICAgQ29udGVudFJlc29sdmVyQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLnNldEVtYmVkZGVkKHRydWUpLmJ1aWxkKCk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiT1RIRVJTQ0hFTUU6Ly90ZXN0L2VtYmVkZGVkX3Jld3JpdGVzU2NoZW1lIik7CisgICAgVXJpIGNvbnRlbnRVcmkgPSB1cmkuYnVpbGRVcG9uKCkuc2NoZW1lKCJjb250ZW50IikuYnVpbGQoKTsKKyAgICBTdHJpbmcgZXhwZWN0ZWQgPSAiZXhwZWN0ZWQgY29udGVudCI7CisgICAgU2hhZG93cy5zaGFkb3dPZihjb250ZW50UmVzb2x2ZXIpCisgICAgICAgIC5yZWdpc3RlcklucHV0U3RyZWFtKGNvbnRlbnRVcmksIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShleHBlY3RlZC5nZXRCeXRlcyhVVEZfOCkpKTsKKworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBlbWJlZGRlZC5vcGVuRm9yUmVhZCh1cmkpKSB7CisgICAgICBTdHJpbmcgYWN0dWFsID0gbmV3IFN0cmluZyhCeXRlU3RyZWFtcy50b0J5dGVBcnJheShpbiksIFVURl84KTsKKyAgICAgIGFzc2VydFRoYXQoYWN0dWFsKS5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICAgIH0KKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbFN0YXRlRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBlbWJlZGRlZC5uYW1lKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9GaWxlRGVzY3JpcHRvclVyaUFuZHJvaWRUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9GaWxlRGVzY3JpcHRvclVyaUFuZHJvaWRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDcxMjgyZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0ZpbGVEZXNjcmlwdG9yVXJpQW5kcm9pZFRlc3QuamF2YQpAQCAtMCwwICsxLDY2IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuUGFyY2VsRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgYW5kcm9pZC51dGlsLlBhaXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uTWFsZm9ybWVkVXJpRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuSlVuaXQ0OworCisvKiogVGVzdCB7QGxpbmsgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5GaWxlRGVzY3JpcHRvclVyaX0uICovCitAUnVuV2l0aChKVW5pdDQuY2xhc3MpCitwdWJsaWMgY2xhc3MgRmlsZURlc2NyaXB0b3JVcmlBbmRyb2lkVGVzdCB7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY29udmVuaWVuY2VNZXRob2Rfc2hvdWxkR2VuZXJhdGVVcmlGcm9tUEZEKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgUGFyY2VsRmlsZURlc2NyaXB0b3Igc3RkaW4gPSBQYXJjZWxGaWxlRGVzY3JpcHRvci5hZG9wdEZkKDApOworICAgIFBhaXI8VXJpLCBDbG9zZWFibGU+IHJlc3VsdCA9IEZpbGVEZXNjcmlwdG9yVXJpLmZyb21QYXJjZWxGaWxlRGVzY3JpcHRvcihzdGRpbik7CisgICAgYXNzZXJ0VGhhdChyZXN1bHQuZmlyc3QuZ2V0U2NoZW1lKCkpLmlzRXF1YWxUbygiZmQiKTsKKyAgICBhc3NlcnRUaGF0KHJlc3VsdC5maXJzdC5nZXRTY2hlbWVTcGVjaWZpY1BhcnQoKSkuaXNFcXVhbFRvKCIwIik7CisgICAgYXNzZXJ0VGhhdChGaWxlRGVzY3JpcHRvclVyaS5nZXRGZChyZXN1bHQuZmlyc3QpKS5pc0VxdWFsVG8oMCk7CisgICAgYXNzZXJ0VGhhdChyZXN1bHQuZmlyc3QudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCJmZDowIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjbG9zZV9zaG91bGRDbG9zZUZkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgUGFyY2VsRmlsZURlc2NyaXB0b3IgY3dkID0KKyAgICAgICAgUGFyY2VsRmlsZURlc2NyaXB0b3Iub3BlbihuZXcgRmlsZSgiLiIpLCBQYXJjZWxGaWxlRGVzY3JpcHRvci5NT0RFX1JFQURfT05MWSk7CisgICAgUGFpcjxVcmksIENsb3NlYWJsZT4gcmVzdWx0ID0gRmlsZURlc2NyaXB0b3JVcmkuZnJvbVBhcmNlbEZpbGVEZXNjcmlwdG9yKGN3ZCk7CisKKyAgICBhc3NlcnRUaGF0KHJlc3VsdC5maXJzdC5nZXRTY2hlbWUoKSkuaXNFcXVhbFRvKCJmZCIpOworICAgIGFzc2VydFRoYXQoRmlsZURlc2NyaXB0b3JVcmkuZ2V0RmQocmVzdWx0LmZpcnN0KSkuaXNHcmVhdGVyVGhhbigwKTsKKworICAgIEZpbGUgcHJvY0ZkID0gbmV3IEZpbGUoIi9wcm9jL3NlbGYvZmQvIiArIHJlc3VsdC5maXJzdC5nZXRTY2hlbWVTcGVjaWZpY1BhcnQoKSk7CisgICAgYXNzZXJ0VGhhdChwcm9jRmQuZXhpc3RzKCkpLmlzVHJ1ZSgpOworICAgIHJlc3VsdC5zZWNvbmQuY2xvc2UoKTsKKyAgICBhc3NlcnRUaGF0KHByb2NGZC5leGlzdHMoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0RmRfdmFsaWRhdGVzVXJpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhyb3dzKE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gRmlsZURlc2NyaXB0b3JVcmkuZ2V0RmQoVXJpLnBhcnNlKCJmaWxlOjUiKSkpOworICAgIGFzc2VydFRocm93cyhNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsICgpIC0+IEZpbGVEZXNjcmlwdG9yVXJpLmdldEZkKFVyaS5wYXJzZSgiZmQ6IikpKTsKKyAgICBhc3NlcnRUaHJvd3MoTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBGaWxlRGVzY3JpcHRvclVyaS5nZXRGZChVcmkucGFyc2UoImZkOmFiYyIpKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0ZpbGVVcmlBZGFwdGVyVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvRmlsZVVyaUFkYXB0ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDcxMDMzOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0ZpbGVVcmlBZGFwdGVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uTWFsZm9ybWVkVXJpRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUudGhpcmRwYXJ0eS5yb2JvbGVjdHJpYy5Hb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKKworLyoqIFRlc3Qge0BsaW5rIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuRmlsZVVyaUFkYXB0ZXJ9LiAqLworQFJ1bldpdGgoR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGNsYXNzIEZpbGVVcmlBZGFwdGVyVGVzdCB7CisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHNob3VsZEdlbmVyYXRlRmlsZUZyb21VcmkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZpbGUgPSBGaWxlVXJpQWRhcHRlci5pbnN0YW5jZSgpLnRvRmlsZShVcmkucGFyc2UoImZpbGU6Ly8vdG1wL2Zvby50eHQiKSk7CisgICAgYXNzZXJ0VGhhdChmaWxlLmdldFBhdGgoKSkuaXNFcXVhbFRvKCIvdG1wL2Zvby50eHQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGlnbm9yZXNGcmFnbWVudEF0Q2FsbGVyc1BlcmlsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRmlsZSBmaWxlID0gRmlsZVVyaUFkYXB0ZXIuaW5zdGFuY2UoKS50b0ZpbGUoVXJpLnBhcnNlKCJmaWxlOi8vL3RtcC9mb28udHh0I2ZyYWdtZW50IikpOworICAgIGFzc2VydFRoYXQoZmlsZS5nZXRQYXRoKCkpLmlzRXF1YWxUbygiL3RtcC9mb28udHh0Iik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZXF1aXJlc0ZpbGVTY2hlbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIE1hbGZvcm1lZFVyaUV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgKCkgLT4gRmlsZVVyaUFkYXB0ZXIuaW5zdGFuY2UoKS50b0ZpbGUoVXJpLnBhcnNlKCJ4eHg6Ly8vdG1wL2Zvby50eHQiKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVxdWlyZXNFbXB0eVF1ZXJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICgpIC0+IEZpbGVVcmlBZGFwdGVyLmluc3RhbmNlKCkudG9GaWxlKFVyaS5wYXJzZSgiZmlsZTovLy90bXAvZm9vLnR4dD9xdWVyeSIpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZXF1aXJlc0VtcHR5QXV0aG9yaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICgpIC0+IEZpbGVVcmlBZGFwdGVyLmluc3RhbmNlKCkudG9GaWxlKFVyaS5wYXJzZSgiZmlsZTovL2F1dGhvcml0eS90bXAvZm9vLnR4dCIpKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0ZpbGVVcmlUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9GaWxlVXJpVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM4OWM4YzYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9GaWxlVXJpVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjQgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLnRoaXJkcGFydHkucm9ib2xlY3RyaWMuR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CisKKy8qKiBUZXN0IHtAbGluayBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkZpbGVVcml9LiAqLworQFJ1bldpdGgoR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGNsYXNzIEZpbGVVcmlUZXN0IHsKKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzaG91bGRHZW5lcmF0ZVVyaUZyb21GaWxlKCkgeworICAgIFVyaSB1cmkgPSBGaWxlVXJpLmJ1aWxkZXIoKS5mcm9tRmlsZShuZXcgRmlsZSgiL3RtcC9mb28udHh0IikpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdCh1cmkuZ2V0U2NoZW1lKCkpLmlzRXF1YWxUbygiZmlsZSIpOworICAgIGFzc2VydFRoYXQodXJpLmdldFBhdGgoKSkuaXNFcXVhbFRvKCIvdG1wL2Zvby50eHQiKTsKKyAgICBhc3NlcnRUaGF0KHVyaS50b1N0cmluZygpKS5pc0VxdWFsVG8oImZpbGU6Ly8vdG1wL2Zvby50eHQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHNob3VsZEdlbmVyYXRlVXJpRnJvbVN0cmluZ1BhdGgoKSB7CisgICAgVXJpIHVyaSA9IEZpbGVVcmkuYnVpbGRlcigpLnNldFBhdGgoIi90bXAvZm9vLnR4dCIpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdCh1cmkudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCJmaWxlOi8vL3RtcC9mb28udHh0Iik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZGVyX2FwcGVuZFBhdGhfYWRkc1BhdGhTZWdtZW50KCkgeworICAgIFVyaSB1cmkgPSBGaWxlVXJpLmJ1aWxkZXIoKS5zZXRQYXRoKCJ0bXAiKS5hcHBlbmRQYXRoKCJmb28udHh0IikuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KHVyaS50b1N0cmluZygpKS5pc0VxdWFsVG8oImZpbGU6Ly8vdG1wL2Zvby50eHQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGhhc1NhZmVEZWZhdWx0KCkgeworICAgIFVyaSB1cmkgPSBGaWxlVXJpLmJ1aWxkZXIoKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQodXJpLnRvU3RyaW5nKCkpLmlzRXF1YWxUbygiZmlsZTovLy8iKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlcGVhdGVkQ2FsbHNfc2hvdWxkUmV0YWluSW5mbygpIHsKKyAgICBGaWxlVXJpLkJ1aWxkZXIgdXJpQnVpbGRlciA9IEZpbGVVcmkuYnVpbGRlcigpLnNldFBhdGgoIi9mYWtlIik7CisgICAgVXJpIGZpbGVVcmkgPSB1cmlCdWlsZGVyLmJ1aWxkKCk7CisgICAgVXJpIGZpbGVVcmlXaXRoVHJhbnNmb3JtID0gZmlsZVVyaS5idWlsZFVwb24oKS5lbmNvZGVkRnJhZ21lbnQoInRyYW5zZm9ybT1mb28iKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZmlsZVVyaS50b1N0cmluZygpKS5pc0VxdWFsVG8oImZpbGU6Ly8vZmFrZSIpOworICAgIGFzc2VydFRoYXQoZmlsZVVyaVdpdGhUcmFuc2Zvcm0udG9TdHJpbmcoKSkuaXNFcXVhbFRvKCJmaWxlOi8vL2Zha2UjdHJhbnNmb3JtPWZvbyIpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9HZW5lcmljVXJpQWRhcHRlclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0dlbmVyaWNVcmlBZGFwdGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU4ZGNiZjAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9HZW5lcmljVXJpQWRhcHRlclRlc3QuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5NYWxmb3JtZWRVcmlFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS50aGlyZHBhcnR5LnJvYm9sZWN0cmljLkdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworCisvKiogVGVzdCB7QGxpbmsgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5HZW5lcmljVXJpQWRhcHRlcn0uICovCitAUnVuV2l0aChHb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgY2xhc3MgR2VuZXJpY1VyaUFkYXB0ZXJUZXN0IHsKKworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2hvdWxkR2VuZXJhdGVGaWxlRnJvbUZpbGVVcmkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZpbGUgPSBHZW5lcmljVXJpQWRhcHRlci5mb3JDb250ZXh0KGNvbnRleHQpLnRvRmlsZShVcmkucGFyc2UoImZpbGU6Ly8vdG1wL2Zvby50eHQiKSk7CisgICAgYXNzZXJ0VGhhdChmaWxlLmdldFBhdGgoKSkuaXNFcXVhbFRvKCIvdG1wL2Zvby50eHQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHNob3VsZEdlbmVyYXRlRmlsZUZyb21BbmRyb2lkVXJpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRmlsZSBmaWxlID0KKyAgICAgICAgR2VuZXJpY1VyaUFkYXB0ZXIuZm9yQ29udGV4dChjb250ZXh0KQorICAgICAgICAgICAgLnRvRmlsZShVcmkucGFyc2UoImFuZHJvaWQ6Ly9wYWNrYWdlL2ZpbGVzL2NvbW1vbi9zaGFyZWQvcGF0aCIpKTsKKyAgICBhc3NlcnRUaGF0KGZpbGUuZ2V0UGF0aCgpKS5lbmRzV2l0aCgiL2ZpbGVzL2NvbW1vbi9zaGFyZWQvcGF0aCIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2hvdWxkR2VuZXJhdGVGaWxlRnJvbUV4dGVybmFsTG9jYXRpb25VcmkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZpbGUgPQorICAgICAgICBHZW5lcmljVXJpQWRhcHRlci5mb3JDb250ZXh0KGNvbnRleHQpCisgICAgICAgICAgICAudG9GaWxlKFVyaS5wYXJzZSgiYW5kcm9pZDovL3BhY2thZ2UvZXh0ZXJuYWwvY29tbW9uL3NoYXJlZC9wYXRoIikpOworICAgIGFzc2VydFRoYXQoZmlsZS5nZXRQYXRoKCkpLmVuZHNXaXRoKCIvZXh0ZXJuYWwtZmlsZXMvY29tbW9uL3NoYXJlZC9wYXRoIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzaG91bGRDaGVja1NjaGVtZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAoKSAtPiBGaWxlVXJpQWRhcHRlci5pbnN0YW5jZSgpLnRvRmlsZShVcmkucGFyc2UoInh4eDovLy90bXAvZm9vLnR4dCIpKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0phdmFGaWxlQmFja2VuZFRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL0phdmFGaWxlQmFja2VuZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTczNzNhCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvSmF2YUZpbGVCYWNrZW5kVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTIyIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMubWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQ7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uRmlsZUNoYW5uZWxDb252ZXJ0aWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5Mb2NrU2NvcGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uU2l6YWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkJhY2tlbmRUZXN0QmFzZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5CYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLnRoaXJkcGFydHkucm9ib2xlY3RyaWMuR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGVtcG9yYXJ5Rm9sZGVyOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKKworQFJ1bldpdGgoR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIEphdmFGaWxlQmFja2VuZFRlc3QgZXh0ZW5kcyBCYWNrZW5kVGVzdEJhc2UgeworCisgIHByaXZhdGUgQmFja2VuZCBiYWNrZW5kID0gbmV3IEphdmFGaWxlQmFja2VuZCgpOworCisgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlGb2xkZXIgdG1wRm9sZGVyID0gbmV3IFRlbXBvcmFyeUZvbGRlcigpOworCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5Gb3JSZWFkX3Nob3VsZEltcGxlbWVudEZpbGVDaGFubmVsQ29udmVydGlibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJhY2tlbmQub3BlbkZvcldyaXRlKHVyaUZvclRlc3RNZXRob2QoKSkuY2xvc2UoKTsKKyAgICB0cnkgKElucHV0U3RyZWFtIGlucHV0U3RyZWFtID0gYmFja2VuZC5vcGVuRm9yUmVhZCh1cmlGb3JUZXN0TWV0aG9kKCkpKSB7CisgICAgICBhc3NlcnRUaGF0KGlucHV0U3RyZWFtKS5pc0luc3RhbmNlT2YoRmlsZUNoYW5uZWxDb252ZXJ0aWJsZS5jbGFzcyk7CisgICAgICBhc3NlcnRUaGF0KCgoRmlsZUNoYW5uZWxDb252ZXJ0aWJsZSkgaW5wdXRTdHJlYW0pLnRvRmlsZUNoYW5uZWwoKS5wb3NpdGlvbigpKS5pc0VxdWFsVG8oMCk7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkZvcldyaXRlX3Nob3VsZEltcGxlbWVudEZpbGVDaGFubmVsQ29udmVydGlibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSA9IGJhY2tlbmQub3BlbkZvcldyaXRlKHVyaUZvclRlc3RNZXRob2QoKSkpIHsKKyAgICAgIGFzc2VydFRoYXQob3V0cHV0U3RyZWFtKS5pc0luc3RhbmNlT2YoRmlsZUNoYW5uZWxDb252ZXJ0aWJsZS5jbGFzcyk7CisgICAgICBhc3NlcnRUaGF0KCgoRmlsZUNoYW5uZWxDb252ZXJ0aWJsZSkgb3V0cHV0U3RyZWFtKS50b0ZpbGVDaGFubmVsKCkucG9zaXRpb24oKSkuaXNFcXVhbFRvKDApOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5Gb3JBcHBlbmRfc2hvdWxkSW1wbGVtZW50RmlsZUNoYW5uZWxDb252ZXJ0aWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtID0gYmFja2VuZC5vcGVuRm9yQXBwZW5kKHVyaUZvclRlc3RNZXRob2QoKSkpIHsKKyAgICAgIGFzc2VydFRoYXQob3V0cHV0U3RyZWFtKS5pc0luc3RhbmNlT2YoRmlsZUNoYW5uZWxDb252ZXJ0aWJsZS5jbGFzcyk7CisgICAgICBhc3NlcnRUaGF0KCgoRmlsZUNoYW5uZWxDb252ZXJ0aWJsZSkgb3V0cHV0U3RyZWFtKS50b0ZpbGVDaGFubmVsKCkucG9zaXRpb24oKSkuaXNFcXVhbFRvKDApOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5Gb3JSZWFkX3Nob3VsZEltcGxlbWVudFNpemFibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIGJ5dGVbXSBjb250ZW50ID0gbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoKTsKKyAgICB0cnkgKE91dHB1dFN0cmVhbSBvdXQgPSBiYWNrZW5kLm9wZW5Gb3JXcml0ZSh1cmlGb3JUZXN0TWV0aG9kKCkpKSB7CisgICAgICBvdXQud3JpdGUoY29udGVudCk7CisgICAgfQorCisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSA9IGJhY2tlbmQub3BlbkZvclJlYWQodXJpRm9yVGVzdE1ldGhvZCgpKSkgeworICAgICAgYXNzZXJ0VGhhdChpbnB1dFN0cmVhbSkuaXNJbnN0YW5jZU9mKFNpemFibGUuY2xhc3MpOworICAgICAgYXNzZXJ0VGhhdCgoKFNpemFibGUpIGlucHV0U3RyZWFtKS5zaXplKCkpLmlzRXF1YWxUbyhjb250ZW50Lmxlbmd0aCk7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbG9ja1Njb3BlX3JldHVybnNOb25OdWxsTG9ja1Njb3BlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaGF0KGJhY2tlbmQubG9ja1Njb3BlKCkpLmlzTm90TnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbG9ja1Njb3BlX2NhbkJlT3ZlcnJpZGRlbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTG9ja1Njb3BlIGxvY2tTY29wZSA9IG5ldyBMb2NrU2NvcGUoKTsKKyAgICBiYWNrZW5kID0gbmV3IEphdmFGaWxlQmFja2VuZChsb2NrU2NvcGUpOworICAgIGFzc2VydFRoYXQoYmFja2VuZC5sb2NrU2NvcGUoKSkuaXNTYW1lSW5zdGFuY2VBcyhsb2NrU2NvcGUpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBCYWNrZW5kIGJhY2tlbmQoKSB7CisgICAgcmV0dXJuIGJhY2tlbmQ7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIFVyaSBsZWdhbFVyaUJhc2UoKSB7CisgICAgcmV0dXJuIEZpbGVVcmkuZnJvbUZpbGUodG1wRm9sZGVyLmdldFJvb3QoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIExpc3Q8VXJpPiBpbGxlZ2FsVXJpc1RvUmVhZCgpIHsKKyAgICBTdHJpbmcgcm9vdCA9IGxlZ2FsVXJpQmFzZSgpLmdldFBhdGgoKTsKKyAgICByZXR1cm4gSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgVXJpLnBhcnNlKCJmaWxlOi8vPGludGVybmFsPkBhdXRob3JpdHk6MTIzLyIgKyByb290ICsgIi91cmlXaXRoQXV0aG9yaXR5IiksCisgICAgICAgIFVyaS5wYXJzZSgiZmlsZTovLy8iICsgcm9vdCArICIvdXJpV2l0aFF1ZXJ5P3E9YSIpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgTGlzdDxVcmk+IGlsbGVnYWxVcmlzVG9Xcml0ZSgpIHsKKyAgICByZXR1cm4gSW1tdXRhYmxlTGlzdC5vZigpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBMaXN0PFVyaT4gaWxsZWdhbFVyaXNUb0FwcGVuZCgpIHsKKyAgICByZXR1cm4gaWxsZWdhbFVyaXNUb1dyaXRlKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL01lbW9yeUJhY2tlbmRUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9NZW1vcnlCYWNrZW5kVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY5Mzk2MzMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9NZW1vcnlCYWNrZW5kVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHM7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5CYWNrZW5kVGVzdEJhc2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS50aGlyZHBhcnR5LnJvYm9sZWN0cmljLkdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CisKK0BSdW5XaXRoKEdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBNZW1vcnlCYWNrZW5kVGVzdCBleHRlbmRzIEJhY2tlbmRUZXN0QmFzZSB7CisKKyAgcHJpdmF0ZSBmaW5hbCBCYWNrZW5kIGJhY2tlbmQgPSBuZXcgTWVtb3J5QmFja2VuZCgpOworCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgQmFja2VuZCBiYWNrZW5kKCkgeworICAgIHJldHVybiBiYWNrZW5kOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBVcmkgbGVnYWxVcmlCYXNlKCkgeworICAgIHJldHVybiBVcmkucGFyc2UoIm1lbW9yeToiKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgTGlzdDxVcmk+IGlsbGVnYWxVcmlzVG9SZWFkKCkgeworICAgIHJldHVybiBJbW11dGFibGVMaXN0Lm9mKAorICAgICAgICBVcmkucGFyc2UoIm1lbW9yeToiKSwKKyAgICAgICAgVXJpLnBhcnNlKCJtZW1vcnk6Ly88aW50ZXJuYWw+QGF1dGhvcml0eToxMjMvdXJpV2l0aEF1dGhvcml0eSIpLAorICAgICAgICBVcmkucGFyc2UoIm1lbW9yeTovLy91cmlXaXRoUXVlcnk/cT1hIikpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBMaXN0PFVyaT4gaWxsZWdhbFVyaXNUb1dyaXRlKCkgeworICAgIHJldHVybiBpbGxlZ2FsVXJpc1RvUmVhZCgpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHByb3RlY3RlZCBib29sZWFuIHN1cHBvcnRzQXBwZW5kKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgYm9vbGVhbiBzdXBwb3J0c0RpcmVjdG9yaWVzKCkgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgYm9vbGVhbiBzdXBwb3J0c0ZpbGVDb252ZXJ0aWJsZSgpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIGJvb2xlYW4gc3VwcG9ydHNUb0ZpbGUoKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9NZW1vcnlVcmlUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcy9NZW1vcnlVcmlUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWI4NjYwNgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL01lbW9yeVVyaVRlc3QuamF2YQpAQCAtMCwwICsxLDYxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLk1hbGZvcm1lZFVyaUV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLnRoaXJkcGFydHkucm9ib2xlY3RyaWMuR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKKworQFJ1bldpdGgoR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGNsYXNzIE1lbW9yeVVyaVRlc3QgeworCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfd2l0aG91dEtleV90aHJvd3NFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaHJvd3MoTWFsZm9ybWVkVXJpRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBNZW1vcnlVcmkuYnVpbGRlcigpLmJ1aWxkKCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9zZXRLZXlfc2V0c1NjaGVtZVNwZWNpZmljUGFydCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSBNZW1vcnlVcmkuYnVpbGRlcigpLnNldEtleSgiZm9vIikuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KHVyaS5nZXRTY2hlbWVTcGVjaWZpY1BhcnQoKSkuaXNFcXVhbFRvKCJmb28iKTsKKyAgICBhc3NlcnRUaGF0KHVyaS50b1N0cmluZygpKS5pc0VxdWFsVG8oIm1lbW9yeTpmb28iKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfc2V0S2V5X3JlcXVpcmVzTm9uRW1wdHlWYWx1ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRocm93cyhNYWxmb3JtZWRVcmlFeGNlcHRpb24uY2xhc3MsICgpIC0+IE1lbW9yeVVyaS5idWlsZGVyKCkuc2V0S2V5KCIiKS5idWlsZCgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXJfYnVpbGRzT3BhcXVlVXJpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IE1lbW9yeVVyaS5idWlsZGVyKCkuc2V0S2V5KCJmb28/d2l0aFF1ZXN0aW9uTWFyayIpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdCh1cmkuZ2V0U2NoZW1lU3BlY2lmaWNQYXJ0KCkpLmlzRXF1YWxUbygiZm9vP3dpdGhRdWVzdGlvbk1hcmsiKTsKKyAgICBhc3NlcnRUaGF0KHVyaS50b1N0cmluZygpKS5pc0VxdWFsVG8oIm1lbW9yeTpmb28lM0Z3aXRoUXVlc3Rpb25NYXJrIik7CisKKyAgICB1cmkgPSBNZW1vcnlVcmkuYnVpbGRlcigpLnNldEtleSgiZm9vL3dpdGhGb3J3YXJkU2xhc2giKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQodXJpLmdldFNjaGVtZVNwZWNpZmljUGFydCgpKS5pc0VxdWFsVG8oImZvby93aXRoRm9yd2FyZFNsYXNoIik7CisgICAgYXNzZXJ0VGhhdCh1cmkudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCJtZW1vcnk6Zm9vJTJGd2l0aEZvcndhcmRTbGFzaCIpOworCisgICAgdXJpID0gTWVtb3J5VXJpLmJ1aWxkZXIoKS5zZXRLZXkoImZvbyN3aXRoUG91bmQiKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQodXJpLmdldFNjaGVtZVNwZWNpZmljUGFydCgpKS5pc0VxdWFsVG8oImZvbyN3aXRoUG91bmQiKTsKKyAgICBhc3NlcnRUaGF0KHVyaS50b1N0cmluZygpKS5pc0VxdWFsVG8oIm1lbW9yeTpmb28lMjN3aXRoUG91bmQiKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHMvVXJpTm9ybWFsaXplclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL1VyaU5vcm1hbGl6ZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGQ1NmIxOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzL1VyaU5vcm1hbGl6ZXJUZXN0LmphdmEKQEAgLTAsMCArMSw2NyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUudGhpcmRwYXJ0eS5yb2JvbGVjdHJpYy5Hb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworCisvKiogVGVzdCB7QGxpbmsgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5VcmlOb3JtYWxpemVyfS4gKi8KK0BSdW5XaXRoKEdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBVcmlOb3JtYWxpemVyVGVzdCB7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbm9ybWFsaXplVXJpV2l0aERvdERvdCgpIHsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJhbmRyb2lkOi8vcGFja2FnZS9maWxlcy9jb21tb24vLi4vc2hhcmVkL3BhdGgvLi4iKTsKKworICAgIGFzc2VydFRoYXQoVXJpTm9ybWFsaXplci5ub3JtYWxpemVVcmkodXJpKS50b1N0cmluZygpKQorICAgICAgICAuaXNFcXVhbFRvKCJhbmRyb2lkOi8vcGFja2FnZS9maWxlcy9zaGFyZWQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZVVyaVdpdGhEb3QoKSB7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiYW5kcm9pZDovL3BhY2thZ2UvZmlsZXMvY29tbW9uLy4vc2hhcmVkL3BhdGgvLi8uLy4iKTsKKworICAgIGFzc2VydFRoYXQoVXJpTm9ybWFsaXplci5ub3JtYWxpemVVcmkodXJpKS50b1N0cmluZygpKQorICAgICAgICAuaXNFcXVhbFRvKCJhbmRyb2lkOi8vcGFja2FnZS9maWxlcy9jb21tb24vc2hhcmVkL3BhdGgiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZVVyaVdpdGhTbGFzaFNsYXNoKCkgeworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImFuZHJvaWQ6Ly9wYWNrYWdlL2ZpbGVzL2NvbW1vbi8vc2hhcmVkL3BhdGgvLyIpOworCisgICAgYXNzZXJ0VGhhdChVcmlOb3JtYWxpemVyLm5vcm1hbGl6ZVVyaSh1cmkpLnRvU3RyaW5nKCkpCisgICAgICAgIC5pc0VxdWFsVG8oImFuZHJvaWQ6Ly9wYWNrYWdlL2ZpbGVzL2NvbW1vbi9zaGFyZWQvcGF0aCIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbm9ybWFsaXplVXJpV2l0aFVwcGVyY2FzZVNjaGVtZSgpIHsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJBTkRST0lEOi8vcGFja2FnZS9maWxlcy9jb21tb24vc2hhcmVkL3BhdGgiKTsKKworICAgIGFzc2VydFRoYXQoVXJpTm9ybWFsaXplci5ub3JtYWxpemVVcmkodXJpKS50b1N0cmluZygpKQorICAgICAgICAuaXNFcXVhbFRvKCJhbmRyb2lkOi8vcGFja2FnZS9maWxlcy9jb21tb24vc2hhcmVkL3BhdGgiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG5vcm1hbGl6ZVVyaVJlYWNoZXNFbmRPZlBhdGgoKSB7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiYW5kcm9pZDovL3BhY2thZ2UvZmlsZXMvY29tbW9uL3NoYXJlZC9wYXRoLy4uLy4uLy4uLy4uLy4uLy4uIik7CisKKyAgICBhc3NlcnRUaGF0KFVyaU5vcm1hbGl6ZXIubm9ybWFsaXplVXJpKHVyaSkudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCJhbmRyb2lkOi8vcGFja2FnZS8iKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzL0JVSUxEIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmYmIzMDQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iZWhhdmlvcnMvQlVJTEQKQEAgLTAsMCArMSw3MyBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfYmluYXJ5IiwgImFuZHJvaWRfaW5zdHJ1bWVudGF0aW9uX3Rlc3QiLCAiYW5kcm9pZF9saWJyYXJ5IiwgImFuZHJvaWRfbG9jYWxfdGVzdCIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWyIvLzpfX3N1YnBhY2thZ2VzX18iXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIlVyaUNvbXB1dGluZ0JlaGF2aW9yVGVzdCIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlVyaUNvbXB1dGluZ0JlaGF2aW9yVGVzdC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JlaGF2aW9yczpjb21wdXRlX3VyaSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiU3luY2luZ0JlaGF2aW9yQW5kcm9pZFRlc3RfbGliIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlN5bmNpbmdCZWhhdmlvckFuZHJvaWRUZXN0LmphdmEiLAorICAgIF0sCisgICAgbWFuaWZlc3QgPSAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZTpBbmRyb2lkTWFuaWZlc3QueG1sIiwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iZWhhdmlvcnM6c3luY2luZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnN0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOmJ1ZmZlciIsCisgICAgICAgICJAY29tX2dvb2dsZV9hbmRyb2lkX3Rlc3RpbmcvLzp0ZXN0cnVubmVyIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBqdW5pdCIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfYmluYXJ5KAorICAgIG5hbWUgPSAiU3luY2luZ0JlaGF2aW9yQW5kcm9pZFRlc3RfYmluIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgbWFuaWZlc3QgPSAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZTpBbmRyb2lkTWFuaWZlc3QueG1sIiwKKyAgICBkZXBzID0gWyI6U3luY2luZ0JlaGF2aW9yQW5kcm9pZFRlc3RfbGliIl0sCispCisKK2FuZHJvaWRfaW5zdHJ1bWVudGF0aW9uX3Rlc3QoCisgICAgbmFtZSA9ICJTeW5jaW5nQmVoYXZpb3JBbmRyb2lkVGVzdCIsCisgICAgdGltZW91dCA9ICJtb2RlcmF0ZSIsCisgICAgdGVzdG9ubHkgPSAxLAorICAgIHRhcmdldF9kZXZpY2UgPSAiLy90b29scy9hbmRyb2lkL2VtdWxhdGVkX2RldmljZXMvZ2VuZXJpY19waG9uZTpnb29nbGVfMjNfeDg2IiwKKyAgICB0ZXN0X2FwcCA9ICI6U3luY2luZ0JlaGF2aW9yQW5kcm9pZFRlc3RfYmluIiwKKykKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JlaGF2aW9ycy9TeW5jaW5nQmVoYXZpb3JBbmRyb2lkVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzL1N5bmNpbmdCZWhhdmlvckFuZHJvaWRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDJhNWU4YgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JlaGF2aW9ycy9TeW5jaW5nQmVoYXZpb3JBbmRyb2lkVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzAgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmVoYXZpb3JzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuSmF2YUZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVtcG9yYXJ5VXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWFkU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5Xcml0ZVN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuQnVmZmVyVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLkpVbml0NDsKKworQFJ1bldpdGgoSlVuaXQ0LmNsYXNzKQorcHVibGljIGNsYXNzIFN5bmNpbmdCZWhhdmlvckFuZHJvaWRUZXN0IHsKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeVVyaSB0bXBVcmkgPSBuZXcgVGVtcG9yYXJ5VXJpKCk7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcFN0b3JhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9yYWdlID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKG5ldyBKYXZhRmlsZUJhY2tlbmQoKSksIEltbXV0YWJsZUxpc3Qub2YobmV3IEJ1ZmZlclRyYW5zZm9ybSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzeW5jaW5nX3N5bmMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpMSA9CisgICAgICAgIHRtcFVyaQorICAgICAgICAgICAgLm5ld1VyaUJ1aWxkZXIoKQorICAgICAgICAgICAgLmJ1aWxkKCkKKyAgICAgICAgICAgIC5idWlsZFVwb24oKQorICAgICAgICAgICAgLmVuY29kZWRGcmFnbWVudCgidHJhbnNmb3JtPWJ1ZmZlcihzaXplPTgxOTIpIikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFN5bmNpbmdCZWhhdmlvciBzeW5jaW5nID0gbmV3IFN5bmNpbmdCZWhhdmlvcigpOworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9IHN0b3JhZ2Uub3Blbih1cmkxLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKS53aXRoQmVoYXZpb3JzKHN5bmNpbmcpKSkgeworICAgICAgb3V0LndyaXRlKDQyKTsKKyAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBzdG9yYWdlLm9wZW4odXJpMSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgICAgYXNzZXJ0VGhhdChpbi5yZWFkKCkpLmlzRXF1YWxUbygtMSk7CisgICAgICB9CisgICAgICBzeW5jaW5nLnN5bmMoKTsKKyAgICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBzdG9yYWdlLm9wZW4odXJpMSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgICAgYXNzZXJ0VGhhdChpbi5yZWFkKCkpLmlzRXF1YWxUbyg0Mik7CisgICAgICB9CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iZWhhdmlvcnMvVXJpQ29tcHV0aW5nQmVoYXZpb3JUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iZWhhdmlvcnMvVXJpQ29tcHV0aW5nQmVoYXZpb3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTY5NmIwOAotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JlaGF2aW9ycy9VcmlDb21wdXRpbmdCZWhhdmlvclRlc3QuamF2YQpAQCAtMCwwICsxLDEzMCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iZWhhdmlvcnM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ud2hlbjsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5GaWxlVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuRHVtbXlUcmFuc2Zvcm1zOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5SZWFkU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5Xcml0ZVN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5CYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLnRoaXJkcGFydHkucm9ib2xlY3RyaWMuR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5GdXR1cmU7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm1vY2tpdG8uTW9jazsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvSlVuaXQ7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b1J1bGU7CisKK0BSdW5XaXRoKEdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBVcmlDb21wdXRpbmdCZWhhdmlvclRlc3QgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIElucHV0U3RyZWFtIEVNUFRZX0lOUFVUX1NUUkVBTSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVswXSk7CisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworCisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgQE1vY2sgcHJvdGVjdGVkIEJhY2tlbmQgZmlsZUJhY2tlbmQ7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBpbml0U3RvcmFnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHdoZW4oZmlsZUJhY2tlbmQubmFtZSgpKS50aGVuUmV0dXJuKCJmaWxlIik7CisgICAgc3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihmaWxlQmFja2VuZCksCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKER1bW15VHJhbnNmb3Jtcy5DQVBfRklMRU5BTUVfVFJBTlNGT1JNKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRDb21wdXRlZFVyaV9yZWFkX3Nob3VsZFJldGFpblVuZW5jb2RlZFVyaUFuZEZyYWdtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGZpbGVVcmlXaXRoVHJhbnNmb3JtID0KKyAgICAgICAgRmlsZVVyaS5idWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRQYXRoKCIvZmFrZSIpCisgICAgICAgICAgICAuYnVpbGQoKQorICAgICAgICAgICAgLmJ1aWxkVXBvbigpCisgICAgICAgICAgICAuZW5jb2RlZEZyYWdtZW50KCJ0cmFuc2Zvcm09Y2FwIikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHdoZW4oZmlsZUJhY2tlbmQub3BlbkZvclJlYWQoYW55KCkpKS50aGVuUmV0dXJuKEVNUFRZX0lOUFVUX1NUUkVBTSk7CisgICAgRnV0dXJlPFVyaT4gdXJpRnV0dXJlOworICAgIFVyaUNvbXB1dGluZ0JlaGF2aW9yIGNvbXB1dGVVcmkgPSBuZXcgVXJpQ29tcHV0aW5nQmVoYXZpb3IoZmlsZVVyaVdpdGhUcmFuc2Zvcm0pOworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPQorICAgICAgICBzdG9yYWdlLm9wZW4oZmlsZVVyaVdpdGhUcmFuc2Zvcm0sIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkud2l0aEJlaGF2aW9ycyhjb21wdXRlVXJpKSkpIHsKKyAgICAgIHVyaUZ1dHVyZSA9IGNvbXB1dGVVcmkudXJpRnV0dXJlKCk7CisgICAgfQorICAgIGFzc2VydFRoYXQodXJpRnV0dXJlLmdldCgpKS5pc0VxdWFsVG8oZmlsZVVyaVdpdGhUcmFuc2Zvcm0pOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0Q29tcHV0ZWRVcmlfcmVhZF93aXRoTm9UcmFuc2Zvcm1fcmV0dXJuc1NhbWVVcmkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgZmlsZVVyaVdpdGhvdXRUcmFuc2Zvcm0gPSBGaWxlVXJpLmJ1aWxkZXIoKS5zZXRQYXRoKCIvZmFrZSIpLmJ1aWxkKCk7CisgICAgd2hlbihmaWxlQmFja2VuZC5vcGVuRm9yUmVhZChhbnkoKSkpLnRoZW5SZXR1cm4oRU1QVFlfSU5QVVRfU1RSRUFNKTsKKyAgICBGdXR1cmU8VXJpPiB1cmlGdXR1cmU7CisgICAgVXJpQ29tcHV0aW5nQmVoYXZpb3IgY29tcHV0ZVVyaSA9IG5ldyBVcmlDb21wdXRpbmdCZWhhdmlvcihmaWxlVXJpV2l0aG91dFRyYW5zZm9ybSk7CisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgIHN0b3JhZ2Uub3BlbigKKyAgICAgICAgICAgIGZpbGVVcmlXaXRob3V0VHJhbnNmb3JtLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLndpdGhCZWhhdmlvcnMoY29tcHV0ZVVyaSkpKSB7CisgICAgICB1cmlGdXR1cmUgPSBjb21wdXRlVXJpLnVyaUZ1dHVyZSgpOworICAgIH0KKyAgICBhc3NlcnRUaGF0KHVyaUZ1dHVyZS5nZXQoKSkuaXNFcXVhbFRvKGZpbGVVcmlXaXRob3V0VHJhbnNmb3JtKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdldENvbXB1dGVkVXJpX3dyaXRlX3Nob3VsZFJldGFpblVuZW5jb2RlZFVyaUFuZEZyYWdtZW50KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBVcmkgZmlsZVVyaVdpdGhUcmFuc2Zvcm0gPQorICAgICAgICBGaWxlVXJpLmJ1aWxkZXIoKQorICAgICAgICAgICAgLnNldFBhdGgoIi9mYWtlIikKKyAgICAgICAgICAgIC5idWlsZCgpCisgICAgICAgICAgICAuYnVpbGRVcG9uKCkKKyAgICAgICAgICAgIC5lbmNvZGVkRnJhZ21lbnQoInRyYW5zZm9ybT1jYXAiKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd2hlbihmaWxlQmFja2VuZC5vcGVuRm9yV3JpdGUoYW55KCkpKS50aGVuUmV0dXJuKG91dHB1dFN0cmVhbSk7CisgICAgRnV0dXJlPFVyaT4gdXJpRnV0dXJlOworICAgIFVyaUNvbXB1dGluZ0JlaGF2aW9yIGNvbXB1dGVVcmkgPSBuZXcgVXJpQ29tcHV0aW5nQmVoYXZpb3IoZmlsZVVyaVdpdGhUcmFuc2Zvcm0pOworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9CisgICAgICAgIHN0b3JhZ2Uub3BlbihmaWxlVXJpV2l0aFRyYW5zZm9ybSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkud2l0aEJlaGF2aW9ycyhjb21wdXRlVXJpKSkpIHsKKyAgICAgIHVyaUZ1dHVyZSA9IGNvbXB1dGVVcmkudXJpRnV0dXJlKCk7CisgICAgfQorICAgIGFzc2VydFRoYXQodXJpRnV0dXJlLmdldCgpKS5pc0VxdWFsVG8oZmlsZVVyaVdpdGhUcmFuc2Zvcm0pOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0Q29tcHV0ZWRVcmlfd3JpdGVfd2l0aE5vVHJhbnNmb3JtX3JldHVybnNTYW1lVXJpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKKyAgICBVcmkgZmlsZVVyaVdpdGhvdXRUcmFuc2Zvcm0gPSBGaWxlVXJpLmJ1aWxkZXIoKS5zZXRQYXRoKCIvZmFrZSIpLmJ1aWxkKCk7CisgICAgd2hlbihmaWxlQmFja2VuZC5vcGVuRm9yV3JpdGUoYW55KCkpKS50aGVuUmV0dXJuKG91dHB1dFN0cmVhbSk7CisgICAgRnV0dXJlPFVyaT4gdXJpRnV0dXJlOworICAgIFVyaUNvbXB1dGluZ0JlaGF2aW9yIGNvbXB1dGVVcmkgPSBuZXcgVXJpQ29tcHV0aW5nQmVoYXZpb3IoZmlsZVVyaVdpdGhvdXRUcmFuc2Zvcm0pOworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dCA9CisgICAgICAgIHN0b3JhZ2Uub3BlbigKKyAgICAgICAgICAgIGZpbGVVcmlXaXRob3V0VHJhbnNmb3JtLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKS53aXRoQmVoYXZpb3JzKGNvbXB1dGVVcmkpKSkgeworICAgICAgdXJpRnV0dXJlID0gY29tcHV0ZVVyaS51cmlGdXR1cmUoKTsKKyAgICB9CisgICAgYXNzZXJ0VGhhdCh1cmlGdXR1cmUuZ2V0KCkpLmlzRXF1YWxUbyhmaWxlVXJpV2l0aG91dFRyYW5zZm9ybSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NDhhMWZmCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0JVSUxECkBAIC0wLDAgKzEsNDkgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xvY2FsX3Rlc3QiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJGcmFnbWVudFRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkZyYWdtZW50VGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbjpmcmFnbWVudCIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkdjUGFyYW1UZXN0IiwKKyAgICBzaXplID0gInNtYWxsIiwKKyAgICBzcmNzID0gWyJHY1BhcmFtVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkxvY2tTY29wZVRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkxvY2tTY29wZVRlc3QuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0ZyYWdtZW50VGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL0ZyYWdtZW50VGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI5ZmQyOTgKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vRnJhZ21lbnRUZXN0LmphdmEKQEAgLTAsMCArMSwzMjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUudGhpcmRwYXJ0eS5yb2JvbGVjdHJpYy5Hb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworCitAUnVuV2l0aChHb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgRnJhZ21lbnRUZXN0IHsKKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZGVyX2VtcHR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRnJhZ21lbnQuQnVpbGRlciBmcmFnbWVudCA9IEZyYWdtZW50LmJ1aWxkZXIoKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50LmJ1aWxkKCkudG9TdHJpbmcoKSkuaXNFbXB0eSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcGFyc2VfZW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGcmFnbWVudCBmcmFnbWVudCA9IEZyYWdtZW50LnBhcnNlKCIiKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50LnRvU3RyaW5nKCkpLmlzRW1wdHkoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHBhcnNlX3NpbXBsZVBhcmFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRnJhZ21lbnQgZnJhZ21lbnQgPSBGcmFnbWVudC5wYXJzZSgic2ltcGxlPXRydWUiKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50LnRvU3RyaW5nKCkpLmlzRXF1YWxUbygic2ltcGxlPXRydWUiKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50LnBhcmFtcygpLmdldCgwKS5rZXkoKSkuaXNFcXVhbFRvKCJzaW1wbGUiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGcmFnbWVudCBmcmFnbWVudCA9CisgICAgICAgIEZyYWdtZW50LmJ1aWxkZXIoKQorICAgICAgICAgICAgLmFkZFBhcmFtKAorICAgICAgICAgICAgICAgIEZyYWdtZW50LlBhcmFtLmJ1aWxkZXIoInBhcmFtS2V5IikKKyAgICAgICAgICAgICAgICAgICAgLmFkZFZhbHVlKAorICAgICAgICAgICAgICAgICAgICAgICAgRnJhZ21lbnQuUGFyYW1WYWx1ZS5idWlsZGVyKCJwYXJhbVZhbHVlIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkU3ViUGFyYW0oInN1YnBhcmFtS2V5IiwgInN1YnBhcmFtVmFsdWUiKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQoZnJhZ21lbnQudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCJwYXJhbUtleT1wYXJhbVZhbHVlKHN1YnBhcmFtS2V5PXN1YnBhcmFtVmFsdWUpIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBwYXJzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZyYWdtZW50IGZyYWdtZW50ID0gRnJhZ21lbnQucGFyc2UoInBhcmFtS2V5PXBhcmFtVmFsdWUoc3VicGFyYW1LZXk9c3VicGFyYW1WYWx1ZSkiKTsKKworICAgIGFzc2VydFRoYXQoZnJhZ21lbnQudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCJwYXJhbUtleT1wYXJhbVZhbHVlKHN1YnBhcmFtS2V5PXN1YnBhcmFtVmFsdWUpIik7CisKKyAgICBGcmFnbWVudC5QYXJhbSBwYXJhbSA9IGZyYWdtZW50LnBhcmFtcygpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KHBhcmFtLmtleSgpKS5pc0VxdWFsVG8oInBhcmFtS2V5Iik7CisgICAgRnJhZ21lbnQuUGFyYW1WYWx1ZSB2YWx1ZSA9IHBhcmFtLnZhbHVlcygpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KHZhbHVlLm5hbWUoKSkuaXNFcXVhbFRvKCJwYXJhbVZhbHVlIik7CisgICAgRnJhZ21lbnQuU3ViUGFyYW0gc3VicGFyYW0gPSB2YWx1ZS5zdWJQYXJhbXMoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChzdWJwYXJhbS5rZXkoKSkuaXNFcXVhbFRvKCJzdWJwYXJhbUtleSIpOworICAgIGFzc2VydFRoYXQoc3VicGFyYW0udmFsdWUoKSkuaXNFcXVhbFRvKCJzdWJwYXJhbVZhbHVlIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBwYXJzZV9tdWx0aXBsZVBhcmFtc0FuZHN1YlBhcmFtcygpIHRocm93cyBFeGNlcHRpb24geworICAgIEZyYWdtZW50IGZyYWdtZW50ID0gRnJhZ21lbnQucGFyc2UoImsxPXYxJmsyPXYyKHNrMT1zdjEpJmszPXYzKHNrMT1zdjEsc2syPXN2MixzazMpIik7CisKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50LnRvU3RyaW5nKCkpLmlzRXF1YWxUbygiazE9djEmazI9djIoc2sxPXN2MSkmazM9djMoc2sxPXN2MSxzazI9c3YyLHNrMykiKTsKKworICAgIEZyYWdtZW50LlBhcmFtIHAxID0gZnJhZ21lbnQucGFyYW1zKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQocDEua2V5KCkpLmlzRXF1YWxUbygiazEiKTsKKyAgICBGcmFnbWVudC5QYXJhbVZhbHVlIHYxID0gcDEudmFsdWVzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQodjEubmFtZSgpKS5pc0VxdWFsVG8oInYxIik7CisgICAgYXNzZXJ0VGhhdCh2MS5zdWJQYXJhbXMoKS5zaXplKCkpLmlzRXF1YWxUbygwKTsKKworICAgIEZyYWdtZW50LlBhcmFtIHAyID0gZnJhZ21lbnQucGFyYW1zKCkuZ2V0KDEpOworICAgIGFzc2VydFRoYXQocDIua2V5KCkpLmlzRXF1YWxUbygiazIiKTsKKyAgICBGcmFnbWVudC5QYXJhbVZhbHVlIHYyID0gcDIudmFsdWVzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQodjIubmFtZSgpKS5pc0VxdWFsVG8oInYyIik7CisgICAgYXNzZXJ0VGhhdCh2Mi5zdWJQYXJhbXMoKS5zaXplKCkpLmlzRXF1YWxUbygxKTsKKyAgICBGcmFnbWVudC5TdWJQYXJhbSBwMnMgPSB2Mi5zdWJQYXJhbXMoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChwMnMua2V5KCkpLmlzRXF1YWxUbygic2sxIik7CisgICAgYXNzZXJ0VGhhdChwMnMudmFsdWUoKSkuaXNFcXVhbFRvKCJzdjEiKTsKKworICAgIEZyYWdtZW50LlBhcmFtIHAzID0gZnJhZ21lbnQucGFyYW1zKCkuZ2V0KDIpOworICAgIGFzc2VydFRoYXQocDMua2V5KCkpLmlzRXF1YWxUbygiazMiKTsKKyAgICBGcmFnbWVudC5QYXJhbVZhbHVlIHYzID0gcDMudmFsdWVzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQodjMubmFtZSgpKS5pc0VxdWFsVG8oInYzIik7CisgICAgYXNzZXJ0VGhhdCh2My5zdWJQYXJhbXMoKS5zaXplKCkpLmlzRXF1YWxUbygzKTsKKyAgICBGcmFnbWVudC5TdWJQYXJhbSBwM3MxID0gdjMuc3ViUGFyYW1zKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQocDNzMS5rZXkoKSkuaXNFcXVhbFRvKCJzazEiKTsKKyAgICBhc3NlcnRUaGF0KHAzczEuaGFzVmFsdWUoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChwM3MxLnZhbHVlKCkpLmlzRXF1YWxUbygic3YxIik7CisgICAgRnJhZ21lbnQuU3ViUGFyYW0gcDNzMiA9IHYzLnN1YlBhcmFtcygpLmdldCgxKTsKKyAgICBhc3NlcnRUaGF0KHAzczIua2V5KCkpLmlzRXF1YWxUbygic2syIik7CisgICAgYXNzZXJ0VGhhdChwM3MyLmhhc1ZhbHVlKCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQocDNzMi52YWx1ZSgpKS5pc0VxdWFsVG8oInN2MiIpOworICAgIEZyYWdtZW50LlN1YlBhcmFtIHAzczMgPSB2My5zdWJQYXJhbXMoKS5nZXQoMik7CisgICAgYXNzZXJ0VGhhdChwM3MzLmtleSgpKS5pc0VxdWFsVG8oInNrMyIpOworICAgIGFzc2VydFRoYXQocDNzMy5oYXNWYWx1ZSgpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChwM3MzLnZhbHVlKCkpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVpbGRlcl9tdWx0aXBsZVZhbHVlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIEZyYWdtZW50IGZyYWdtZW50ID0KKyAgICAgICAgRnJhZ21lbnQuYnVpbGRlcigpCisgICAgICAgICAgICAuYWRkUGFyYW0oInVuc2V0IikKKyAgICAgICAgICAgIC5hZGRQYXJhbShGcmFnbWVudC5QYXJhbS5idWlsZGVyKCJrMSIpLmFkZFZhbHVlKCJ2MSIpKQorICAgICAgICAgICAgLmFkZFBhcmFtKAorICAgICAgICAgICAgICAgIEZyYWdtZW50LlBhcmFtLmJ1aWxkZXIoImsyIikKKyAgICAgICAgICAgICAgICAgICAgLmFkZFZhbHVlKCJ2MiIpCisgICAgICAgICAgICAgICAgICAgIC5hZGRWYWx1ZSgidjJhIikKKyAgICAgICAgICAgICAgICAgICAgLmFkZFZhbHVlKEZyYWdtZW50LlBhcmFtVmFsdWUuYnVpbGRlcigidjJiIikuYWRkU3ViUGFyYW0oInNrMSIsICJzdjEiKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQoZnJhZ21lbnQudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCJrMT12MSZrMj12Mit2MmErdjJiKHNrMT1zdjEpIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZGVyX25lc3RlZE11dGF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRnJhZ21lbnQuQnVpbGRlciBmcmFnbWVudCA9IEZyYWdtZW50LnBhcnNlKCJrMD12MGEmazE9djEmazI9djIrdjJhK3YyYihzazE9c3YxKSIpLnRvQnVpbGRlcigpOworCisgICAgZnJhZ21lbnQuZmluZFBhcmFtKCJrMCIpLmFkZFZhbHVlKCJ2MGIiKTsKKyAgICBmcmFnbWVudC5maW5kUGFyYW0oImsxIikuZmluZFZhbHVlKCJ2MSIpLmFkZFN1YlBhcmFtKCJzazEiLCAic3YxIik7CisgICAgZnJhZ21lbnQuZmluZFBhcmFtKCJrMiIpLmZpbmRWYWx1ZSgidjJiIikuYWRkU3ViUGFyYW0oInNrMiIsICJzdjIiKTsKKworICAgIGFzc2VydFRoYXQoZnJhZ21lbnQuYnVpbGQoKS50b1N0cmluZygpKQorICAgICAgICAuaXNFcXVhbFRvKCJrMD12MGErdjBiJmsxPXYxKHNrMT1zdjEpJmsyPXYyK3YyYSt2MmIoc2sxPXN2MSxzazI9c3YyKSIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcGFyc2VfbXVsdGlwbGVWYWx1ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGcmFnbWVudCBmcmFnbWVudCA9IEZyYWdtZW50LnBhcnNlKCJrMD12MCZrMT12MSZrMj12Mit2MmErdjJiKHNrMT1zdjEpIik7CisKKyAgICBGcmFnbWVudC5QYXJhbSBwMCA9IGZyYWdtZW50LnBhcmFtcygpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KHAwLmtleSgpKS5pc0VxdWFsVG8oImswIik7CisgICAgRnJhZ21lbnQuUGFyYW1WYWx1ZSB2MCA9IHAwLnZhbHVlcygpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KHYwLm5hbWUoKSkuaXNFcXVhbFRvKCJ2MCIpOworICAgIGFzc2VydFRoYXQodjAuc3ViUGFyYW1zKCkuaXNFbXB0eSgpKS5pc1RydWUoKTsKKworICAgIEZyYWdtZW50LlBhcmFtIHAxID0gZnJhZ21lbnQucGFyYW1zKCkuZ2V0KDEpOworICAgIGFzc2VydFRoYXQocDEua2V5KCkpLmlzRXF1YWxUbygiazEiKTsKKyAgICBGcmFnbWVudC5QYXJhbVZhbHVlIHYxID0gcDEudmFsdWVzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQodjEubmFtZSgpKS5pc0VxdWFsVG8oInYxIik7CisgICAgYXNzZXJ0VGhhdCh2MS5zdWJQYXJhbXMoKS5pc0VtcHR5KCkpLmlzVHJ1ZSgpOworCisgICAgRnJhZ21lbnQuUGFyYW0gcDIgPSBmcmFnbWVudC5wYXJhbXMoKS5nZXQoMik7CisgICAgYXNzZXJ0VGhhdChwMi5rZXkoKSkuaXNFcXVhbFRvKCJrMiIpOworICAgIEZyYWdtZW50LlBhcmFtVmFsdWUgdjIgPSBwMi52YWx1ZXMoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdCh2Mi5uYW1lKCkpLmlzRXF1YWxUbygidjIiKTsKKyAgICBhc3NlcnRUaGF0KHYyLnN1YlBhcmFtcygpLmlzRW1wdHkoKSkuaXNUcnVlKCk7CisKKyAgICBGcmFnbWVudC5QYXJhbVZhbHVlIHYyYSA9IHAyLnZhbHVlcygpLmdldCgxKTsKKyAgICBhc3NlcnRUaGF0KHYyYS5uYW1lKCkpLmlzRXF1YWxUbygidjJhIik7CisgICAgYXNzZXJ0VGhhdCh2MmEuc3ViUGFyYW1zKCkuaXNFbXB0eSgpKS5pc1RydWUoKTsKKworICAgIEZyYWdtZW50LlBhcmFtVmFsdWUgdjJiID0gcDIudmFsdWVzKCkuZ2V0KDIpOworICAgIGFzc2VydFRoYXQodjJiLm5hbWUoKSkuaXNFcXVhbFRvKCJ2MmIiKTsKKyAgICBhc3NlcnRUaGF0KHYyYi5zdWJQYXJhbXMoKS5zaXplKCkpLmlzRXF1YWxUbygxKTsKKyAgICBGcmFnbWVudC5TdWJQYXJhbSB2MmJzMSA9IHYyYi5zdWJQYXJhbXMoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdCh2MmJzMS5rZXkoKSkuaXNFcXVhbFRvKCJzazEiKTsKKyAgICBhc3NlcnRUaGF0KHYyYnMxLnZhbHVlKCkpLmlzRXF1YWxUbygic3YxIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBwYXJzZV9kdXBsaWNhdGVQYXJhbXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGcmFnbWVudCBmcmFnbWVudCA9IEZyYWdtZW50LnBhcnNlKCJrPTEmaz0yIik7CisgICAgYXNzZXJ0VGhhdChmcmFnbWVudC5wYXJhbXMoKS5nZXQoMCkudmFsdWVzKCkuZ2V0KDApLm5hbWUoKSkuaXNFcXVhbFRvKCIyIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBwYXJzZV9kdXBsaWNhdGVQYXJhbVZhbHVlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIEZyYWdtZW50IGZyYWdtZW50ID0gRnJhZ21lbnQucGFyc2UoIms9MSsxKHg9eSkiKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50LnBhcmFtcygpLmdldCgwKS52YWx1ZXMoKS5nZXQoMCkuZmluZFN1YlBhcmFtVmFsdWUoIngiKSkuaXNFcXVhbFRvKCJ5Iik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBwYXJzZV9kdXBsaWNhdGVzdWJQYXJhbXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGcmFnbWVudCBmcmFnbWVudCA9IEZyYWdtZW50LnBhcnNlKCJrPTEoeD15LHg9eikiKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50LnBhcmFtcygpLmdldCgwKS52YWx1ZXMoKS5nZXQoMCkuZmluZFN1YlBhcmFtVmFsdWUoIngiKSkuaXNFcXVhbFRvKCJ6Iik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBwYXJzZV9kdXBsaWNhdGVVbnNldFN1YlBhcmFtcygpIHRocm93cyBFeGNlcHRpb24geworICAgIEZyYWdtZW50IGZyYWdtZW50ID0gRnJhZ21lbnQucGFyc2UoIms9MSh4PXkseCkiKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50LnBhcmFtcygpLmdldCgwKS52YWx1ZXMoKS5nZXQoMCkuZmluZFN1YlBhcmFtKCJ4IikpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoZnJhZ21lbnQucGFyYW1zKCkuZ2V0KDApLnZhbHVlcygpLmdldCgwKS5maW5kU3ViUGFyYW0oIngiKS5oYXNWYWx1ZSgpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChmcmFnbWVudC5wYXJhbXMoKS5nZXQoMCkudmFsdWVzKCkuZ2V0KDApLmZpbmRTdWJQYXJhbVZhbHVlKCJ4IikpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcGFyc2VfdW5zZXRTdWJQYXJhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZyYWdtZW50IGZyYWdtZW50ID0gRnJhZ21lbnQucGFyc2UoInA9dihzcDEpIik7CisgICAgYXNzZXJ0VGhhdChmcmFnbWVudC5maW5kUGFyYW0oInAiKS5maW5kVmFsdWUoInYiKS5maW5kU3ViUGFyYW0oInNwMSIpKS5pc05vdE51bGwoKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50LmZpbmRQYXJhbSgicCIpLmZpbmRWYWx1ZSgidiIpLmZpbmRTdWJQYXJhbSgic3AxIikuaGFzVmFsdWUoKSkuaXNGYWxzZSgpOworICAgIGFzc2VydFRoYXQoZnJhZ21lbnQuZmluZFBhcmFtKCJwIikuZmluZFZhbHVlKCJ2IikuZmluZFN1YlBhcmFtVmFsdWUoInNwMSIpKS5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJvdW5kVHJpcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZyYWdtZW50IGZyYWdtZW50ID0gRnJhZ21lbnQucGFyc2UoImE9YiZjPWQoZT1mLGc9aCxpPWopK2UrZiIpOworCisgICAgYXNzZXJ0VGhhdChmcmFnbWVudC50b1N0cmluZygpKS5pc0VxdWFsVG8oImE9YiZjPWQoZT1mLGc9aCxpPWopK2UrZiIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcGFyc2VfaWxsZWdhbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEZyYWdtZW50LnBhcnNlKCJ4IikpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEZyYWdtZW50LnBhcnNlKCJ4PSIpKTsKKworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEZyYWdtZW50LnBhcnNlKCI9IikpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEZyYWdtZW50LnBhcnNlKCI9PSIpKTsKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBGcmFnbWVudC5wYXJzZSgiPXgiKSk7CisKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBGcmFnbWVudC5wYXJzZSgieD15KCIpKTsKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBGcmFnbWVudC5wYXJzZSgieD15KSIpKTsKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBGcmFnbWVudC5wYXJzZSgieD15KCkiKSk7CisKKyAgICBhc3NlcnRUaHJvd3MoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBGcmFnbWVudC5wYXJzZSgieD15KD0pIikpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEZyYWdtZW50LnBhcnNlKCJ4PXkoPT0pIikpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsICgpIC0+IEZyYWdtZW50LnBhcnNlKCJ4PXkoPXopIikpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcGFyc2Vfd2VpcmRCdXROb3RJbGxlZ2FsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVW5lbmNvZGVkIGNoYXJzIGdldHMgZW5jb2RlZAorICAgIGFzc2VydFRoYXQoRnJhZ21lbnQucGFyc2UoIiA9eSIpLnRvU3RyaW5nKCkpLmlzRXF1YWxUbygiKz15Iik7CisgICAgYXNzZXJ0VGhhdChGcmFnbWVudC5wYXJzZSgiIHg9eSAiKS50b1N0cmluZygpKS5pc0VxdWFsVG8oIit4PXkrIik7CisgICAgYXNzZXJ0VGhhdChGcmFnbWVudC5wYXJzZSgiKCk9eSIpLnRvU3RyaW5nKCkpLmlzRXF1YWxUbygiJTI4JTI5PXkiKTsKKyAgICBhc3NlcnRUaGF0KEZyYWdtZW50LnBhcnNlKCJ4PT15IikudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCJ4PSUzRHkiKTsKKyAgICBhc3NlcnRUaGF0KEZyYWdtZW50LnBhcnNlKCJ4PXkoej09KSIpLnRvU3RyaW5nKCkpLmlzRXF1YWxUbygieD15KHo9JTNEKSIpOworCisgICAgYXNzZXJ0VGhhdChGcmFnbWVudC5wYXJzZSgieD15KHo9KSIpLnRvU3RyaW5nKCkpLmlzRXF1YWxUbygieD15KHopIik7CisgICAgYXNzZXJ0VGhhdChGcmFnbWVudC5wYXJzZSgiKz15IikudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCIrPXkiKTsKKyAgICBhc3NlcnRUaGF0KEZyYWdtZW50LnBhcnNlKCIiKS50b1N0cmluZygpKS5pc0VtcHR5KCk7CisgICAgYXNzZXJ0VGhhdChGcmFnbWVudC5wYXJzZSgoU3RyaW5nKSBudWxsKS50b1N0cmluZygpKS5pc0VtcHR5KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBidWlsZF9lc2NhcGluZ0ludmFsaWRDaGFyYWN0ZXJzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRnJhZ21lbnQgZnJhZ21lbnQgPQorICAgICAgICBGcmFnbWVudC5idWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRQYXJhbSgKKyAgICAgICAgICAgICAgICBGcmFnbWVudC5QYXJhbS5idWlsZGVyKCJtJm0iKQorICAgICAgICAgICAgICAgICAgICAuYWRkVmFsdWUoRnJhZ21lbnQuUGFyYW1WYWx1ZS5idWlsZGVyKCIyKzIiKS5hZGRTdWJQYXJhbSgiaz0iLCAiKHYpIikpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChmcmFnbWVudC50b1N0cmluZygpKS5pc0VxdWFsVG8oIm0lMjZtPTIlMkIyKGslM0Q9JTI4diUyOSkiKTsKKworICAgIEZyYWdtZW50IHJvdW5kdHJpcCA9IEZyYWdtZW50LnBhcnNlKGZyYWdtZW50LnRvU3RyaW5nKCkpOworICAgIEZyYWdtZW50LlBhcmFtIG1ubSA9IHJvdW5kdHJpcC5wYXJhbXMoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChtbm0ua2V5KCkpLmlzRXF1YWxUbygibSZtIik7CisgICAgRnJhZ21lbnQuUGFyYW1WYWx1ZSB0d29wdHdvID0gbW5tLnZhbHVlcygpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KHR3b3B0d28ubmFtZSgpKS5pc0VxdWFsVG8oIjIrMiIpOworICAgIEZyYWdtZW50LlN1YlBhcmFtIHBxcCA9IHR3b3B0d28uc3ViUGFyYW1zKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQocHFwLmtleSgpKS5pc0VxdWFsVG8oIms9Iik7CisgICAgYXNzZXJ0VGhhdChwcXAudmFsdWUoKSkuaXNFcXVhbFRvKCIodikiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRvQnVpbGRlcl9zaG91bGRNYWtlRGVmZW5zaXZlQ29weSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZyYWdtZW50IGZyYWdtZW50ID0gRnJhZ21lbnQucGFyc2UoImE9YihjPWQpIik7CisgICAgRnJhZ21lbnQuQnVpbGRlciBmcmFnbWVudEJ1aWxkZXIgPSBmcmFnbWVudC50b0J1aWxkZXIoKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50LnRvU3RyaW5nKCkpLmlzRXF1YWxUbygiYT1iKGM9ZCkiKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50QnVpbGRlci5idWlsZCgpLnRvU3RyaW5nKCkpLmlzRXF1YWxUbygiYT1iKGM9ZCkiKTsKKworICAgIGZyYWdtZW50QnVpbGRlci5hZGRQYXJhbShGcmFnbWVudC5QYXJhbS5idWlsZGVyKCJYIikuYWRkVmFsdWUoIlhYIikpOworICAgIGZyYWdtZW50QnVpbGRlci5maW5kUGFyYW0oImEiKS5hZGRWYWx1ZSgiWSIpOworICAgIGZyYWdtZW50QnVpbGRlci5maW5kUGFyYW0oImEiKS5maW5kVmFsdWUoImIiKS5hZGRTdWJQYXJhbSgiWiIsICJaWiIpOworCisgICAgYXNzZXJ0VGhhdChmcmFnbWVudC50b1N0cmluZygpKS5pc0VxdWFsVG8oImE9YihjPWQpIik7CisgICAgYXNzZXJ0VGhhdChmcmFnbWVudEJ1aWxkZXIuYnVpbGQoKS50b1N0cmluZygpKS5pc0VxdWFsVG8oImE9YihjPWQsWj1aWikrWSZYPVhYIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cmlfd2l0aFZhbGlkQ2hhcmFjdGVycygpIHRocm93cyBFeGNlcHRpb24geworICAgIFN0cmluZyBlbmNvZGVkRnJhZ21lbnRTdHJpbmcgPSAiYT1iK2MoZD1lKSI7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiYTovL2IvYyIpLmJ1aWxkVXBvbigpLmVuY29kZWRGcmFnbWVudChlbmNvZGVkRnJhZ21lbnRTdHJpbmcpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdCh1cmkudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCJhOi8vYi9jI2E9YitjKGQ9ZSkiKTsKKyAgICBhc3NlcnRUaGF0KHVyaS5nZXRFbmNvZGVkRnJhZ21lbnQoKSkuaXNFcXVhbFRvKGVuY29kZWRGcmFnbWVudFN0cmluZyk7CisgICAgRnJhZ21lbnQgcm91bmR0cmlwID0gRnJhZ21lbnQucGFyc2UodXJpKTsKKyAgICBGcmFnbWVudC5QYXJhbSBhID0gcm91bmR0cmlwLnBhcmFtcygpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KGEua2V5KCkpLmlzRXF1YWxUbygiYSIpOworICAgIEZyYWdtZW50LlBhcmFtVmFsdWUgYiA9IGEudmFsdWVzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoYi5uYW1lKCkpLmlzRXF1YWxUbygiYiIpOworICAgIEZyYWdtZW50LlBhcmFtVmFsdWUgYyA9IGEudmFsdWVzKCkuZ2V0KDEpOworICAgIGFzc2VydFRoYXQoYy5uYW1lKCkpLmlzRXF1YWxUbygiYyIpOworICAgIEZyYWdtZW50LlN1YlBhcmFtIGRlID0gYy5zdWJQYXJhbXMoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChkZS5rZXkoKSkuaXNFcXVhbFRvKCJkIik7CisgICAgYXNzZXJ0VGhhdChkZS52YWx1ZSgpKS5pc0VxdWFsVG8oImUiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVyaV93aXRoSW52YWxpZENoYXJhY3RlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgZW5jb2RlZEZyYWdtZW50U3RyaW5nID0gIm0lMjZtPTIlMkIyKGslM0Q9JTI4diUyOSkiOworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImE6Ly9iL2MiKS5idWlsZFVwb24oKS5lbmNvZGVkRnJhZ21lbnQoZW5jb2RlZEZyYWdtZW50U3RyaW5nKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQodXJpLnRvU3RyaW5nKCkpLmlzRXF1YWxUbygiYTovL2IvYyNtJTI2bT0yJTJCMihrJTNEPSUyOHYlMjkpIik7CisgICAgYXNzZXJ0VGhhdCh1cmkuZ2V0RW5jb2RlZEZyYWdtZW50KCkpLmlzRXF1YWxUbyhlbmNvZGVkRnJhZ21lbnRTdHJpbmcpOworICAgIEZyYWdtZW50IHJvdW5kdHJpcCA9IEZyYWdtZW50LnBhcnNlKHVyaSk7CisgICAgRnJhZ21lbnQuUGFyYW0gbW5tID0gcm91bmR0cmlwLnBhcmFtcygpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KG1ubS5rZXkoKSkuaXNFcXVhbFRvKCJtJm0iKTsKKyAgICBGcmFnbWVudC5QYXJhbVZhbHVlIHR3b3B0d28gPSBtbm0udmFsdWVzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQodHdvcHR3by5uYW1lKCkpLmlzRXF1YWxUbygiMisyIik7CisgICAgRnJhZ21lbnQuU3ViUGFyYW0gcHFwID0gdHdvcHR3by5zdWJQYXJhbXMoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChwcXAua2V5KCkpLmlzRXF1YWxUbygiaz0iKTsKKyAgICBhc3NlcnRUaGF0KHBxcC52YWx1ZSgpKS5pc0VxdWFsVG8oIih2KSIpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vR2NQYXJhbVRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9HY1BhcmFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3OGVhZDMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vR2NQYXJhbVRlc3QuamF2YQpAQCAtMCwwICsxLDk2IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbjsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKKworaW1wb3J0IGNvbS5nb29nbGUudGhpcmRwYXJ0eS5yb2JvbGVjdHJpYy5Hb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CitpbXBvcnQgamF2YS51dGlsLkRhdGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworCitAUnVuV2l0aChHb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgY2xhc3MgR2NQYXJhbVRlc3QgeworCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG5vbmVfc2hvdWxkSGF2ZU5vbmVUYWdBbmROb0V4cGlyYXRpb24oKSB7CisgICAgR2NQYXJhbSBub25lID0gR2NQYXJhbS5ub25lKCk7CisgICAgYXNzZXJ0VGhhdChub25lKS5pc05vdE51bGwoKTsKKyAgICBhc3NlcnRUaGF0KG5vbmUuaXNFeHBpcmVzQXQoKSkuaXNGYWxzZSgpOworICAgIGFzc2VydFRocm93cyhJbGxlZ2FsU3RhdGVFeGNlcHRpb24uY2xhc3MsICgpIC0+IG5vbmUuZ2V0RXhwaXJhdGlvbigpKTsKKyAgICBhc3NlcnRUaGF0KG5vbmUuaXNOb25lKCkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZXhwaXJlc0F0X3Nob3VsZEhhdmVFeHBpcmVzQXRUYWdBbmRFeHBpcmF0aW9uKCkgeworCisgICAgRGF0ZSBkYXRlMSA9IG5ldyBEYXRlKDFMKTsKKyAgICBEYXRlIGRhdGUyID0gbmV3IERhdGUoMkwpOworICAgIEdjUGFyYW0gZXhwaXJlc0F0MSA9IEdjUGFyYW0uZXhwaXJlc0F0KGRhdGUxKTsKKyAgICBHY1BhcmFtIGV4cGlyZXNBdDIgPSBHY1BhcmFtLmV4cGlyZXNBdChkYXRlMik7CisKKyAgICBhc3NlcnRUaGF0KGV4cGlyZXNBdDEpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoZXhwaXJlc0F0MikuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChleHBpcmVzQXQxLmlzTm9uZSgpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChleHBpcmVzQXQyLmlzTm9uZSgpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChleHBpcmVzQXQxLmlzRXhwaXJlc0F0KCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoZXhwaXJlc0F0Mi5pc0V4cGlyZXNBdCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGV4cGlyZXNBdDEuZ2V0RXhwaXJhdGlvbigpKS5pc0VxdWFsVG8oZGF0ZTEpOworICAgIGFzc2VydFRoYXQoZXhwaXJlc0F0Mi5nZXRFeHBpcmF0aW9uKCkpLmlzRXF1YWxUbyhkYXRlMik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBlcXVhbHNfc2hvdWxkQ29tcGFyZURhdGFNZW1iZXJzKCkgeworCisgICAgR2NQYXJhbSBleHBpcmVzQXQxID0gR2NQYXJhbS5leHBpcmVzQXQobmV3IERhdGUoMUwpKTsKKyAgICBHY1BhcmFtIGV4cGlyZXNBdDIgPSBHY1BhcmFtLmV4cGlyZXNBdChuZXcgRGF0ZSgyTCkpOworICAgIEdjUGFyYW0gZXhwaXJlc0F0MWIgPSBHY1BhcmFtLmV4cGlyZXNBdChuZXcgRGF0ZSgxTCkpOworICAgIEdjUGFyYW0gbm9uZTEgPSBHY1BhcmFtLm5vbmUoKTsKKyAgICBHY1BhcmFtIG5vbmUyID0gR2NQYXJhbS5ub25lKCk7CisKKyAgICBhc3NlcnRUaGF0KGV4cGlyZXNBdDEpLmlzTm90RXF1YWxUbyhudWxsKTsKKyAgICBhc3NlcnRUaGF0KGV4cGlyZXNBdDIpLmlzTm90RXF1YWxUbyhudWxsKTsKKyAgICBhc3NlcnRUaGF0KGV4cGlyZXNBdDFiKS5pc05vdEVxdWFsVG8obnVsbCk7CisgICAgYXNzZXJ0VGhhdChub25lMSkuaXNOb3RFcXVhbFRvKG51bGwpOworICAgIGFzc2VydFRoYXQobm9uZTIpLmlzTm90RXF1YWxUbyhudWxsKTsKKworICAgIGFzc2VydFRoYXQoZXhwaXJlc0F0MSkuaXNOb3RFcXVhbFRvKGV4cGlyZXNBdDIpOworICAgIGFzc2VydFRoYXQoZXhwaXJlc0F0MSkuaXNFcXVhbFRvKGV4cGlyZXNBdDFiKTsKKyAgICBhc3NlcnRUaGF0KGV4cGlyZXNBdDEpLmlzTm90RXF1YWxUbyhub25lMSk7CisgICAgYXNzZXJ0VGhhdChleHBpcmVzQXQxKS5pc05vdEVxdWFsVG8obm9uZTIpOworCisgICAgYXNzZXJ0VGhhdChleHBpcmVzQXQyKS5pc05vdEVxdWFsVG8oZXhwaXJlc0F0MSk7CisgICAgYXNzZXJ0VGhhdChleHBpcmVzQXQyKS5pc05vdEVxdWFsVG8oZXhwaXJlc0F0MWIpOworICAgIGFzc2VydFRoYXQoZXhwaXJlc0F0MikuaXNOb3RFcXVhbFRvKG5vbmUxKTsKKyAgICBhc3NlcnRUaGF0KGV4cGlyZXNBdDIpLmlzTm90RXF1YWxUbyhub25lMik7CisKKyAgICBhc3NlcnRUaGF0KGV4cGlyZXNBdDFiKS5pc0VxdWFsVG8oZXhwaXJlc0F0MSk7CisgICAgYXNzZXJ0VGhhdChleHBpcmVzQXQxYikuaXNOb3RFcXVhbFRvKGV4cGlyZXNBdDIpOworICAgIGFzc2VydFRoYXQoZXhwaXJlc0F0MWIpLmlzTm90RXF1YWxUbyhub25lMSk7CisgICAgYXNzZXJ0VGhhdChleHBpcmVzQXQxYikuaXNOb3RFcXVhbFRvKG5vbmUyKTsKKworICAgIGFzc2VydFRoYXQobm9uZTEpLmlzTm90RXF1YWxUbyhleHBpcmVzQXQxKTsKKyAgICBhc3NlcnRUaGF0KG5vbmUxKS5pc05vdEVxdWFsVG8oZXhwaXJlc0F0Mik7CisgICAgYXNzZXJ0VGhhdChub25lMSkuaXNOb3RFcXVhbFRvKGV4cGlyZXNBdDFiKTsKKyAgICBhc3NlcnRUaGF0KG5vbmUxKS5pc0VxdWFsVG8obm9uZTIpOworCisgICAgYXNzZXJ0VGhhdChub25lMikuaXNOb3RFcXVhbFRvKGV4cGlyZXNBdDEpOworICAgIGFzc2VydFRoYXQobm9uZTIpLmlzTm90RXF1YWxUbyhleHBpcmVzQXQyKTsKKyAgICBhc3NlcnRUaGF0KG5vbmUyKS5pc05vdEVxdWFsVG8oZXhwaXJlc0F0MWIpOworICAgIGFzc2VydFRoYXQobm9uZTIpLmlzRXF1YWxUbyhub25lMSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9Mb2NrU2NvcGVUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vTG9ja1Njb3BlVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY3ZmU4OGQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vTG9ja1Njb3BlVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUudGhpcmRwYXJ0eS5yb2JvbGVjdHJpYy5Hb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db25jdXJyZW50SGFzaE1hcDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db25jdXJyZW50TWFwOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlNlbWFwaG9yZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CisKK0BSdW5XaXRoKEdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBMb2NrU2NvcGVUZXN0IHsKKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjcmVhdGVXaXRoU2hhcmVkVGhyZWFkTG9ja3Nfc2hhcmVzVGhyZWFkTG9ja3NBY3Jvc3NJbnN0YW5jZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIENvbmN1cnJlbnRNYXA8U3RyaW5nLCBTZW1hcGhvcmU+IGxvY2tNYXAgPSBuZXcgQ29uY3VycmVudEhhc2hNYXA8PigpOworICAgIExvY2tTY29wZSBsb2NrU2NvcGUgPSBMb2NrU2NvcGUuY3JlYXRlV2l0aEV4aXN0aW5nVGhyZWFkTG9ja3MobG9ja01hcCk7CisgICAgTG9ja1Njb3BlIG90aGVyTG9ja1Njb3BlID0gTG9ja1Njb3BlLmNyZWF0ZVdpdGhFeGlzdGluZ1RocmVhZExvY2tzKGxvY2tNYXApOworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImZpbGU6Ly8vZHVtbXkiKTsKKworICAgIHRyeSAoTG9jayBsb2NrID0gbG9ja1Njb3BlLnRocmVhZExvY2sodXJpKSkgeworICAgICAgYXNzZXJ0VGhhdChvdGhlckxvY2tTY29wZS50cnlUaHJlYWRMb2NrKHVyaSkpLmlzTnVsbCgpOworICAgIH0KKworICAgIGFzc2VydFRoYXQob3RoZXJMb2NrU2NvcGUudHJ5VGhyZWFkTG9jayh1cmkpKS5pc05vdE51bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNyZWF0ZVdpdGhGYWlsaW5nVGhyZWFkTG9ja3Nfd2lsbEZhaWxUb0FjcXVpcmVUaHJlYWRMb2NrcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgTG9ja1Njb3BlIGxvY2tTY29wZSA9IExvY2tTY29wZS5jcmVhdGVXaXRoRmFpbGluZ1RocmVhZExvY2tzKCk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiZmlsZTovLy9kdW1teSIpOworCisgICAgYXNzZXJ0VGhyb3dzKFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24uY2xhc3MsICgpIC0+IGxvY2tTY29wZS50aHJlYWRMb2NrKHVyaSkpOworICAgIGFzc2VydFRoYXQobG9ja1Njb3BlLnRyeVRocmVhZExvY2sodXJpKSkuaXNOdWxsKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOTZkNmE2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0JVSUxECkBAIC0wLDAgKzEsNjQgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xvY2FsX3Rlc3QiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJCYWNrZW5kSW5wdXRTdHJlYW1UZXN0IiwKKyAgICBzaXplID0gInNtYWxsIiwKKyAgICBzcmNzID0gWyJCYWNrZW5kSW5wdXRTdHJlYW1UZXN0LmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsOmJhY2tlbmRfc3RyZWFtIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiQmFja2VuZE91dHB1dFN0cmVhbVRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkJhY2tlbmRPdXRwdXRTdHJlYW1UZXN0LmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsOmJhY2tlbmRfc3RyZWFtIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtVGVzdCIsCisgICAgc2l6ZSA9ICJzbWFsbCIsCisgICAgc3JjcyA9IFsiTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpsYXp5X3N0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkxpdGVUcmFuc2Zvcm1GcmFnbWVudHNUZXN0IiwKKyAgICBzaXplID0gInNtYWxsIiwKKyAgICBzcmNzID0gWyJMaXRlVHJhbnNmb3JtRnJhZ21lbnRzVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbjpmcmFnbWVudCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWw6bGl0ZV90cmFuc2Zvcm1fZnJhZ21lbnRzIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9CYWNrZW5kSW5wdXRTdHJlYW1UZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvQmFja2VuZElucHV0U3RyZWFtVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1YmQzZmUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvQmFja2VuZElucHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMubWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQ7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMud3JpdGVGaWxlVG9TaW5rOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworCitpbXBvcnQgY29tLmdvb2dsZS50aGlyZHBhcnR5LnJvYm9sZWN0cmljLkdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRlbXBvcmFyeUZvbGRlcjsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CisKKy8qKiBCYXNpYyBzYW5pdHkgdGVzdHMgZm9yIEJhY2tlbmRJbnB1dFN0cmVhbTsgbW9yZSBjb21wbGV4IGJlaGF2aW9ycyBhcmUgdGVzdGVkIGVsc2V3aGVyZS4gKi8KK0BSdW5XaXRoKEdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBCYWNrZW5kSW5wdXRTdHJlYW1UZXN0IHsKKworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5Rm9sZGVyIHRtcEZvbGRlciA9IG5ldyBUZW1wb3JhcnlGb2xkZXIoKTsKKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0b0ZpbGVfcmV0dXJuc0lucHV0RmlsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZSBmaWxlID0gdG1wRm9sZGVyLm5ld0ZpbGUoKTsKKyAgICB0cnkgKEJhY2tlbmRJbnB1dFN0cmVhbSBzdHJlYW0gPSBCYWNrZW5kSW5wdXRTdHJlYW0uY3JlYXRlKGZpbGUpKSB7CisgICAgICBhc3NlcnRUaGF0KHN0cmVhbS50b0ZpbGUoKSkuaXNTYW1lSW5zdGFuY2VBcyhmaWxlKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0b0ZpbGVDaGFubmVsX3JldHVybnNJbnB1dEZpbGVDaGFubmVsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZpbGUgPSB0bXBGb2xkZXIubmV3RmlsZSgpOworICAgIHdyaXRlRmlsZVRvU2luayhuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlKSwgbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoNSkpOworICAgIHRyeSAoQmFja2VuZElucHV0U3RyZWFtIHN0cmVhbSA9IEJhY2tlbmRJbnB1dFN0cmVhbS5jcmVhdGUoZmlsZSkpIHsKKyAgICAgIGFzc2VydFRoYXQoc3RyZWFtLnRvRmlsZUNoYW5uZWwoKS5zaXplKCkpLmlzRXF1YWxUbyg1KTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9CYWNrZW5kT3V0cHV0U3RyZWFtVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0JhY2tlbmRPdXRwdXRTdHJlYW1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDZkNjExMAotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbC9CYWNrZW5kT3V0cHV0U3RyZWFtVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMubWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQ7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMud3JpdGVGaWxlVG9TaW5rOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworCitpbXBvcnQgY29tLmdvb2dsZS50aGlyZHBhcnR5LnJvYm9sZWN0cmljLkdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRlbXBvcmFyeUZvbGRlcjsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CisKKy8qKiBCYXNpYyBzYW5pdHkgdGVzdHMgZm9yIEJhY2tlbmRPdXRwdXRTdHJlYW07IG1vcmUgY29tcGxleCBiZWhhdmlvcnMgYXJlIHRlc3RlZCBlbHNld2hlcmUuICovCitAUnVuV2l0aChHb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgQmFja2VuZE91dHB1dFN0cmVhbVRlc3QgeworCisgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlGb2xkZXIgdG1wRm9sZGVyID0gbmV3IFRlbXBvcmFyeUZvbGRlcigpOworCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRvRmlsZV9yZXR1cm5zSW5wdXRGaWxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZpbGUgPSB0bXBGb2xkZXIubmV3RmlsZSgpOworICAgIHRyeSAoQmFja2VuZE91dHB1dFN0cmVhbSBzdHJlYW0gPSBCYWNrZW5kT3V0cHV0U3RyZWFtLmNyZWF0ZUZvcldyaXRlKGZpbGUpKSB7CisgICAgICBhc3NlcnRUaGF0KHN0cmVhbS50b0ZpbGUoKSkuaXNTYW1lSW5zdGFuY2VBcyhmaWxlKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0b0ZpbGVDaGFubmVsX3JldHVybnNJbnB1dEZpbGVDaGFubmVsKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBGaWxlIGZpbGUgPSB0bXBGb2xkZXIubmV3RmlsZSgpOworICAgIHdyaXRlRmlsZVRvU2luayhuZXcgRmlsZU91dHB1dFN0cmVhbShmaWxlKSwgbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoNSkpOworICAgIHRyeSAoQmFja2VuZE91dHB1dFN0cmVhbSBzdHJlYW0gPSBCYWNrZW5kT3V0cHV0U3RyZWFtLmNyZWF0ZUZvckFwcGVuZChmaWxlKSkgeworICAgICAgYXNzZXJ0VGhhdChzdHJlYW0udG9GaWxlQ2hhbm5lbCgpLnNpemUoKSkuaXNFcXVhbFRvKDUpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHN5bmNfZmx1c2hlc1N0cmVhbSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZSBmaWxlID0gdG1wRm9sZGVyLm5ld0ZpbGUoKTsKKyAgICB0cnkgKEJhY2tlbmRPdXRwdXRTdHJlYW0gc3RyZWFtID0gQmFja2VuZE91dHB1dFN0cmVhbS5jcmVhdGVGb3JXcml0ZShmaWxlKSkgeworICAgICAgLy8gTk9URTogdGVzdGluZyBzeW5jKCkgYmVoYXZpb3IgcmVxdWlyZXMgYW4gYW5kcm9pZF9lbXVsYXRvcl90ZXN0IGFuZCBpcyBjb3ZlcmVkIGJ5CisgICAgICAvLyBTeW5jaW5nQmVoYXZpb3JBbmRyb2lkVGVzdC4gSW4gdGhlIGludGVyZXN0IG9mIHF1aWNrIHRlc3RzLCBqdXN0IGVuc3VyZSB0aGlzIGRvZXNuJ3QgZmFpbC4KKyAgICAgIHN0cmVhbS5zeW5jKCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0xhenlCeXRlQXJyYXlJbnB1dFN0cmVhbVRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wODc3N2VjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0xhenlCeXRlQXJyYXlJbnB1dFN0cmVhbVRlc3QuamF2YQpAQCAtMCwwICsxLDE1NCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uaW50ZXJuYWw7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5yZWFkRmlsZUZyb21Tb3VyY2U7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0cy5VVEZfODsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBjb20uZ29vZ2xlLnRoaXJkcGFydHkucm9ib2xlY3RyaWMuR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5DYWxsYWJsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CisKK0BSdW5XaXRoKEdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBMYXp5Qnl0ZUFycmF5SW5wdXRTdHJlYW1UZXN0IHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09OVEVOVCA9ICJUaGUgZml2ZSBib3hpbmcgd2l6YXJkcyBqdW1wIHF1aWNrbHkiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDYWxsYWJsZTxieXRlW10+IENPTlRFTlRfQ0FMTEFCTEUgPSAoKSAtPiBDT05URU5ULmdldEJ5dGVzKFVURl84KTsKKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjYWxsYWJsZUlzQ2FsbGVkTGF6aWx5RXhhY3RseU9uY2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFNweUNhbGxhYmxlPGJ5dGVbXT4gc3B5ID0gbmV3IFNweUNhbGxhYmxlPGJ5dGVbXT4oQ09OVEVOVF9DQUxMQUJMRSk7CisgICAgSW5wdXRTdHJlYW0gc3RyZWFtID0gbmV3IExhenlCeXRlQXJyYXlJbnB1dFN0cmVhbShzcHkpOworCisgICAgYXNzZXJ0VGhhdChzcHkuY2FsbENvdW50KCkpLmlzRXF1YWxUbygwKTsKKyAgICBzdHJlYW0ucmVhZCgpOworICAgIHN0cmVhbS5yZWFkKCk7CisgICAgYXNzZXJ0VGhhdChzcHkuY2FsbENvdW50KCkpLmlzRXF1YWxUbygxKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGV4Y2VwdGlvbkZyb21DYWxsYWJsZUlzV3JhcHBlZEFuZFByb3BhZ2F0ZWQoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIENhbGxhYmxlPGJ5dGVbXT4gZ2VuZXJpY1Rocm93ZXIgPQorICAgICAgICAoKSAtPiB7CisgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiZ2VuZXJpYyIpOworICAgICAgICB9OworICAgIElucHV0U3RyZWFtIGdlbmVyaWNTdHJlYW0gPSBuZXcgTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtKGdlbmVyaWNUaHJvd2VyKTsKKyAgICBJT0V4Y2VwdGlvbiBnZW5lcmljVGhyb3duID0gYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBnZW5lcmljU3RyZWFtLnJlYWQoKSk7CisgICAgYXNzZXJ0VGhhdChnZW5lcmljVGhyb3duKS5oYXNDYXVzZVRoYXQoKS5oYXNNZXNzYWdlVGhhdCgpLmlzRXF1YWxUbygiZ2VuZXJpYyIpOworCisgICAgQ2FsbGFibGU8Ynl0ZVtdPiBpb0NhbGxhYmxlID0KKyAgICAgICAgKCkgLT4geworICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigiaW8iKTsKKyAgICAgICAgfTsKKyAgICBJbnB1dFN0cmVhbSBpb1N0cmVhbSA9IG5ldyBMYXp5Qnl0ZUFycmF5SW5wdXRTdHJlYW0oaW9DYWxsYWJsZSk7CisgICAgSU9FeGNlcHRpb24gaW9UaHJvd24gPSBhc3NlcnRUaHJvd3MoSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IGlvU3RyZWFtLnJlYWQoKSk7CisgICAgYXNzZXJ0VGhhdChpb1Rocm93bikuaGFzTWVzc2FnZVRoYXQoKS5pc0VxdWFsVG8oImlvIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBhdmFpbGFibGVfb25TdHJlYW1UaGF0SGFzTm90QmVlblJlYWRfcmV0dXJuc1plcm8oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFNweUNhbGxhYmxlPGJ5dGVbXT4gc3B5ID0gbmV3IFNweUNhbGxhYmxlPGJ5dGVbXT4oQ09OVEVOVF9DQUxMQUJMRSk7CisgICAgSW5wdXRTdHJlYW0gc3RyZWFtID0gbmV3IExhenlCeXRlQXJyYXlJbnB1dFN0cmVhbShzcHkpOworCisgICAgYXNzZXJ0VGhhdChzdHJlYW0uYXZhaWxhYmxlKCkpLmlzRXF1YWxUbygwKTsKKyAgICBhc3NlcnRUaGF0KHNweS5jYWxsQ291bnQoKSkuaXNFcXVhbFRvKDApOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYXZhaWxhYmxlX3JldHVybnNSZW1haW5pbmdDYWxsYWJsZUJ5dGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBJbnB1dFN0cmVhbSBzdHJlYW0gPSBuZXcgTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtKENPTlRFTlRfQ0FMTEFCTEUpOworCisgICAgc3RyZWFtLnNraXAoMyk7CisgICAgYXNzZXJ0VGhhdChzdHJlYW0uYXZhaWxhYmxlKCkpLmlzRXF1YWxUbyhDT05URU5ULmxlbmd0aCgpIC0gMyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjbG9zZV9jYWxsc0NhbGxhYmxlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBTcHlDYWxsYWJsZTxieXRlW10+IHNweSA9IG5ldyBTcHlDYWxsYWJsZTxieXRlW10+KENPTlRFTlRfQ0FMTEFCTEUpOworICAgIElucHV0U3RyZWFtIHN0cmVhbSA9IG5ldyBMYXp5Qnl0ZUFycmF5SW5wdXRTdHJlYW0oc3B5KTsKKworICAgIHN0cmVhbS5jbG9zZSgpOworICAgIGFzc2VydFRoYXQoc3B5LmNhbGxDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZWFkX3JldHVybnNDYWxsYWJsZUJ5dGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBJbnB1dFN0cmVhbSBzdHJlYW0gPSBuZXcgTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtKENPTlRFTlRfQ0FMTEFCTEUpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVGcm9tU291cmNlKHN0cmVhbSkpLmlzRXF1YWxUbyhDT05URU5UKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHNraXBfc2tpcHNDYWxsYWJsZUJ5dGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBJbnB1dFN0cmVhbSBzdHJlYW0gPSBuZXcgTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtKENPTlRFTlRfQ0FMTEFCTEUpOworICAgIHN0cmVhbS5za2lwKDUpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVGcm9tU291cmNlKHN0cmVhbSkpLmlzRXF1YWxUbyhDT05URU5ULnN1YnN0cmluZyg1KSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtYXJrU3VwcG9ydGVkX3JldHVybnNUcnVlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBJbnB1dFN0cmVhbSBzdHJlYW0gPSBuZXcgTGF6eUJ5dGVBcnJheUlucHV0U3RyZWFtKENPTlRFTlRfQ0FMTEFCTEUpOworICAgIGFzc2VydFRoYXQoc3RyZWFtLm1hcmtTdXBwb3J0ZWQoKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZXNldF9mcm9tRmlyc3RCeXRlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAvLyBSZWFkIHdob2xlIHN0cmluZywgcmVzZXQgdG8gZGVmYXVsdCBtYXJrIHBvc2l0aW9uID0gMCwgcmVhZCBzYW1lIHRoaW5nCisgICAgSW5wdXRTdHJlYW0gc3RyZWFtID0gbmV3IExhenlCeXRlQXJyYXlJbnB1dFN0cmVhbShDT05URU5UX0NBTExBQkxFKTsKKworICAgIHJlYWRGaWxlRnJvbVNvdXJjZShzdHJlYW0pOworICAgIHN0cmVhbS5yZXNldCgpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVGcm9tU291cmNlKHN0cmVhbSkpLmlzRXF1YWxUbyhDT05URU5UKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1hcmtBbmRSZXNldF9mcm9tTWlkd2F5Qnl0ZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgLy8gU2tpcCAxMCBhbmQgbWFyaywgcmVhZCByZW1haW5kZXIsIHJlc2V0IHRvIG1hcmtlZCAxMCBwb3NpdGlvbiwgcmVhZCBzYW1lIHRoaW5nCisgICAgSW5wdXRTdHJlYW0gc3RyZWFtID0gbmV3IExhenlCeXRlQXJyYXlJbnB1dFN0cmVhbShDT05URU5UX0NBTExBQkxFKTsKKworICAgIHN0cmVhbS5za2lwKDEwKTsKKyAgICBzdHJlYW0ubWFyaygwKTsgLy8gYXJiaXRyYXJ5IHJlYWRsaW1pdAorCisgICAgcmVhZEZpbGVGcm9tU291cmNlKHN0cmVhbSk7CisgICAgc3RyZWFtLnJlc2V0KCk7CisgICAgYXNzZXJ0VGhhdChyZWFkRmlsZUZyb21Tb3VyY2Uoc3RyZWFtKSkuaXNFcXVhbFRvKENPTlRFTlQuc3Vic3RyaW5nKDEwKSk7CisgIH0KKworICAvKiogQSBzdWJzdGl0dXRlIGZvciBNb2NraXRvLnNweShDYWxsYWJsZTxUPikgc2luY2UgTW9ja2l0byBjYW4ndCB3cmFwIGFub255bW91cyBjbGFzc2VzLiAqLworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTcHlDYWxsYWJsZTxUPiBpbXBsZW1lbnRzIENhbGxhYmxlPFQ+IHsKKyAgICBwcml2YXRlIGZpbmFsIENhbGxhYmxlPFQ+IGRlbGVnYXRlOworICAgIHByaXZhdGUgaW50IGNhbGxDb3VudDsKKworICAgIFNweUNhbGxhYmxlKENhbGxhYmxlPFQ+IGRlbGVnYXRlKSB7CisgICAgICB0aGlzLmRlbGVnYXRlID0gZGVsZWdhdGU7CisgICAgICB0aGlzLmNhbGxDb3VudCA9IDA7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIFQgY2FsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgICAgY2FsbENvdW50Kys7CisgICAgICByZXR1cm4gZGVsZWdhdGUuY2FsbCgpOworICAgIH0KKworICAgIGludCBjYWxsQ291bnQoKSB7CisgICAgICByZXR1cm4gY2FsbENvdW50OworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0xpdGVUcmFuc2Zvcm1GcmFnbWVudHNUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vaW50ZXJuYWwvTGl0ZVRyYW5zZm9ybUZyYWdtZW50c1Rlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNjRjYjNiCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsL0xpdGVUcmFuc2Zvcm1GcmFnbWVudHNUZXN0LmphdmEKQEAgLTAsMCArMSwxNTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLmludGVybmFsOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uRnJhZ21lbnQ7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgTGl0ZVRyYW5zZm9ybUZyYWdtZW50c1Rlc3QgeworCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHBhcnNlQWJzZW50VHJhbnNmb3JtRnJhZ21lbnRfeWllbGRzRW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJzY2hlbWU6cGF0aCIpOworICAgIGFzc2VydFRoYXQoTGl0ZVRyYW5zZm9ybUZyYWdtZW50cy5wYXJzZVRyYW5zZm9ybU5hbWVzKHVyaSkpLmlzRW1wdHkoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHBhcnNlRW1wdHlUcmFuc2Zvcm1GcmFnbWVudF95aWVsZHNFbXB0eSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoInNjaGVtZTpwYXRoIyIpOworICAgIGFzc2VydFRoYXQoTGl0ZVRyYW5zZm9ybUZyYWdtZW50cy5wYXJzZVRyYW5zZm9ybU5hbWVzKHVyaSkpLmlzRW1wdHkoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHBhcnNlTm9uVHJhbnNmb3JtRnJhZ21lbnRfeWllbGRzRW1wdHkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJzY2hlbWU6cGF0aCNub250cmFuc2Zvcm0iKTsKKyAgICBhc3NlcnRUaGF0KExpdGVUcmFuc2Zvcm1GcmFnbWVudHMucGFyc2VUcmFuc2Zvcm1OYW1lcyh1cmkpKS5pc0VtcHR5KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBwYXJzZVNpbXBsZVRyYW5zZm9ybUZyYWdtZW50X3lpZWxkc1NwZWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJzY2hlbWU6cGF0aCN0cmFuc2Zvcm09c2ltcGxlIik7CisgICAgYXNzZXJ0VGhhdChMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLnBhcnNlVHJhbnNmb3JtTmFtZXModXJpKSkuY29udGFpbnNFeGFjdGx5KCJzaW1wbGUiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHBhcnNlTWl4ZWRUcmFuc2Zvcm1GcmFnbWVudF95aWVsZHNTcGVjKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgic2NoZW1lOnBhdGgjdHJhbnNmb3JtPU0xWF9kIik7CisgICAgYXNzZXJ0VGhhdChMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLnBhcnNlVHJhbnNmb3JtTmFtZXModXJpKSkuY29udGFpbnNFeGFjdGx5KCJNMVhfZCIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcGFyc2VFbmNvZGVkVHJhbnNmb3JtRnJhZ21lbnRfeWllbGRzSW52YWxpZFNwZWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUcmFpbGluZyAiJTNEIiBpcyBpZ25vcmVkLgorICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoInNjaGVtZTpwYXRoI3RyYW5zZm9ybT1JTlZBTElEJTNEIik7CisgICAgYXNzZXJ0VGhhdChMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLnBhcnNlVHJhbnNmb3JtTmFtZXModXJpKSkuY29udGFpbnNFeGFjdGx5KCJJTlZBTElEIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBwYXJzZVRyYW5zZm9ybUJlZm9yZU90aGVyRnJhZ21lbnRfeWllbGRzU3BlYygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoInNjaGVtZTpwYXRoI3RyYW5zZm9ybT1iZWZvcmVvdGhlciZvdGhlciIpOworICAgIGFzc2VydFRoYXQoTGl0ZVRyYW5zZm9ybUZyYWdtZW50cy5wYXJzZVRyYW5zZm9ybU5hbWVzKHVyaSkpLmNvbnRhaW5zRXhhY3RseSgiYmVmb3Jlb3RoZXIiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHBhcnNlVHJhbnNmb3JtQWZ0ZXJPdGhlckZyYWdtZW50X3lpZWxkc0VtcHR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgic2NoZW1lOnBhdGgjbm9udHJhbnNmb3JtJnRyYW5zZm9ybT1hZnRlcm90aGVyIik7CisgICAgYXNzZXJ0VGhhdChMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLnBhcnNlVHJhbnNmb3JtTmFtZXModXJpKSkuaXNFbXB0eSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcGFyc2VNdWx0aXBsZVRyYW5zZm9ybUZyYWdtZW50c195aWVsZHNBbGxTcGVjcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoInNjaGVtZTpwYXRoI3RyYW5zZm9ybT1maXJzdCtzZWNvbmQrdGhpcmQiKTsKKyAgICBhc3NlcnRUaGF0KExpdGVUcmFuc2Zvcm1GcmFnbWVudHMucGFyc2VUcmFuc2Zvcm1OYW1lcyh1cmkpKQorICAgICAgICAuY29udGFpbnNFeGFjdGx5KCJmaXJzdCIsICJzZWNvbmQiLCAidGhpcmQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHBhcnNlVHJhbnNmb3JtRnJhZ21lbnRXaXRoU3VicGFyYW1zX3lpZWxkc0p1c3ROYW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgic2NoZW1lOnBhdGgjdHJhbnNmb3JtPXdpdGhwYXJhbXMoZm9vPWJhcikiKTsKKyAgICBhc3NlcnRUaGF0KExpdGVUcmFuc2Zvcm1GcmFnbWVudHMucGFyc2VUcmFuc2Zvcm1OYW1lcyh1cmkpKS5jb250YWluc0V4YWN0bHkoIndpdGhwYXJhbXMiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHBhcnNlTXVsdGlwbGVUcmFuc2Zvcm1GcmFnbWVudHNXaXRoU3VicGFyYW1zX3lpZWxkc0FsbE5hbWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgic2NoZW1lOnBhdGgjdHJhbnNmb3JtPWZpcnN0KGZvbz1iYXIpK3NlY29uZCh5YWRhPXlhZGEseD15KSt0aGlyZCh4eHgpIik7CisgICAgYXNzZXJ0VGhhdChMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLnBhcnNlVHJhbnNmb3JtTmFtZXModXJpKSkKKyAgICAgICAgLmNvbnRhaW5zRXhhY3RseSgiZmlyc3QiLCAic2Vjb25kIiwgInRoaXJkIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBwYXJzZVRyYW5zZm9ybUZyYWdtZW50V2l0aEVuY29kZWRTdWJwYXJhbXNfeWllbGRzSnVzdE5hbWUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJzY2hlbWU6cGF0aCN0cmFuc2Zvcm09d2l0aGVuY29kZWQoayUzRD0lMjh2JTI5KSIpOworICAgIGFzc2VydFRoYXQoTGl0ZVRyYW5zZm9ybUZyYWdtZW50cy5wYXJzZVRyYW5zZm9ybU5hbWVzKHVyaSkpLmNvbnRhaW5zRXhhY3RseSgid2l0aGVuY29kZWQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGpvaW5FbXB0eV95aWVsZE5pbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFN0cmluZyBlbmNvZGVkRnJhZ21lbnQgPSBMaXRlVHJhbnNmb3JtRnJhZ21lbnRzLmpvaW5UcmFuc2Zvcm1TcGVjcyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIGFzc2VydFRoYXQoZW5jb2RlZEZyYWdtZW50KS5pc051bGwoKTsKKworICAgIC8vIE5PVEU6IEFuZHJvaWQgVXJpIHRyZWF0cyBudWxsIGFzIHJlbW92aW5nIHRoZSBmcmFnbWVudC4KKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJzY2hlbWU6cGF0aCNSRU1PVkVEIikuYnVpbGRVcG9uKCkuZW5jb2RlZEZyYWdtZW50KGVuY29kZWRGcmFnbWVudCkuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KHVyaS50b1N0cmluZygpKS5pc0VxdWFsVG8oInNjaGVtZTpwYXRoIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBqb2luU2ltcGxlX3lpZWxkRnJhZ21lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaGF0KExpdGVUcmFuc2Zvcm1GcmFnbWVudHMuam9pblRyYW5zZm9ybVNwZWNzKEltbXV0YWJsZUxpc3Qub2YoInNpbXBsZSIpKSkKKyAgICAgICAgLmlzRXF1YWxUbygidHJhbnNmb3JtPXNpbXBsZSIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgam9pbk11bHRpcGxlX3lpZWxkRnJhZ21lbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaGF0KExpdGVUcmFuc2Zvcm1GcmFnbWVudHMuam9pblRyYW5zZm9ybVNwZWNzKEltbXV0YWJsZUxpc3Qub2YoImZpcnN0IiwgInNlY29uZCIpKSkKKyAgICAgICAgLmlzRXF1YWxUbygidHJhbnNmb3JtPWZpcnN0K3NlY29uZCIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgam9pbk11bHRpcGxlV2l0aFBhcmFtc195aWVsZEVuY29kZWRGcmFnbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFN0cmluZyBmcmFnbWVudCA9CisgICAgICAgIExpdGVUcmFuc2Zvcm1GcmFnbWVudHMuam9pblRyYW5zZm9ybVNwZWNzKAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigiZmlyc3QoZm9vPWJhcikiLCAic2Vjb25kKGslM0Q9JTI4diUyOSkiKSk7CisgICAgYXNzZXJ0VGhhdChmcmFnbWVudCkuaXNFcXVhbFRvKCJ0cmFuc2Zvcm09Zmlyc3QoZm9vPWJhcikrc2Vjb25kKGslM0Q9JTI4diUyOSkiKTsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJzY2hlbWU6cGF0aCIpLmJ1aWxkVXBvbigpLmVuY29kZWRGcmFnbWVudChmcmFnbWVudCkuYnVpbGQoKTsKKworICAgIC8vIFJ1biBpdCB0aHJvdWdoIHRoZSBmdWxsIGZyYWdtZW50IHBhcnNlciB0byBlbnN1cmUgb3V0cHV0IGlzIHZhbGlkLgorICAgIEZyYWdtZW50IGZ1bGxGcmFnbWVudCA9IEZyYWdtZW50LnBhcnNlKHVyaSk7CisgICAgRnJhZ21lbnQuUGFyYW0gdHJhbnNmb3JtID0gZnVsbEZyYWdtZW50LnBhcmFtcygpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KHRyYW5zZm9ybS5rZXkoKSkuaXNFcXVhbFRvKCJ0cmFuc2Zvcm0iKTsKKworICAgIEZyYWdtZW50LlBhcmFtVmFsdWUgZmlyc3QgPSB0cmFuc2Zvcm0udmFsdWVzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoZmlyc3QubmFtZSgpKS5pc0VxdWFsVG8oImZpcnN0Iik7CisgICAgRnJhZ21lbnQuU3ViUGFyYW0gZm9vID0gZmlyc3Quc3ViUGFyYW1zKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoZm9vLmtleSgpKS5pc0VxdWFsVG8oImZvbyIpOworICAgIGFzc2VydFRoYXQoZm9vLnZhbHVlKCkpLmlzRXF1YWxUbygiYmFyIik7CisKKyAgICBGcmFnbWVudC5QYXJhbVZhbHVlIHNlY29uZCA9IHRyYW5zZm9ybS52YWx1ZXMoKS5nZXQoMSk7CisgICAgYXNzZXJ0VGhhdChzZWNvbmQubmFtZSgpKS5pc0VxdWFsVG8oInNlY29uZCIpOworICAgIEZyYWdtZW50LlN1YlBhcmFtIGtlcXVhbCA9IHNlY29uZC5zdWJQYXJhbXMoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChrZXF1YWwua2V5KCkpLmlzRXF1YWxUbygiaz0iKTsKKyAgICBhc3NlcnRUaGF0KGtlcXVhbC52YWx1ZSgpKS5pc0VxdWFsVG8oIih2KSIpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE4NjFjMzAKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9CVUlMRApAQCAtMCwwICsxLDMyIEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9sb2NhbF90ZXN0IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiRmFrZUZpbGVCYWNrZW5kVGVzdCIsCisgICAgc2l6ZSA9ICJzbWFsbCIsCisgICAgc3JjcyA9IFsiRmFrZUZpbGVCYWNrZW5kVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvRmFrZUZpbGVCYWNrZW5kVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmcvRmFrZUZpbGVCYWNrZW5kVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjMWY5MGEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZy9GYWtlRmlsZUJhY2tlbmRUZXN0LmphdmEKQEAgLTAsMCArMSwxNTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3Rpbmc7CisKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC51dGlsLlBhaXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uR2NQYXJhbTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5VbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGphdmEuaW8uQ2xvc2VhYmxlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBGYWtlRmlsZUJhY2tlbmRUZXN0IGV4dGVuZHMgQmFja2VuZFRlc3RCYXNlIHsKKyAgcHJpdmF0ZSBmaW5hbCBGYWtlRmlsZUJhY2tlbmQgYmFja2VuZCA9IG5ldyBGYWtlRmlsZUJhY2tlbmQoKTsKKworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5VXJpIHRtcFVyaSA9IG5ldyBUZW1wb3JhcnlVcmkoKTsKKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIEJhY2tlbmQgYmFja2VuZCgpIHsKKyAgICByZXR1cm4gYmFja2VuZDsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgVXJpIGxlZ2FsVXJpQmFzZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHRtcFVyaS5uZXdEaXJlY3RvcnlVcmkoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgTGlzdDxVcmk+IGlsbGVnYWxVcmlzVG9SZWFkKCkgeworICAgIHJldHVybiBJbW11dGFibGVMaXN0Lm9mKCk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHJvdGVjdGVkIExpc3Q8VXJpPiBpbGxlZ2FsVXJpc1RvV3JpdGUoKSB7CisgICAgcmV0dXJuIEltbXV0YWJsZUxpc3Qub2YoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwcm90ZWN0ZWQgTGlzdDxVcmk+IGlsbGVnYWxVcmlzVG9BcHBlbmQoKSB7CisgICAgcmV0dXJuIEltbXV0YWJsZUxpc3Qub2YoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRocm93c0V4Y2VwdGlvbnNfZm9yUmVhZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgYmFja2VuZC5zZXRGYWlsdXJlKEZha2VGaWxlQmFja2VuZC5PcGVyYXRpb25UeXBlLlJFQUQsIG5ldyBGYWtlSU9FeGNlcHRpb24oInRlc3QiKSk7CisgICAgYXNzZXJ0VGhyb3dzKEZha2VJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gYmFja2VuZC5vcGVuRm9yUmVhZCh1cmkpKTsKKyAgICBhc3NlcnRUaHJvd3MoRmFrZUlPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBiYWNrZW5kLm9wZW5Gb3JOYXRpdmVSZWFkKHVyaSkpOworCisgICAgYmFja2VuZC5jbGVhckZhaWx1cmUoRmFrZUZpbGVCYWNrZW5kLk9wZXJhdGlvblR5cGUuUkVBRCk7CisgICAgdHJ5IChDbG9zZWFibGUgcmVzb3VyY2UgPSBiYWNrZW5kLm9wZW5Gb3JSZWFkKHVyaSkpIHt9CisgICAgUGFpcjxVcmksIENsb3NlYWJsZT4gbmF0aXZlT3BlbiA9IGJhY2tlbmQub3BlbkZvck5hdGl2ZVJlYWQodXJpKTsKKyAgICB0cnkgKENsb3NlYWJsZSByZXNvdXJjZSA9IG5hdGl2ZU9wZW4uc2Vjb25kKSB7fQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGhyb3dzRXhjZXB0aW9uc19mb3JXcml0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgYmFja2VuZC5zZXRGYWlsdXJlKEZha2VGaWxlQmFja2VuZC5PcGVyYXRpb25UeXBlLldSSVRFLCBuZXcgRmFrZUlPRXhjZXB0aW9uKCJ0ZXN0IikpOworICAgIGFzc2VydFRocm93cyhGYWtlSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IGJhY2tlbmQub3BlbkZvcldyaXRlKHVyaSkpOworICAgIGFzc2VydFRocm93cyhGYWtlSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IGJhY2tlbmQub3BlbkZvckFwcGVuZCh1cmkpKTsKKworICAgIGJhY2tlbmQuY2xlYXJGYWlsdXJlKEZha2VGaWxlQmFja2VuZC5PcGVyYXRpb25UeXBlLldSSVRFKTsKKyAgICB0cnkgKENsb3NlYWJsZSByZXNvdXJjZSA9IGJhY2tlbmQub3BlbkZvcldyaXRlKHVyaSkpIHt9CisgICAgdHJ5IChDbG9zZWFibGUgcmVzb3VyY2UgPSBiYWNrZW5kLm9wZW5Gb3JBcHBlbmQodXJpKSkge30KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRocm93c0V4Y2VwdGlvbnNfZm9yUXVlcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIFVyaSBkaXIgPSB0bXBVcmkubmV3RGlyZWN0b3J5VXJpKCk7CisKKyAgICBiYWNrZW5kLnNldEZhaWx1cmUoRmFrZUZpbGVCYWNrZW5kLk9wZXJhdGlvblR5cGUuUVVFUlksIG5ldyBGYWtlSU9FeGNlcHRpb24oInRlc3QiKSk7CisgICAgYXNzZXJ0VGhyb3dzKEZha2VJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gYmFja2VuZC5leGlzdHModXJpKSk7CisgICAgYXNzZXJ0VGhyb3dzKEZha2VJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gYmFja2VuZC5pc0RpcmVjdG9yeSh1cmkpKTsKKyAgICBhc3NlcnRUaHJvd3MoRmFrZUlPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBiYWNrZW5kLmZpbGVTaXplKHVyaSkpOworICAgIGFzc2VydFRocm93cyhGYWtlSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IGJhY2tlbmQuY2hpbGRyZW4oZGlyKSk7CisgICAgYXNzZXJ0VGhyb3dzKEZha2VJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gYmFja2VuZC5nZXRHY1BhcmFtKHVyaSkpOworICAgIGFzc2VydFRocm93cyhGYWtlSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IGJhY2tlbmQudG9GaWxlKHVyaSkpOworCisgICAgYmFja2VuZC5jbGVhckZhaWx1cmUoRmFrZUZpbGVCYWNrZW5kLk9wZXJhdGlvblR5cGUuUVVFUlkpOworICAgIGJhY2tlbmQuZXhpc3RzKHVyaSk7CisgICAgYmFja2VuZC5pc0RpcmVjdG9yeSh1cmkpOworICAgIGJhY2tlbmQuZmlsZVNpemUodXJpKTsKKyAgICBiYWNrZW5kLmNoaWxkcmVuKGRpcik7CisgICAgYXNzZXJ0VGhyb3dzKFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24uY2xhc3MsICgpIC0+IGJhY2tlbmQuZ2V0R2NQYXJhbSh1cmkpKTsKKyAgICBiYWNrZW5kLnRvRmlsZSh1cmkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGhyb3dzRXhjZXB0aW9uc19mb3JNYW5hZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIFVyaSB1cmkyID0gdG1wVXJpLm5ld1VyaSgpOworICAgIFVyaSBkaXIgPSB0bXBVcmkubmV3RGlyZWN0b3J5VXJpKCk7CisKKyAgICBiYWNrZW5kLnNldEZhaWx1cmUoRmFrZUZpbGVCYWNrZW5kLk9wZXJhdGlvblR5cGUuTUFOQUdFLCBuZXcgRmFrZUlPRXhjZXB0aW9uKCJ0ZXN0IikpOworICAgIGFzc2VydFRocm93cyhGYWtlSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IGJhY2tlbmQuZGVsZXRlRmlsZSh1cmkpKTsKKyAgICBhc3NlcnRUaHJvd3MoRmFrZUlPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBiYWNrZW5kLmRlbGV0ZURpcmVjdG9yeShkaXIpKTsKKyAgICBhc3NlcnRUaHJvd3MoRmFrZUlPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBiYWNrZW5kLnJlbmFtZSh1cmksIHVyaTIpKTsKKyAgICBhc3NlcnRUaHJvd3MoRmFrZUlPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBiYWNrZW5kLmNyZWF0ZURpcmVjdG9yeShkaXIpKTsKKyAgICBhc3NlcnRUaHJvd3MoRmFrZUlPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBiYWNrZW5kLnNldEdjUGFyYW0odXJpLCBHY1BhcmFtLm5vbmUoKSkpOworCisgICAgYmFja2VuZC5jbGVhckZhaWx1cmUoRmFrZUZpbGVCYWNrZW5kLk9wZXJhdGlvblR5cGUuTUFOQUdFKTsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24uY2xhc3MsICgpIC0+IGJhY2tlbmQuc2V0R2NQYXJhbSh1cmksIEdjUGFyYW0ubm9uZSgpKSk7CisgICAgYmFja2VuZC5yZW5hbWUodXJpLCB1cmkyKTsKKyAgICBiYWNrZW5kLmRlbGV0ZUZpbGUodXJpMik7CisgICAgYmFja2VuZC5kZWxldGVEaXJlY3RvcnkoZGlyKTsKKyAgICBiYWNrZW5kLmNyZWF0ZURpcmVjdG9yeShkaXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGhyb3dzRXhjZXB0aW9uc19mb3JBbGwoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworCisgICAgYmFja2VuZC5zZXRGYWlsdXJlKEZha2VGaWxlQmFja2VuZC5PcGVyYXRpb25UeXBlLkFMTCwgbmV3IEZha2VJT0V4Y2VwdGlvbigidGVzdCIpKTsKKyAgICBhc3NlcnRUaHJvd3MoRmFrZUlPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBiYWNrZW5kLm9wZW5Gb3JSZWFkKHVyaSkpOyAvLyBSRUFECisgICAgYXNzZXJ0VGhyb3dzKEZha2VJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gYmFja2VuZC5vcGVuRm9yV3JpdGUodXJpKSk7IC8vIFdSSVRFCisgICAgYXNzZXJ0VGhyb3dzKEZha2VJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gYmFja2VuZC5leGlzdHModXJpKSk7IC8vIFFVRVJZCisgICAgYXNzZXJ0VGhyb3dzKEZha2VJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gYmFja2VuZC5kZWxldGVGaWxlKHVyaSkpOyAvLyBNQU5BR0UKKworICAgIGJhY2tlbmQuY2xlYXJGYWlsdXJlKEZha2VGaWxlQmFja2VuZC5PcGVyYXRpb25UeXBlLkFMTCk7CisgICAgdHJ5IChDbG9zZWFibGUgcmVzb3VyY2UgPSBiYWNrZW5kLm9wZW5Gb3JSZWFkKHVyaSkpIHt9CisgICAgdHJ5IChDbG9zZWFibGUgcmVzb3VyY2UgPSBiYWNrZW5kLm9wZW5Gb3JXcml0ZSh1cmkpKSB7fQorICAgIGJhY2tlbmQuZXhpc3RzKHVyaSk7CisgICAgYmFja2VuZC5kZWxldGVGaWxlKHVyaSk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBGYWtlSU9FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CisgICAgRmFrZUlPRXhjZXB0aW9uKFN0cmluZyBtZXNzYWdlKSB7CisgICAgICBzdXBlcihtZXNzYWdlKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXIvQlVJTEQgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9pbnRlZ3JhdGlvbi9kb3dubG9hZGVyL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYwNTQ5OTcKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9pbnRlZ3JhdGlvbi9kb3dubG9hZGVyL0JVSUxECkBAIC0wLDAgKzEsMzcgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xvY2FsX3Rlc3QiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJEb3dubG9hZERlc3RpbmF0aW9uT3BlbmVyVGVzdCIsCisgICAgc2l6ZSA9ICJzbWFsbCIsCisgICAgc3JjcyA9IFsiRG93bmxvYWREZXN0aW5hdGlvbk9wZW5lclRlc3QuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXI6ZG93bmxvYWRlcjIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvaW50ZWdyYXRpb24vZG93bmxvYWRlcjpkb3dubG9hZGVyMl9zcCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOmJ5dGVzIiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBkb3dubG9hZGVyIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXIvRG93bmxvYWREZXN0aW5hdGlvbk9wZW5lclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2ludGVncmF0aW9uL2Rvd25sb2FkZXIvRG93bmxvYWREZXN0aW5hdGlvbk9wZW5lclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Njg4ZDU1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvaW50ZWdyYXRpb24vZG93bmxvYWRlci9Eb3dubG9hZERlc3RpbmF0aW9uT3BlbmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjMzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmludGVncmF0aW9uLmRvd25sb2FkZXI7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5tYWtlQXJyYXlPZkJ5dGVzQ29udGVudDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQuU0VDT05EUzsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5TaGFyZWRQcmVmZXJlbmNlczsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5kb3dubG9hZGVyLkRvd25sb2FkRGVzdGluYXRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmRvd25sb2FkZXIuRG93bmxvYWRNZXRhZGF0YTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5KYXZhRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5UZW1wb3JhcnlVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLlJlYWRCeXRlQXJyYXlPcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLldyaXRlQnl0ZUFycmF5T3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5wcmltaXRpdmVzLkJ5dGVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgamF2YS5uaW8uQnl0ZUJ1ZmZlcjsKK2ltcG9ydCBqYXZhLm5pby5jaGFubmVscy5Xcml0YWJsZUJ5dGVDaGFubmVsOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZW91dEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUGFyYW1ldGVyaXplZFJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUGFyYW1ldGVyaXplZFJvYm9sZWN0cmljVGVzdFJ1bm5lci5QYXJhbWV0ZXJzOworCitAUnVuV2l0aChQYXJhbWV0ZXJpemVkUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIERvd25sb2FkRGVzdGluYXRpb25PcGVuZXJUZXN0IHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBUSU1FT1VUID0gM0w7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgYnl0ZVtdIENPTlRFTlQgPSBtYWtlQXJyYXlPZkJ5dGVzQ29udGVudCgpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIExpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSBFWEVDVVRPUl9TRVJWSUNFID0KKyAgICAgIE1vcmVFeGVjdXRvcnMubGlzdGVuaW5nRGVjb3JhdG9yKEV4ZWN1dG9ycy5uZXdDYWNoZWRUaHJlYWRQb29sKCkpOworCisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworCisgIHByaXZhdGUgZmluYWwgSW1wbGVtZW50YXRpb24gaW1wbFVuZGVyVGVzdDsKKyAgcHJpdmF0ZSBTaGFyZWRQcmVmZXJlbmNlcyBkb3dubG9hZE1ldGFkYXRhU3A7CisKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeVVyaSB0bXBVcmkgPSBuZXcgVGVtcG9yYXJ5VXJpKCk7CisKKyAgLyogUnVuIHRoZSBzYW1lIHRlc3Qgc3VpdGUgb24gbXVsdGlwbGUgaW1wbGVtZW50YXRpb25zIG9mIHRoZSBzYW1lIGludGVyZmFjZS4gKi8KKyAgcHJpdmF0ZSBlbnVtIEltcGxlbWVudGF0aW9uIHsKKyAgICBTSEFSRURfUFJFRkVSRU5DRVMKKyAgfQorCisgIEBQYXJhbWV0ZXJzKG5hbWUgPSAiaW1wbGVtZW50YXRpb249ezB9IikKKyAgcHVibGljIHN0YXRpYyBJbW11dGFibGVMaXN0PE9iamVjdFtdPiBkYXRhKCkgeworICAgIHJldHVybiBJbW11dGFibGVMaXN0Lm9mKG5ldyBPYmplY3RbXSB7SW1wbGVtZW50YXRpb24uU0hBUkVEX1BSRUZFUkVOQ0VTfSk7CisgIH0KKworICBwdWJsaWMgRG93bmxvYWREZXN0aW5hdGlvbk9wZW5lclRlc3QoSW1wbGVtZW50YXRpb24gaW1wbCkgeworICAgIHRoaXMuaW1wbFVuZGVyVGVzdCA9IGltcGw7CisgIH0KKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3RvcmFnZSA9IG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEltbXV0YWJsZUxpc3Qub2YobmV3IEphdmFGaWxlQmFja2VuZCgpKSk7CisgICAgZG93bmxvYWRNZXRhZGF0YVNwID0KKyAgICAgICAgQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKS5nZXRTaGFyZWRQcmVmZXJlbmNlcygicHJlZnMiLCAwKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5lcl93aXRoTm9FeGlzdGluZ0RhdGFfY3JlYXRlc05ld01ldGFkYXRhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGZpbGVVcmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgRG93bmxvYWRNZXRhZGF0YSBlbXB0eU1ldGFkYXRhID0gRG93bmxvYWRNZXRhZGF0YS5jcmVhdGUoIiIsIDApOworCisgICAgLy8gQ3JlYXRlIGRlc3RpbmF0aW9uLgorICAgIERvd25sb2FkTWV0YWRhdGFTdG9yZSBzdG9yZSA9IGNyZWF0ZU1ldGFkYXRhU3RvcmUoKTsKKyAgICBEb3dubG9hZERlc3RpbmF0aW9uT3BlbmVyIG9wZW5lciA9IERvd25sb2FkRGVzdGluYXRpb25PcGVuZXIuY3JlYXRlKHN0b3JlKTsKKyAgICBEb3dubG9hZERlc3RpbmF0aW9uIGRlc3RpbmF0aW9uID0gc3RvcmFnZS5vcGVuKGZpbGVVcmksIG9wZW5lcik7CisKKyAgICAvLyBBc3NldCB0aGF0IGRlc3RpbmF0aW9uIGhhcyBpbml0aWFsLCBlbXB0eSB2YWx1ZXMuCisgICAgYXNzZXJ0VGhhdChkZXN0aW5hdGlvbi5udW1FeGlzdGluZ0J5dGVzKCkpLmlzRXF1YWxUbygwKTsKKyAgICBhc3NlcnRUaGF0KGRlc3RpbmF0aW9uLnJlYWRNZXRhZGF0YSgpKS5pc0VxdWFsVG8oZW1wdHlNZXRhZGF0YSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuZXJfd2l0aE5vRXhpc3RpbmdEYXRhX3dyaXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSBmaWxlVXJpID0gdG1wVXJpLm5ld1VyaSgpOworCisgICAgLy8gU2V0IHVwIGRhdGEgYW5kIG1ldGFkYXRhIHRvIHdyaXRlLgorICAgIEJ5dGVCdWZmZXIgYnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShDT05URU5ULmxlbmd0aCk7CisgICAgYnVmZmVyLnB1dChDT05URU5UKTsKKyAgICBidWZmZXIucG9zaXRpb24oMCk7CisKKyAgICBEb3dubG9hZE1ldGFkYXRhIG1ldGFkYXRhVG9Xcml0ZSA9IERvd25sb2FkTWV0YWRhdGEuY3JlYXRlKCJ0ZXN0IiwgMTApOworCisgICAgLy8gQ3JlYXRlIGRlc3RpbmF0aW9uIGFuZCB3cml0ZSBkYXRhL21ldGFkYXRhLgorICAgIERvd25sb2FkTWV0YWRhdGFTdG9yZSBzdG9yZSA9IGNyZWF0ZU1ldGFkYXRhU3RvcmUoKTsKKyAgICBEb3dubG9hZERlc3RpbmF0aW9uT3BlbmVyIG9wZW5lciA9IERvd25sb2FkRGVzdGluYXRpb25PcGVuZXIuY3JlYXRlKHN0b3JlKTsKKyAgICBEb3dubG9hZERlc3RpbmF0aW9uIGRlc3RpbmF0aW9uID0gc3RvcmFnZS5vcGVuKGZpbGVVcmksIG9wZW5lcik7CisKKyAgICB0cnkgKFdyaXRhYmxlQnl0ZUNoYW5uZWwgd3JpdGVDaGFubmVsID0gZGVzdGluYXRpb24ub3BlbkJ5dGVDaGFubmVsKDAsIG1ldGFkYXRhVG9Xcml0ZSkpIHsKKyAgICAgIHdyaXRlQ2hhbm5lbC53cml0ZShidWZmZXIpOworICAgIH0KKworICAgIC8vIFJlYWQgYmFjayBkYXRhIHRvIGVuc3VyZSB0aGUgd3JpdGUgY29tcGxldGVkIHByb3Blcmx5LgorICAgIFJlYWRCeXRlQXJyYXlPcGVuZXIgcmVhZE9wZW5lciA9IFJlYWRCeXRlQXJyYXlPcGVuZXIuY3JlYXRlKCk7CisgICAgYnl0ZVtdIHJlYWRDb250ZW50ID0gc3RvcmFnZS5vcGVuKGZpbGVVcmksIHJlYWRPcGVuZXIpOworCisgICAgYXNzZXJ0VGhhdChyZWFkQ29udGVudCkuaGFzTGVuZ3RoKENPTlRFTlQubGVuZ3RoKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRDb250ZW50KS5pc0VxdWFsVG8oQ09OVEVOVCk7CisKKyAgICAvLyBBc3NlcnQgdGhhdCBkZXN0aW5hdGlvbiBub3cgcmVmbGVjdHMgdGhlIGxhdGVzdCBzdGF0ZS4KKyAgICBhc3NlcnRUaGF0KGRlc3RpbmF0aW9uLm51bUV4aXN0aW5nQnl0ZXMoKSkuaXNFcXVhbFRvKENPTlRFTlQubGVuZ3RoKTsKKyAgICBhc3NlcnRUaGF0KGRlc3RpbmF0aW9uLnJlYWRNZXRhZGF0YSgpKS5pc0VxdWFsVG8obWV0YWRhdGFUb1dyaXRlKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5lcl93aXRoRXhpc3RpbmdEYXRhX3VzZXNFeGlzdGluZ01ldGFkYXRhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIGZpbGVVcmkgPSB0bXBVcmkubmV3VXJpKCk7CisKKyAgICBEb3dubG9hZE1ldGFkYXRhIGV4cGVjdGVkTWV0YWRhdGEgPSBEb3dubG9hZE1ldGFkYXRhLmNyZWF0ZSgidGVzdCIsIDEwKTsKKworICAgIC8vIFNldCB1cCBmaWxlIHdpdGggZXhpc3RpbmcgZGF0YSBhbmQgZXhpc3RpbmcgbWV0YWRhdGEgaW4gc3RvcmUuCisgICAgVm9pZCB1bnVzZWQgPSBzdG9yYWdlLm9wZW4oZmlsZVVyaSwgV3JpdGVCeXRlQXJyYXlPcGVuZXIuY3JlYXRlKENPTlRFTlQpKTsKKworICAgIHdyaXRlVG9NZXRhZGF0YVN0b3JlKGZpbGVVcmkudG9TdHJpbmcoKSwgZXhwZWN0ZWRNZXRhZGF0YSk7CisKKyAgICAvLyBDcmVhdGUgZGVzdGluYXRpb24uCisgICAgRG93bmxvYWRNZXRhZGF0YVN0b3JlIHN0b3JlID0gY3JlYXRlTWV0YWRhdGFTdG9yZSgpOworICAgIERvd25sb2FkRGVzdGluYXRpb25PcGVuZXIgb3BlbmVyID0gRG93bmxvYWREZXN0aW5hdGlvbk9wZW5lci5jcmVhdGUoc3RvcmUpOworICAgIERvd25sb2FkRGVzdGluYXRpb24gZGVzdGluYXRpb24gPSBzdG9yYWdlLm9wZW4oZmlsZVVyaSwgb3BlbmVyKTsKKworICAgIC8vIEFzc2VydCB0aGF0IGRlc3RpbmF0aW9uIG5vdyByZWZsZWN0cyB0aGUgbGF0ZXN0IHN0YXRlLgorICAgIGFzc2VydFRoYXQoZGVzdGluYXRpb24ubnVtRXhpc3RpbmdCeXRlcygpKS5pc0VxdWFsVG8oQ09OVEVOVC5sZW5ndGgpOworICAgIGFzc2VydFRoYXQoZGVzdGluYXRpb24ucmVhZE1ldGFkYXRhKCkpLmlzRXF1YWxUbyhleHBlY3RlZE1ldGFkYXRhKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5lcl93aXRoRXhpc3RpbmdEYXRhX3dyaXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSBmaWxlVXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIGJ5dGVbXSBuZXdDb250ZW50ID0gbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoKTsKKyAgICBieXRlW10gZXhwZWN0ZWRDb250ZW50ID0gQnl0ZXMuY29uY2F0KENPTlRFTlQsIG5ld0NvbnRlbnQpOworCisgICAgLy8gU2V0IHVwIGZpbGUgd2l0aCBleGlzdGluZyBkYXRhIGFuZCBleGlzdGluZyBtZXRhZGF0YSBpbiBzdG9yZQorICAgIFZvaWQgdW51c2VkID0gc3RvcmFnZS5vcGVuKGZpbGVVcmksIFdyaXRlQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZShDT05URU5UKSk7CisKKyAgICB3cml0ZVRvTWV0YWRhdGFTdG9yZShmaWxlVXJpLnRvU3RyaW5nKCksIERvd25sb2FkTWV0YWRhdGEuY3JlYXRlKCJpbml0aWFsIiwgNUwpKTsKKworICAgIC8vIFNldCB1cCBkYXRhL21ldGFkYXRhIHRvIHdyaXRlLgorICAgIEJ5dGVCdWZmZXIgYnVmZmVyID0gQnl0ZUJ1ZmZlci5hbGxvY2F0ZShuZXdDb250ZW50Lmxlbmd0aCk7CisgICAgYnVmZmVyLnB1dChuZXdDb250ZW50KTsKKyAgICBidWZmZXIucG9zaXRpb24oMCk7CisKKyAgICBEb3dubG9hZE1ldGFkYXRhIG1ldGFkYXRhVG9Xcml0ZSA9IERvd25sb2FkTWV0YWRhdGEuY3JlYXRlKCJ0ZXN0IiwgMTApOworCisgICAgLy8gQ3JlYXRlIGRlc3RpbmF0aW9uIGFuZCB3cml0ZSBkYXRhL21ldGFkYXRhLgorICAgIERvd25sb2FkTWV0YWRhdGFTdG9yZSBzdG9yZSA9IGNyZWF0ZU1ldGFkYXRhU3RvcmUoKTsKKyAgICBEb3dubG9hZERlc3RpbmF0aW9uT3BlbmVyIG9wZW5lciA9IERvd25sb2FkRGVzdGluYXRpb25PcGVuZXIuY3JlYXRlKHN0b3JlKTsKKyAgICBEb3dubG9hZERlc3RpbmF0aW9uIGRlc3RpbmF0aW9uID0gc3RvcmFnZS5vcGVuKGZpbGVVcmksIG9wZW5lcik7CisKKyAgICB0cnkgKFdyaXRhYmxlQnl0ZUNoYW5uZWwgd3JpdGVDaGFubmVsID0KKyAgICAgICAgZGVzdGluYXRpb24ub3BlbkJ5dGVDaGFubmVsKGRlc3RpbmF0aW9uLm51bUV4aXN0aW5nQnl0ZXMoKSwgbWV0YWRhdGFUb1dyaXRlKSkgeworICAgICAgd3JpdGVDaGFubmVsLndyaXRlKGJ1ZmZlcik7CisgICAgfQorCisgICAgLy8gUmVhZCBiYWNrIGRhdGEgdG8gZW5zdXJlIHRoZSB3cml0ZSBjb21wbGV0ZWQgcHJvcGVybHkuCisgICAgYnl0ZVtdIHJlYWRDb250ZW50ID0gc3RvcmFnZS5vcGVuKGZpbGVVcmksIFJlYWRCeXRlQXJyYXlPcGVuZXIuY3JlYXRlKCkpOworCisgICAgYXNzZXJ0VGhhdChyZWFkQ29udGVudCkuaGFzTGVuZ3RoKGV4cGVjdGVkQ29udGVudC5sZW5ndGgpOworICAgIGFzc2VydFRoYXQocmVhZENvbnRlbnQpLmlzRXF1YWxUbyhleHBlY3RlZENvbnRlbnQpOworCisgICAgLy8gQXNzZXJ0IHRoYXQgZGVzdGluYXRpb24gbm93IHJlZmxlY3RzIHRoZSBsYXRlc3Qgc3RhdGUuCisgICAgYXNzZXJ0VGhhdChkZXN0aW5hdGlvbi5udW1FeGlzdGluZ0J5dGVzKCkpLmlzRXF1YWxUbyhleHBlY3RlZENvbnRlbnQubGVuZ3RoKTsKKyAgICBhc3NlcnRUaGF0KGRlc3RpbmF0aW9uLnJlYWRNZXRhZGF0YSgpKS5pc0VxdWFsVG8obWV0YWRhdGFUb1dyaXRlKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5lcl9jbGVhcnNNZXRhZGF0YUFuZERhdGEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgZmlsZVVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBEb3dubG9hZE1ldGFkYXRhIGVtcHR5TWV0YWRhdGEgPSBEb3dubG9hZE1ldGFkYXRhLmNyZWF0ZSgiIiwgMCk7CisKKyAgICAvLyBTZXQgdXAgZmlsZSB3aXRoIGV4aXN0aW5nIGRhdGEgYW5kIGV4aXN0aW5nIG1ldGFkYXRhIGluIHN0b3JlLgorICAgIFZvaWQgdW51c2VkID0gc3RvcmFnZS5vcGVuKGZpbGVVcmksIFdyaXRlQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZShDT05URU5UKSk7CisKKyAgICB3cml0ZVRvTWV0YWRhdGFTdG9yZShmaWxlVXJpLnRvU3RyaW5nKCksIERvd25sb2FkTWV0YWRhdGEuY3JlYXRlKCJ0ZXN0IiwgMTBMKSk7CisKKyAgICAvLyBDcmVhdGUgZGVzdGluYXRpb24gYW5kIGNsZWFyLgorICAgIERvd25sb2FkTWV0YWRhdGFTdG9yZSBzdG9yZSA9IGNyZWF0ZU1ldGFkYXRhU3RvcmUoKTsKKyAgICBEb3dubG9hZERlc3RpbmF0aW9uT3BlbmVyIG9wZW5lciA9IERvd25sb2FkRGVzdGluYXRpb25PcGVuZXIuY3JlYXRlKHN0b3JlKTsKKyAgICBEb3dubG9hZERlc3RpbmF0aW9uIGRlc3RpbmF0aW9uID0gc3RvcmFnZS5vcGVuKGZpbGVVcmksIG9wZW5lcik7CisKKyAgICBkZXN0aW5hdGlvbi5jbGVhcigpOworCisgICAgLy8gQXNzZXJ0IHRoYXQgZGVzdGluYXRpb24gbm93IHJlZmxlY3RzIHRoZSBsYXRlc3Qgc3RhdGUuCisgICAgYXNzZXJ0VGhhdChkZXN0aW5hdGlvbi5udW1FeGlzdGluZ0J5dGVzKCkpLmlzRXF1YWxUbygwKTsKKyAgICBhc3NlcnRUaGF0KGRlc3RpbmF0aW9uLnJlYWRNZXRhZGF0YSgpKS5pc0VxdWFsVG8oZW1wdHlNZXRhZGF0YSk7CisgIH0KKworICBwcml2YXRlIERvd25sb2FkTWV0YWRhdGFTdG9yZSBjcmVhdGVNZXRhZGF0YVN0b3JlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3dpdGNoIChpbXBsVW5kZXJUZXN0KSB7CisgICAgICBjYXNlIFNIQVJFRF9QUkVGRVJFTkNFUzoKKyAgICAgICAgcmV0dXJuIG5ldyBTaGFyZWRQcmVmZXJlbmNlc0Rvd25sb2FkTWV0YWRhdGEoZG93bmxvYWRNZXRhZGF0YVNwLCBFWEVDVVRPUl9TRVJWSUNFKTsKKyAgICB9CisgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7IC8vIEV4aGF1c3RpdmUgc3dpdGNoCisgIH0KKworICBwcml2YXRlIHZvaWQgd3JpdGVUb01ldGFkYXRhU3RvcmUoU3RyaW5nIGZpbGVVcmksIERvd25sb2FkTWV0YWRhdGEgbWV0YWRhdGFUb1dyaXRlKQorICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24sIFRpbWVvdXRFeGNlcHRpb24geworICAgIHN3aXRjaCAoaW1wbFVuZGVyVGVzdCkgeworICAgICAgY2FzZSBTSEFSRURfUFJFRkVSRU5DRVM6CisgICAgICAgIGRvd25sb2FkTWV0YWRhdGFTcC5lZGl0KCkuY2xlYXIoKS5jb21taXQoKTsKKyAgICAgICAgbmV3IFNoYXJlZFByZWZlcmVuY2VzRG93bmxvYWRNZXRhZGF0YShkb3dubG9hZE1ldGFkYXRhU3AsIEVYRUNVVE9SX1NFUlZJQ0UpCisgICAgICAgICAgICAudXBzZXJ0KFVyaS5wYXJzZShmaWxlVXJpKSwgbWV0YWRhdGFUb1dyaXRlKQorICAgICAgICAgICAgLmdldChUSU1FT1VULCBTRUNPTkRTKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9tb25pdG9ycy9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL21vbml0b3JzL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzODk1ZGMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9tb25pdG9ycy9CVUlMRApAQCAtMCwwICsxLDMwIEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9sb2NhbF90ZXN0IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvclRlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIkJ5dGVDb3VudGluZ091dHB1dE1vbml0b3JUZXN0LmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvbW9uaXRvcnMiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpGYWtlVGltZVNvdXJjZSIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9tb25pdG9ycy9CeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvbW9uaXRvcnMvQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MjJhOGE1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvbW9uaXRvcnMvQnl0ZUNvdW50aW5nT3V0cHV0TW9uaXRvclRlc3QuamF2YQpAQCAtMCwwICsxLDg1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm1vbml0b3JzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0LlNFQ09ORFM7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLkZha2VUaW1lU291cmNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNMb25nOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBCeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yVGVzdCB7CisKKyAgcHJpdmF0ZSBCeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yIHRlc3RPdXRwdXRNb25pdG9yOworICBwcml2YXRlIGxvbmcgdGVzdFN0b3JhZ2VMZW5ndGggPSAwOworICBwcml2YXRlIGZpbmFsIEZha2VUaW1lU291cmNlIGNsb2NrID0gbmV3IEZha2VUaW1lU291cmNlKCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgTE9HX0ZSRVFVRU5DWSA9IDFMOworCisgIHByaXZhdGUgY2xhc3MgVGVzdENvdW50ZXIgaW1wbGVtZW50cyBCeXRlQ291bnRpbmdPdXRwdXRNb25pdG9yLkNvdW50ZXIgeworICAgIHByaXZhdGUgZmluYWwgQXRvbWljTG9uZyBidWZmZXIgPSBuZXcgQXRvbWljTG9uZygpOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYnVmZmVyQ291bnRlcihpbnQgbGVuKSB7CisgICAgICBidWZmZXIuZ2V0QW5kQWRkKGxlbik7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgZmx1c2hDb3VudGVyKCkgeworICAgICAgdGVzdFN0b3JhZ2VMZW5ndGggKz0gYnVmZmVyLmdldEFuZFNldCgwKTsKKyAgICB9CisgIH0KKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgIHRlc3RPdXRwdXRNb25pdG9yID0KKyAgICAgICAgbmV3IEJ5dGVDb3VudGluZ091dHB1dE1vbml0b3IoCisgICAgICAgICAgICBuZXcgVGVzdENvdW50ZXIoKSwgY2xvY2s6OmN1cnJlbnRUaW1lTWlsbGlzLCBMT0dfRlJFUVVFTkNZLCBTRUNPTkRTKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RCeXRlc1dyaXR0ZW5JbnNpZGVJbnRlcnZhbF9zaG91bGROb3RGbHVzaCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgLy8gYWxsb3cgZW5vdWdoIHRpbWUgdG8gcGFzcyB0byBlbmFibGUgZmx1c2hpbmcKKyAgICBjbG9jay5hZHZhbmNlKExPR19GUkVRVUVOQ1ksIFNFQ09ORFMpOworICAgIHRlc3RPdXRwdXRNb25pdG9yLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxXSwgMCwgMSk7CisgICAgdGVzdE91dHB1dE1vbml0b3IuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAwLCAxKTsKKworICAgIGFzc2VydFRoYXQodGVzdFN0b3JhZ2VMZW5ndGgpLmlzRXF1YWxUbygxKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RCeXRlc1dyaXR0ZW5PdXRzaWRlSW50ZXJ2YWxfc2hvdWxkRmx1c2goKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgIHRlc3RPdXRwdXRNb25pdG9yLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxXSwgMCwgMSk7CisgICAgY2xvY2suYWR2YW5jZShMT0dfRlJFUVVFTkNZLCBTRUNPTkRTKTsKKyAgICB0ZXN0T3V0cHV0TW9uaXRvci5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDAsIDEpOworCisgICAgYXNzZXJ0VGhhdCh0ZXN0U3RvcmFnZUxlbmd0aCkuaXNFcXVhbFRvKDIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEJ5dGVzV3JpdHRlbkFmdGVyQ2xvc2Vfc2hvdWxkRmx1c2goKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgIC8vIGFsbG93IGVub3VnaCB0aW1lIHRvIHBhc3MgdG8gZW5hYmxlIGZsdXNoaW5nCisgICAgY2xvY2suYWR2YW5jZShMT0dfRlJFUVVFTkNZLCBTRUNPTkRTKTsKKyAgICB0ZXN0T3V0cHV0TW9uaXRvci5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDAsIDEpOworICAgIHRlc3RPdXRwdXRNb25pdG9yLmNsb3NlKCk7CisKKyAgICBhc3NlcnRUaGF0KHRlc3RTdG9yYWdlTGVuZ3RoKS5pc0VxdWFsVG8oMSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvQXNzZXRGaWxlRGVzY3JpcHRvck9wZW5lckFuZHJvaWRUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL0Fzc2V0RmlsZURlc2NyaXB0b3JPcGVuZXJBbmRyb2lkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1MjYwNzUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL0Fzc2V0RmlsZURlc2NyaXB0b3JPcGVuZXJBbmRyb2lkVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLmNyZWF0ZUZpbGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0cy5VVEZfODsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQucmVzLkFzc2V0RmlsZURlc2NyaXB0b3I7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlsczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNhbXBsZXMuQnl0ZUNvdW50aW5nTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uaW8uQ2hhclN0cmVhbXM7CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLkpVbml0NDsKKworQFJ1bldpdGgoSlVuaXQ0LmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIEFzc2V0RmlsZURlc2NyaXB0b3JPcGVuZXJBbmRyb2lkVGVzdCB7CisKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisKKyAgQFJ1bGUgcHVibGljIEZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXIgbGVha0NoZWNrZXIgPSBuZXcgRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlcigpOworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5VXJpIHRtcFVyaSA9IG5ldyBUZW1wb3JhcnlVcmkoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIGluaXRTdG9yYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3RvcmFnZSA9IG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEltbXV0YWJsZUxpc3Qub2YobmV3IEphdmFGaWxlQmFja2VuZCgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuQXNzZXRGaWxlRGVzY3JpcHRvcl9zaG91bGRSZWFkRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksICJjb250ZW50Iik7CisgICAgdHJ5IChBc3NldEZpbGVEZXNjcmlwdG9yIHJlc3VsdCA9IHN0b3JhZ2Uub3Blbih1cmksIEFzc2V0RmlsZURlc2NyaXB0b3JPcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICBhc3NlcnRUaGF0KHJlc3VsdC5nZXRMZW5ndGgoKSkuaXNFcXVhbFRvKDcpOworICAgICAgSW5wdXRTdHJlYW0gaW4gPSByZXN1bHQuY3JlYXRlSW5wdXRTdHJlYW0oKTsKKyAgICAgIFJlYWRlciByZWFkZXIgPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW4sIFVURl84KTsKKyAgICAgIGFzc2VydFRoYXQoQ2hhclN0cmVhbXMudG9TdHJpbmcocmVhZGVyKSkuaXNFcXVhbFRvKCJjb250ZW50Iik7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkFzc2V0RmlsZURlc2NyaXB0b3Jfd2l0aE1pc3NpbmdGaWxlX3Rocm93c0ZpbGVOb3RGb3VuZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImZpbGU6L2RvZXMtbm90LWV4aXN0Iik7CisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBGaWxlTm90Rm91bmRFeGNlcHRpb24uY2xhc3MsICgpIC0+IHN0b3JhZ2Uub3Blbih1cmksIEFzc2V0RmlsZURlc2NyaXB0b3JPcGVuZXIuY3JlYXRlKCkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5Bc3NldEZpbGVEZXNjcmlwdG9yX3dpdGhNb25pdG9yX3Nob3VsZFJlYWRGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlV2l0aE1vbml0b3IgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IEphdmFGaWxlQmFja2VuZCgpKSwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IEJ5dGVDb3VudGluZ01vbml0b3IoKSkpOworCisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBieXRlW10gY29udGVudCA9IFN0cmVhbVV0aWxzLm1ha2VBcnJheU9mQnl0ZXNDb250ZW50KCk7CisgICAgU3RyZWFtVXRpbHMuY3JlYXRlRmlsZShzdG9yYWdlV2l0aE1vbml0b3IsIHVyaSwgY29udGVudCk7CisKKyAgICB0cnkgKElucHV0U3RyZWFtIGluID0KKyAgICAgICAgc3RvcmFnZS5vcGVuKHVyaSwgQXNzZXRGaWxlRGVzY3JpcHRvck9wZW5lci5jcmVhdGUoKSkuY3JlYXRlSW5wdXRTdHJlYW0oKSkgeworICAgICAgYXNzZXJ0VGhhdChTdHJlYW1VdGlscy5yZWFkRmlsZUluQnl0ZXNGcm9tU291cmNlKGluKSkuaXNFcXVhbFRvKGNvbnRlbnQpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTc3MGRlYQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvQlVJTEQKQEAgLTAsMCArMSw1MTMgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2FwcGxpY2F0aW9uX3Rlc3QiLCAiYW5kcm9pZF9sb2NhbF90ZXN0IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9hcHBsaWNhdGlvbl90ZXN0KAorICAgIG5hbWUgPSAiQXNzZXRGaWxlRGVzY3JpcHRvck9wZW5lckFuZHJvaWRUZXN0IiwKKyAgICB0aW1lb3V0ID0gIm1vZGVyYXRlIiwKKyAgICBzcmNzID0gWworICAgICAgICAiQXNzZXRGaWxlRGVzY3JpcHRvck9wZW5lckFuZHJvaWRUZXN0LmphdmEiLAorICAgIF0sCisgICAgbWFuaWZlc3QgPSAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZTpBbmRyb2lkTWFuaWZlc3QueG1sIiwKKyAgICB0YXJnZXRfZGV2aWNlcyA9IFsKKyAgICAgICAgIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2dlbmVyaWNfcGhvbmU6Z29vZ2xlXzIzX3g4NiIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczphc3NldF9maWxlX2Rlc2NyaXB0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcyIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAanVuaXQiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJJbnRlZ3JpdHlVcmlDb21wdXRpbmdPcGVuZXJUZXN0IiwKKyAgICBzcmNzID0gWyJJbnRlZ3JpdHlVcmlDb21wdXRpbmdPcGVuZXJUZXN0LmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOmludGVncml0eV91cmlfY29tcHV0ZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3JtczppbnRlZ3JpdHkiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtczpwcm90b19mcmFnbWVudHMiLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9hcHBsaWNhdGlvbl90ZXN0KAorICAgIG5hbWUgPSAiTmF0aXZlUmVhZE9wZW5lckFuZHJvaWRUZXN0IiwKKyAgICB0aW1lb3V0ID0gIm1vZGVyYXRlIiwKKyAgICBzcmNzID0gWworICAgICAgICAiTmF0aXZlUmVhZE9wZW5lckFuZHJvaWRUZXN0LmphdmEiLAorICAgIF0sCisgICAgbWFuaWZlc3QgPSAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZTpBbmRyb2lkTWFuaWZlc3QueG1sIiwKKyAgICB0YXJnZXRfZGV2aWNlcyA9IFsKKyAgICAgICAgIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2dlbmVyaWNfcGhvbmU6Z29vZ2xlXzIzX3g4NiIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlX2Rlc2NyaXB0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3Rpbmc6ZXh0cmFzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6Y2xvc2VhYmxlX3VyaSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOm5hdGl2ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAanVuaXQiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJOYXRpdmVSZWFkT3BlbmVyVGVzdCIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIk5hdGl2ZVJlYWRPcGVuZXJUZXN0LmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3Rpbmc6bWF0Y2hlcnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpuYXRpdmUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2FwcGxpY2F0aW9uX3Rlc3QoCisgICAgbmFtZSA9ICJNYXBwZWRCeXRlQnVmZmVyT3BlbmVyQW5kcm9pZFRlc3QiLAorICAgIHRpbWVvdXQgPSAibW9kZXJhdGUiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJNYXBwZWRCeXRlQnVmZmVyT3BlbmVyQW5kcm9pZFRlc3QuamF2YSIsCisgICAgXSwKKyAgICBtYW5pZmVzdCA9ICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlOkFuZHJvaWRNYW5pZmVzdC54bWwiLAorICAgIHNoYXJkX2NvdW50ID0gMiwKKyAgICB0YXJnZXRfZGV2aWNlcyA9IFsKKyAgICAgICAgIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2dlbmVyaWNfcGhvbmU6Z29vZ2xlXzIzX3g4NiIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczptZW1vcnlfbWFwcGVkX2J5dGVzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6Y29tcHJlc3MiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtczpwcm90byIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAanVuaXQiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2FwcGxpY2F0aW9uX3Rlc3QoCisgICAgbmFtZSA9ICJQYXJjZWxGaWxlRGVzY3JpcHRvck9wZW5lckFuZHJvaWRUZXN0IiwKKyAgICB0aW1lb3V0ID0gIm1vZGVyYXRlIiwKKyAgICBzcmNzID0gWworICAgICAgICAiUGFyY2VsRmlsZURlc2NyaXB0b3JPcGVuZXJBbmRyb2lkVGVzdC5qYXZhIiwKKyAgICBdLAorICAgIG1hbmlmZXN0ID0gIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGU6QW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgdGFyZ2V0X2RldmljZXMgPSBbCisgICAgICAgICIvL3Rvb2xzL2FuZHJvaWQvZW11bGF0ZWRfZGV2aWNlcy9nZW5lcmljX3Bob25lOmdvb2dsZV8yM194ODYiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nOmV4dHJhcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnBhcmNlbF9maWxlX2Rlc2NyaXB0b3IiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOmNvbXByZXNzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGp1bml0IiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiUmVhZEJ5dGVBcnJheU9wZW5lclRlc3QiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJSZWFkQnl0ZUFycmF5T3BlbmVyVGVzdC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nOmV4dHJhcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOmJ5dGVzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NhbXBsZXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtczpjb21wcmVzcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOnByb3RvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiV3JpdGVCeXRlQXJyYXlPcGVuZXJUZXN0IiwKKyAgICBzcmNzID0gWworICAgICAgICAiV3JpdGVCeXRlQXJyYXlPcGVuZXJUZXN0LmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzOnN5bmNpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpieXRlcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnN0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zYW1wbGVzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOmNvbXByZXNzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJTdHJpbmdPcGVuZXJUZXN0IiwKKyAgICBzcmNzID0gWworICAgICAgICAiU3RyaW5nT3BlbmVyVGVzdC5qYXZhIiwKKyAgICBdLAorICAgIG1hbmlmZXN0ID0gIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGU6QW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzOnN5bmNpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL2ludGVybmFsOmNoYXJzZXRzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyaW5nIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9hcHBsaWNhdGlvbl90ZXN0KAorICAgIG5hbWUgPSAiUmVhZEZpbGVPcGVuZXJBbmRyb2lkVGVzdCIsCisgICAgdGltZW91dCA9ICJtb2RlcmF0ZSIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlJlYWRGaWxlT3BlbmVyQW5kcm9pZFRlc3QuamF2YSIsCisgICAgXSwKKyAgICBtYW5pZmVzdCA9ICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlOkFuZHJvaWRNYW5pZmVzdC54bWwiLAorICAgIHNoYXJkX2NvdW50ID0gMiwKKyAgICB0YXJnZXRfZGV2aWNlcyA9IFsKKyAgICAgICAgIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2dlbmVyaWNfcGhvbmU6Z29vZ2xlXzIzX3g4NiIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3Rpbmc6ZXh0cmFzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnN0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zYW1wbGVzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6Y29tcHJlc3MiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtczpwcm90byIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAanVuaXQiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2FwcGxpY2F0aW9uX3Rlc3QoCisgICAgbmFtZSA9ICJSYW5kb21BY2Nlc3NGaWxlT3BlbmVyQW5kcm9pZFRlc3QiLAorICAgIHRpbWVvdXQgPSAibW9kZXJhdGUiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJSYW5kb21BY2Nlc3NGaWxlT3BlbmVyQW5kcm9pZFRlc3QuamF2YSIsCisgICAgXSwKKyAgICBtYW5pZmVzdCA9ICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlOkFuZHJvaWRNYW5pZmVzdC54bWwiLAorICAgIHNoYXJkX2NvdW50ID0gMSwKKyAgICB0YXJnZXRfZGV2aWNlcyA9IFsKKyAgICAgICAgIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2dlbmVyaWNfcGhvbmU6Z29vZ2xlXzIzX3g4NiIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpyYW5kb21fYWNjZXNzX2ZpbGUiLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGp1bml0IiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiUmVhZFByb3RvT3BlbmVyVGVzdCIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlJlYWRQcm90b09wZW5lclRlc3QuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzp0ZXN0X21lc3NhZ2VfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6cHJvdG8iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtczpjb21wcmVzcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOnByb3RvIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86cHJvdG9idWZfbGl0ZSIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIlJlYWRTdHJlYW1PcGVuZXJUZXN0IiwKKyAgICBzcmNzID0gWworICAgICAgICAiUmVhZFN0cmVhbU9wZW5lclRlc3QuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiUmVjdXJzaXZlRGVsZXRlT3BlbmVyVGVzdCIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIlJlY3Vyc2l2ZURlbGV0ZU9wZW5lclRlc3QuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpyZWN1cnNpdmVfZGVsZXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyaW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgICAgICJAbW9ja2l0byIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIlJlY3Vyc2l2ZVNpemVPcGVuZXJUZXN0IiwKKyAgICBzcmNzID0gWworICAgICAgICAiUmVjdXJzaXZlU2l6ZU9wZW5lclRlc3QuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpyZWN1cnNpdmVfc2l6ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOmNvbXByZXNzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2FwcGxpY2F0aW9uX3Rlc3QoCisgICAgbmFtZSA9ICJTdHJlYW1NdXRhdGlvbk9wZW5lckFuZHJvaWRUZXN0IiwKKyAgICBzaXplID0gImxhcmdlIiwKKyAgICBzcmNzID0gWworICAgICAgICAiU3RyZWFtTXV0YXRpb25PcGVuZXJBbmRyb2lkVGVzdC5qYXZhIiwKKyAgICBdLAorICAgIG1hbmlmZXN0ID0gIlN0cmVhbU11dGF0aW9uT3BlbmVyQW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgdGFyZ2V0X2RldmljZXMgPSBbCisgICAgICAgICIvL3Rvb2xzL2FuZHJvaWQvZW11bGF0ZWRfZGV2aWNlcy9nZW5lcmljX3Bob25lOmdvb2dsZV8yM194ODYiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpsb2NrX2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW1fbXV0YXRpb24iLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGp1bml0IiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiU3RyZWFtTXV0YXRpb25PcGVuZXJUZXN0IiwKKyAgICBzcmNzID0gWworICAgICAgICAiU3RyZWFtTXV0YXRpb25PcGVuZXJUZXN0LmphdmEiLAorICAgIF0sCisgICAgbWFuaWZlc3QgPSAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZTpBbmRyb2lkTWFuaWZlc3QueG1sIiwKKyAgICBtYW5pZmVzdF92YWx1ZXMgPSB7CisgICAgICAgICJ0YXJnZXRTZGtWZXJzaW9uIjogIjE5IiwgICMgVE9ETyhiLzEzMDkwNzEwNSk6IEVuY3J5cHRUcmFuc2Zvcm0gc2hvdWxkIGhhbmRsZSB0aGlzIGludGVybmFsbHkKKyAgICB9LAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JlaGF2aW9yczpzeW5jaW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nOmV4dHJhcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOmJ5dGVzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6bG9ja19maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyZWFtX211dGF0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyaW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6Y29tcHJlc3MiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtczpwcm90b19mcmFnbWVudHMiLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9hcHBsaWNhdGlvbl90ZXN0KAorICAgIG5hbWUgPSAiU3lzdGVtTGlicmFyeU9wZW5lckFuZHJvaWRUZXN0IiwKKyAgICBzaXplID0gImxhcmdlIiwKKyAgICBzcmNzID0gWworICAgICAgICAiSGVsbG9OYXRpdmUuamF2YSIsCisgICAgICAgICJTeXN0ZW1MaWJyYXJ5T3BlbmVyQW5kcm9pZFRlc3QuamF2YSIsCisgICAgXSwKKyAgICBkYXRhID0gWworICAgICAgICAiOmxpYmhlbGxvMW5hdGl2ZS5zbyIsCisgICAgICAgICI6bGliaGVsbG8ybmF0aXZlLnNvIiwKKyAgICBdLAorICAgIG1hbmlmZXN0ID0gIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGU6QW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgdGFncyA9IFsibm90YXAiXSwgICMgT25seSB3b3JrcyB3aXRoIC0tY29uZmlnPWFuZHJvaWRfeDg2IHNvIGRpc2FibGluZyBmcm9tIFRBUC4KKyAgICB0YXJnZXRfZGV2aWNlcyA9IFsKKyAgICAgICAgIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2dlbmVyaWNfcGhvbmU6Z29vZ2xlXzIzX3g4NiIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzeXN0ZW1fbGlicmFyeSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOmNvbXByZXNzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfYW5kcm9pZF90ZXN0aW5nLy86dXRpbCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAanVuaXQiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2FwcGxpY2F0aW9uX3Rlc3QoCisgICAgbmFtZSA9ICJXcml0ZUZpbGVPcGVuZXJBbmRyb2lkVGVzdCIsCisgICAgc2l6ZSA9ICJsYXJnZSIsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIldyaXRlRmlsZU9wZW5lckFuZHJvaWRUZXN0LmphdmEiLAorICAgIF0sCisgICAgbWFuaWZlc3QgPSAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZTpBbmRyb2lkTWFuaWZlc3QueG1sIiwKKyAgICBzaGFyZF9jb3VudCA9IDIsCisgICAgdGFyZ2V0X2RldmljZXMgPSBbCisgICAgICAgICIvL3Rvb2xzL2FuZHJvaWQvZW11bGF0ZWRfZGV2aWNlcy9nZW5lcmljX3Bob25lOmdvb2dsZV8yM194ODYiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi9pbnRlcm5hbDpmb3J3YXJkaW5nX3N0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyZWFtIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOmNvbXByZXNzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGp1bml0IiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiV3JpdGVQcm90b09wZW5lclRlc3QiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJXcml0ZVByb3RvT3BlbmVyVGVzdC5qYXZhIiwKKyAgICBdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iZWhhdmlvcnM6c3luY2luZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpleHRyYXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3Rpbmc6dGVzdF9tZXNzYWdlX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnByb3RvIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6Y29tcHJlc3MiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJQaXBlc1Rlc3QiLAorICAgIHNyY3MgPSBbCisgICAgICAgICJQaXBlc1Rlc3QuamF2YSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6ZmlsZSIsCisgICAgXSwKKykKKworY2NfYmluYXJ5KAorICAgIG5hbWUgPSAibGliaGVsbG8xbmF0aXZlLnNvIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgbGlua3NoYXJlZCA9IDEsCisgICAgbGlua3N0YXRpYyA9IDEsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpoZWxsbzFuYXRpdmVfbGliIiwKKyAgICBdLAorKQorCitjY19saWJyYXJ5KAorICAgIG5hbWUgPSAiaGVsbG8xbmF0aXZlX2xpYiIsCisgICAgdGVzdG9ubHkgPSAxLAorICAgIHNyY3MgPSBbImhlbGxvMW5hdGl2ZS5jYyJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICJAamRrX2puaSIsCisgICAgXSwKKyAgICBhbHdheXNsaW5rID0gMSwKKykKKworY2NfYmluYXJ5KAorICAgIG5hbWUgPSAibGliaGVsbG8ybmF0aXZlLnNvIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgbGlua3NoYXJlZCA9IDEsCisgICAgbGlua3N0YXRpYyA9IDEsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpoZWxsbzJuYXRpdmVfbGliIiwKKyAgICBdLAorKQorCitjY19saWJyYXJ5KAorICAgIG5hbWUgPSAiaGVsbG8ybmF0aXZlX2xpYiIsCisgICAgdGVzdG9ubHkgPSAxLAorICAgIHNyY3MgPSBbImhlbGxvMm5hdGl2ZS5jYyJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICJAamRrX2puaSIsCisgICAgXSwKKyAgICBhbHdheXNsaW5rID0gMSwKKykKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvSGVsbG9OYXRpdmUuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvSGVsbG9OYXRpdmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOTYzNGQ4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9IZWxsb05hdGl2ZS5qYXZhCkBAIC0wLDAgKzEsMjEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworLyoqIEhlbHBlciBmb3IgdGVzdGluZyBhY2Nlc3MgdG8gbmF0aXZlIGNvZGUuICovCitwdWJsaWMgY2xhc3MgSGVsbG9OYXRpdmUgeworICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBTdHJpbmcgc2F5SGVsbG8oKTsKK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvSW50ZWdyaXR5VXJpQ29tcHV0aW5nT3BlbmVyVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9JbnRlZ3JpdHlVcmlDb21wdXRpbmdPcGVuZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDAyZmFhMAotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvSW50ZWdyaXR5VXJpQ29tcHV0aW5nT3BlbmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLmNyZWF0ZUZpbGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuSmF2YUZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVtcG9yYXJ5VXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5JbnRlZ3JpdHlUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLlRyYW5zZm9ybVByb3RvRnJhZ21lbnRzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90bzsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgSW50ZWdyaXR5VXJpQ29tcHV0aW5nT3BlbmVyVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE9SSUdURVhUID0gIlRoaXMgaXMgc29tZSByZWd1bGFyIG9sZCB0ZXh0IEFCQyAxMjMgIUAjIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE9SSUdURVhUX1NIQTI1Nl9CNjQgPSAiRm9SMUhyeGRBaFkwNURFL2dBVWoweWpwellwZldiMGZKRStYQnA4bFkwbz0iOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1JJR1RFWFRfU0hBMjU2X0I2NF9JTkNPUlJFQ1QgPSAiSU5DT1JSRUNUIjsKKworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5VXJpIHRtcFVyaSA9IG5ldyBUZW1wb3JhcnlVcmkoKTsKKworICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwU3RvcmFnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IEphdmFGaWxlQmFja2VuZCgpKSwgSW1tdXRhYmxlTGlzdC5vZihuZXcgSW50ZWdyaXR5VHJhbnNmb3JtKCkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGludGVncml0eVVyaUNvbXB1dGluZ09wZW5lcl9zaG91bGRQcm9kdWNlQ29ycmVjdENoZWNrc3VtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICBVcmkgaW5pdGlhbFVyaSA9IGNyZWF0ZVRlc3RGaWxlKE9SSUdURVhUKTsKKyAgICBVcmkgdXJpV2l0aENoZWNrc3VtID0gc3RvcmFnZS5vcGVuKGluaXRpYWxVcmksIEludGVncml0eVVyaUNvbXB1dGluZ09wZW5lci5jcmVhdGUoKSk7CisgICAgU3RyaW5nIGRpZ2VzdCA9IEludGVncml0eVRyYW5zZm9ybS5nZXREaWdlc3RJZlByZXNlbnQodXJpV2l0aENoZWNrc3VtKTsKKworICAgIGFzc2VydFRoYXQoZGlnZXN0KS5pc0VxdWFsVG8oT1JJR1RFWFRfU0hBMjU2X0I2NCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbnRlZ3JpdHlVcmlDb21wdXRpbmdPcGVuZXJfc2hvdWxkSWdub3JlSW5jb3JyZWN0SW5pdGlhbFNwZWMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm0gc3BlYyA9CisgICAgICAgIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRJbnRlZ3JpdHkoCisgICAgICAgICAgICAgICAgVHJhbnNmb3JtUHJvdG8uSW50ZWdyaXR5VHJhbnNmb3JtLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0U2hhMjU2KE9SSUdURVhUX1NIQTI1Nl9CNjRfSU5DT1JSRUNUKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFVyaSBpbml0aWFsVXJpID0gVHJhbnNmb3JtUHJvdG9GcmFnbWVudHMuYWRkT3JSZXBsYWNlVHJhbnNmb3JtKGNyZWF0ZVRlc3RGaWxlKE9SSUdURVhUKSwgc3BlYyk7CisgICAgVXJpIHVyaVdpdGhDaGVja3N1bSA9IHN0b3JhZ2Uub3Blbihpbml0aWFsVXJpLCBJbnRlZ3JpdHlVcmlDb21wdXRpbmdPcGVuZXIuY3JlYXRlKCkpOworICAgIFN0cmluZyBkaWdlc3QgPSBJbnRlZ3JpdHlUcmFuc2Zvcm0uZ2V0RGlnZXN0SWZQcmVzZW50KHVyaVdpdGhDaGVja3N1bSk7CisKKyAgICBhc3NlcnRUaGF0KGRpZ2VzdCkuaXNFcXVhbFRvKE9SSUdURVhUX1NIQTI1Nl9CNjQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW50ZWdyaXR5VXJpQ29tcHV0aW5nT3BlbmVyX3Nob3VsZElnbm9yZUludGVncml0eVBhcmFtV2l0aE5vU3VicGFyYW0oKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtIHNwZWMgPQorICAgICAgICBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0SW50ZWdyaXR5KFRyYW5zZm9ybVByb3RvLkludGVncml0eVRyYW5zZm9ybS5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgVXJpIGluaXRpYWxVcmkgPSBUcmFuc2Zvcm1Qcm90b0ZyYWdtZW50cy5hZGRPclJlcGxhY2VUcmFuc2Zvcm0oY3JlYXRlVGVzdEZpbGUoT1JJR1RFWFQpLCBzcGVjKTsKKyAgICBVcmkgdXJpV2l0aENoZWNrc3VtID0gc3RvcmFnZS5vcGVuKGluaXRpYWxVcmksIEludGVncml0eVVyaUNvbXB1dGluZ09wZW5lci5jcmVhdGUoKSk7CisgICAgU3RyaW5nIGRpZ2VzdCA9IEludGVncml0eVRyYW5zZm9ybS5nZXREaWdlc3RJZlByZXNlbnQodXJpV2l0aENoZWNrc3VtKTsKKworICAgIGFzc2VydFRoYXQoZGlnZXN0KS5pc0VxdWFsVG8oT1JJR1RFWFRfU0hBMjU2X0I2NCk7CisgIH0KKworICBwcml2YXRlIFVyaSBjcmVhdGVUZXN0RmlsZShTdHJpbmcgY29udGVudHMpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIGNvbnRlbnRzKTsKKyAgICByZXR1cm4gdXJpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL01hcHBlZEJ5dGVCdWZmZXJPcGVuZXJBbmRyb2lkVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9NYXBwZWRCeXRlQnVmZmVyT3BlbmVyQW5kcm9pZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NTRjMTVjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9NYXBwZWRCeXRlQnVmZmVyT3BlbmVyQW5kcm9pZFRlc3QuamF2YQpAQCAtMCwwICsxLDEzNyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkJ1ZmZlcmluZ01vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5GaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuTm9PcE1vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlsczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuQ29tcHJlc3NUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLlRyYW5zZm9ybVByb3RvczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLm5pby5CeXRlQnVmZmVyOworaW1wb3J0IGphdmEubmlvLk1hcHBlZEJ5dGVCdWZmZXI7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuSlVuaXQ0OworCitAUnVuV2l0aChKVW5pdDQuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgTWFwcGVkQnl0ZUJ1ZmZlck9wZW5lckFuZHJvaWRUZXN0IHsKKworICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZTsKKworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5VXJpIHRtcFVyaSA9IG5ldyBUZW1wb3JhcnlVcmkoKTsKKyAgQFJ1bGUgcHVibGljIEZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXIgbGVha0NoZWNrZXIgPSBuZXcgRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlcigpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXBTdG9yYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihuZXcgSmF2YUZpbGVCYWNrZW5kKCkpLCBJbW11dGFibGVMaXN0Lm9mKG5ldyBDb21wcmVzc1RyYW5zZm9ybSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzdWNjZWVkc1dpdGhTaW1wbGVQYXRoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBieXRlW10gY29udGVudCA9IFN0cmVhbVV0aWxzLm1ha2VBcnJheU9mQnl0ZXNDb250ZW50KCk7CisgICAgU3RyZWFtVXRpbHMuY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIGNvbnRlbnQpOworCisgICAgTWFwcGVkQnl0ZUJ1ZmZlciBidWZmZXIgPSBzdG9yYWdlLm9wZW4odXJpLCBNYXBwZWRCeXRlQnVmZmVyT3BlbmVyLmNyZWF0ZUZvclJlYWQoKSk7CisgICAgYXNzZXJ0VGhhdChleHRyYWN0Qnl0ZXMoYnVmZmVyKSkuaXNFcXVhbFRvKGNvbnRlbnQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnVmZmVySXNSZWFkT25seSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgYnl0ZVtdIGNvbnRlbnQgPSBTdHJlYW1VdGlscy5tYWtlQXJyYXlPZkJ5dGVzQ29udGVudCgpOworICAgIFN0cmVhbVV0aWxzLmNyZWF0ZUZpbGUoc3RvcmFnZSwgdXJpLCBjb250ZW50KTsKKworICAgIE1hcHBlZEJ5dGVCdWZmZXIgYnVmZmVyID0gc3RvcmFnZS5vcGVuKHVyaSwgTWFwcGVkQnl0ZUJ1ZmZlck9wZW5lci5jcmVhdGVGb3JSZWFkKCkpOworICAgIGFzc2VydFRoYXQoYnVmZmVyLmlzUmVhZE9ubHkoKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBmYWlsc1dpdGhUcmFuc2Zvcm0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaUJ1aWxkZXIoKS53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0NPTVBSRVNTX1NQRUMpLmJ1aWxkKCk7CisgICAgYnl0ZVtdIGNvbnRlbnQgPSBTdHJlYW1VdGlscy5tYWtlQXJyYXlPZkJ5dGVzQ29udGVudCgpOworICAgIFN0cmVhbVV0aWxzLmNyZWF0ZUZpbGUoc3RvcmFnZSwgdXJpLCBjb250ZW50KTsKKworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IHN0b3JhZ2Uub3Blbih1cmksIE1hcHBlZEJ5dGVCdWZmZXJPcGVuZXIuY3JlYXRlRm9yUmVhZCgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBmYWlsc1dpdGhNaXNzaW5nRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSBVcmkucGFyc2UoImZpbGU6L2RvZXMtbm90LWV4aXN0Iik7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLm9wZW4odXJpLCBNYXBwZWRCeXRlQnVmZmVyT3BlbmVyLmNyZWF0ZUZvclJlYWQoKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZmFpbHNXaXRoQWN0aXZlTW9uaXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZVdpdGhNb25pdG9yID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKG5ldyBKYXZhRmlsZUJhY2tlbmQoKSksCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKG5ldyBCdWZmZXJpbmdNb25pdG9yKCkpKTsKKworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgYnl0ZVtdIGNvbnRlbnQgPSBTdHJlYW1VdGlscy5tYWtlQXJyYXlPZkJ5dGVzQ29udGVudCgpOworICAgIFN0cmVhbVV0aWxzLmNyZWF0ZUZpbGUoc3RvcmFnZVdpdGhNb25pdG9yLCB1cmksIGNvbnRlbnQpOworCisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBJT0V4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgKCkgLT4gc3RvcmFnZVdpdGhNb25pdG9yLm9wZW4odXJpLCBNYXBwZWRCeXRlQnVmZmVyT3BlbmVyLmNyZWF0ZUZvclJlYWQoKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc3VjY2VlZHNXaXRoSW5hY3RpdmVNb25pdG9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlV2l0aE1vbml0b3IgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IEphdmFGaWxlQmFja2VuZCgpKSwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IE5vT3BNb25pdG9yKCkpKTsKKworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgYnl0ZVtdIGNvbnRlbnQgPSBTdHJlYW1VdGlscy5tYWtlQXJyYXlPZkJ5dGVzQ29udGVudCgpOworICAgIFN0cmVhbVV0aWxzLmNyZWF0ZUZpbGUoc3RvcmFnZVdpdGhNb25pdG9yLCB1cmksIGNvbnRlbnQpOworCisgICAgTWFwcGVkQnl0ZUJ1ZmZlciBidWZmZXIgPSBzdG9yYWdlV2l0aE1vbml0b3Iub3Blbih1cmksIE1hcHBlZEJ5dGVCdWZmZXJPcGVuZXIuY3JlYXRlRm9yUmVhZCgpKTsKKyAgICBhc3NlcnRUaGF0KGV4dHJhY3RCeXRlcyhidWZmZXIpKS5pc0VxdWFsVG8oY29udGVudCk7CisgIH0KKworICAvKioKKyAgICogRXh0cmFjdHMgdGhlIGJ5dGVbXSBmcm9tIHRoZSBCeXRlQnVmZmVyLiBUaGlzIG1ldGhvZCBpcyBmb3JrZWQgZnJvbSBHdWF2YSBCeXRlQnVmZmVycywgd2hpY2gKKyAgICogaXNuJ3QgYXZhaWxhYmxlIG9uIEFuZHJvaWQuCisgICAqLworICBwcml2YXRlIHN0YXRpYyBieXRlW10gZXh0cmFjdEJ5dGVzKEJ5dGVCdWZmZXIgYnVmKSB7CisgICAgYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2J1Zi5yZW1haW5pbmcoKV07CisgICAgYnVmLmdldChyZXN1bHQpOworICAgIGJ1Zi5wb3NpdGlvbihidWYucG9zaXRpb24oKSAtIHJlc3VsdC5sZW5ndGgpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvTmF0aXZlUmVhZE9wZW5lckFuZHJvaWRUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL05hdGl2ZVJlYWRPcGVuZXJBbmRyb2lkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2YWIzYTgKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL05hdGl2ZVJlYWRPcGVuZXJBbmRyb2lkVGVzdC5qYXZhCkBAIC0wLDAgKzEsODQgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLmNyZWF0ZUZpbGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0cy5VVEZfODsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuRmlsZURlc2NyaXB0b3JVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5KYXZhRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5GaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVtcG9yYXJ5VXJpOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5DaGFyU3RyZWFtczsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlTm90Rm91bmRFeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLkpVbml0NDsKKworQFJ1bldpdGgoSlVuaXQ0LmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIE5hdGl2ZVJlYWRPcGVuZXJBbmRyb2lkVGVzdCB7CisKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisKKyAgQFJ1bGUgcHVibGljIEZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXIgbGVha0NoZWNrZXIgPSBuZXcgRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlcigpOworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5VXJpIHRtcFVyaSA9IG5ldyBUZW1wb3JhcnlVcmkoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIGluaXRTdG9yYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3RvcmFnZSA9IG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEltbXV0YWJsZUxpc3Qub2YobmV3IEphdmFGaWxlQmFja2VuZCgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRm9yTmF0aXZlUmVhZF9yZXR1cm5zQVdvcmtpbmdGaWxlRGVzY3JpcHRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksICJjb250ZW50Iik7CisgICAgQ2xvc2VhYmxlVXJpIHJlc3VsdCA9IHN0b3JhZ2Uub3Blbih1cmksIE5hdGl2ZVJlYWRPcGVuZXIuY3JlYXRlKCkpOworCisgICAgYXNzZXJ0VGhhdChyZXN1bHQudXJpKCkuZ2V0U2NoZW1lKCkpLmlzRXF1YWxUbygiZmQiKTsKKyAgICBhc3NlcnRUaGF0KEZpbGVEZXNjcmlwdG9yVXJpLmdldEZkKHJlc3VsdC51cmkoKSkpLmlzR3JlYXRlclRoYW4oMCk7CisKKyAgICAvLyBVc2UgcHJvYyBmaWxlc3lzdGVtIHRvIHZlcmlmeSBkYXRhLgorICAgIEZpbGUgZmRGaWxlID0gbmV3IEZpbGUoIi9wcm9jL3NlbGYvZmQvIiArIHJlc3VsdC51cmkoKS5nZXRTY2hlbWVTcGVjaWZpY1BhcnQoKSk7CisgICAgSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZkRmlsZSk7CisgICAgUmVhZGVyIHJlYWRlciA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihpbiwgVVRGXzgpOworICAgIGFzc2VydFRoYXQoQ2hhclN0cmVhbXMudG9TdHJpbmcocmVhZGVyKSkuaXNFcXVhbFRvKCJjb250ZW50Iik7CisKKyAgICAvLyBWZXJpZnkgY2xvc2luZyBiZWhhdmlvci4KKyAgICBhc3NlcnRUaGF0KGZkRmlsZS5leGlzdHMoKSkuaXNUcnVlKCk7CisgICAgcmVhZGVyLmNsb3NlKCk7IC8vIFRoaXMgd29uJ3QgYWN0dWFsbHkgY2xvc2UgdGhlIGZkLgorICAgIGFzc2VydFRoYXQoZmRGaWxlLmV4aXN0cygpKS5pc1RydWUoKTsKKyAgICByZXN1bHQuY2xvc2UoKTsgLy8gVGhpcyBkb2VzLgorICAgIGFzc2VydFRoYXQoZmRGaWxlLmV4aXN0cygpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRm9yTmF0aXZlUmVhZF93aXRoTWlzc2luZ0ZpbGVfdGhyb3dzRmlsZU5vdEZvdW5kKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiZmlsZTovZG9lcy1ub3QtZXhpc3QiKTsKKyAgICBhc3NlcnRUaHJvd3MoRmlsZU5vdEZvdW5kRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLm9wZW4odXJpLCBOYXRpdmVSZWFkT3BlbmVyLmNyZWF0ZSgpKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvTmF0aXZlUmVhZE9wZW5lclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvTmF0aXZlUmVhZE9wZW5lclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMWQzZDljCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9OYXRpdmVSZWFkT3BlbmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsODUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkZyYWdtZW50UGFyYW1NYXRjaGVycy5lcVBhcmFtOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5lcTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by5uZXZlcjsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ud2hlbjsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5GaWxlVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5UcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLlRyYW5zZm9ybVByb3RvczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS50aGlyZHBhcnR5LnJvYm9sZWN0cmljLkdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBqYXZhLmlvLkNsb3NlYWJsZTsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworCitAUnVuV2l0aChHb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgTmF0aXZlUmVhZE9wZW5lclRlc3QgeworCisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworCisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgQE1vY2sgcHJvdGVjdGVkIEJhY2tlbmQgZmlsZUJhY2tlbmQ7CisgIEBNb2NrIHByb3RlY3RlZCBUcmFuc2Zvcm0gY29tcHJlc3NUcmFuc2Zvcm07CisgIEBNb2NrIHByb3RlY3RlZCBNb25pdG9yIGNvdW50aW5nTW9uaXRvcjsKKyAgQE1vY2sgcHJvdGVjdGVkIENsb3NlYWJsZSBjbG9zZWFibGU7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBpbml0U3RvcmFnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHdoZW4oZmlsZUJhY2tlbmQubmFtZSgpKS50aGVuUmV0dXJuKCJmaWxlIik7CisgICAgd2hlbihjb21wcmVzc1RyYW5zZm9ybS5uYW1lKCkpLnRoZW5SZXR1cm4oImNvbXByZXNzIik7CisgICAgd2hlbihmaWxlQmFja2VuZC5vcGVuRm9yTmF0aXZlUmVhZChhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKFBhaXIuY3JlYXRlKFVyaS5wYXJzZSgiZmQ6MTIzIiksIGNsb3NlYWJsZSkpOworCisgICAgc3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihmaWxlQmFja2VuZCksCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKGNvbXByZXNzVHJhbnNmb3JtKSwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoY291bnRpbmdNb25pdG9yKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBuYXRpdmVSZWFkX3Nob3VsZEVuY29kZUJ1dE5vdEludm9rZVRyYW5zZm9ybXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgZmlsZTFGaWxlbmFtZSA9ICJmaWxlMS50eHQiOworICAgIFVyaSBmaWxlMUNvbXByZXNzVXJpID0KKyAgICAgICAgRmlsZVVyaS5idWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRQYXRoKGZpbGUxRmlsZW5hbWUpCisgICAgICAgICAgICAud2l0aFRyYW5zZm9ybShUcmFuc2Zvcm1Qcm90b3MuREVGQVVMVF9DT01QUkVTU19TUEVDKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgVXJpIGNvbXByZXNzUGFyYW0gPSBVcmkucGFyc2UoIiN0cmFuc2Zvcm09Y29tcHJlc3MiKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2Uub3BlbihmaWxlMUNvbXByZXNzVXJpLCBOYXRpdmVSZWFkT3BlbmVyLmNyZWF0ZSgpKSkuaXNOb3ROdWxsKCk7CisgICAgdmVyaWZ5KGNvbXByZXNzVHJhbnNmb3JtLCBuZXZlcigpKS53cmFwRm9yUmVhZChlcVBhcmFtKGNvbXByZXNzUGFyYW0pLCBhbnkoSW5wdXRTdHJlYW0uY2xhc3MpKTsKKyAgICB2ZXJpZnkoY29tcHJlc3NUcmFuc2Zvcm0pLmVuY29kZShlcVBhcmFtKGNvbXByZXNzUGFyYW0pLCBlcShmaWxlMUZpbGVuYW1lKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUGFyY2VsRmlsZURlc2NyaXB0b3JPcGVuZXJBbmRyb2lkVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9QYXJjZWxGaWxlRGVzY3JpcHRvck9wZW5lckFuZHJvaWRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmI5ODJiZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUGFyY2VsRmlsZURlc2NyaXB0b3JPcGVuZXJBbmRyb2lkVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA4IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5jcmVhdGVGaWxlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHMuVVRGXzg7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuUGFyY2VsRmlsZURlc2NyaXB0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuSmF2YUZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5GaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5UZW1wb3JhcnlVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zYW1wbGVzLkJ5dGVDb3VudGluZ01vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLkNvbXByZXNzVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5UcmFuc2Zvcm1Qcm90b3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmlvLkNoYXJTdHJlYW1zOworaW1wb3J0IGphdmEuaW8uRmlsZU5vdEZvdW5kRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLmlvLlJlYWRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5KVW5pdDQ7CisKK0BSdW5XaXRoKEpVbml0NC5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBQYXJjZWxGaWxlRGVzY3JpcHRvck9wZW5lckFuZHJvaWRUZXN0IHsKKworICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZTsKKworICBAUnVsZSBwdWJsaWMgRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlciBsZWFrQ2hlY2tlciA9IG5ldyBGaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyKCk7CisgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlVcmkgdG1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgaW5pdFN0b3JhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9yYWdlID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKG5ldyBKYXZhRmlsZUJhY2tlbmQoKSksIEltbXV0YWJsZUxpc3Qub2YobmV3IENvbXByZXNzVHJhbnNmb3JtKCkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5QYXJjZWxGaWxlRGVzY3JpcHRvcl9zaG91bGRSZWFkRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksICJjb250ZW50Iik7CisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgIG5ldyBQYXJjZWxGaWxlRGVzY3JpcHRvci5BdXRvQ2xvc2VJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgIHN0b3JhZ2Uub3Blbih1cmksIFBhcmNlbEZpbGVEZXNjcmlwdG9yT3BlbmVyLmNyZWF0ZSgpKSkpIHsKKyAgICAgIFJlYWRlciByZWFkZXIgPSBuZXcgSW5wdXRTdHJlYW1SZWFkZXIoaW4sIFVURl84KTsKKyAgICAgIGFzc2VydFRoYXQoQ2hhclN0cmVhbXMudG9TdHJpbmcocmVhZGVyKSkuaXNFcXVhbFRvKCJjb250ZW50Iik7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlblBhcmNlbEZpbGVEZXNjcmlwdG9yX3dpdGhNaXNzaW5nRmlsZV90aHJvd3NGaWxlTm90Rm91bmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gVXJpLnBhcnNlKCJmaWxlOi9kb2VzLW5vdC1leGlzdCIpOworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgRmlsZU5vdEZvdW5kRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLm9wZW4odXJpLCBQYXJjZWxGaWxlRGVzY3JpcHRvck9wZW5lci5jcmVhdGUoKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlblBhcmNlbEZpbGVEZXNjcmlwdG9yX3dpdGhNb25pdG9yX3Nob3VsZFJlYWRGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlV2l0aE1vbml0b3IgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IEphdmFGaWxlQmFja2VuZCgpKSwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IEJ5dGVDb3VudGluZ01vbml0b3IoKSkpOworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgYnl0ZVtdIGNvbnRlbnQgPSBTdHJlYW1VdGlscy5tYWtlQXJyYXlPZkJ5dGVzQ29udGVudCgpOworICAgIFN0cmVhbVV0aWxzLmNyZWF0ZUZpbGUoc3RvcmFnZVdpdGhNb25pdG9yLCB1cmksIGNvbnRlbnQpOworCisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgIG5ldyBQYXJjZWxGaWxlRGVzY3JpcHRvci5BdXRvQ2xvc2VJbnB1dFN0cmVhbSgKKyAgICAgICAgICAgIHN0b3JhZ2VXaXRoTW9uaXRvci5vcGVuKHVyaSwgUGFyY2VsRmlsZURlc2NyaXB0b3JPcGVuZXIuY3JlYXRlKCkpKSkgeworICAgICAgYXNzZXJ0VGhhdChTdHJlYW1VdGlscy5yZWFkRmlsZUluQnl0ZXNGcm9tU291cmNlKGluKSkuaXNFcXVhbFRvKGNvbnRlbnQpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5QYXJjZWxGaWxlRGVzY3JpcHRvcl93aXRoVHJhbnNmb3JtX3Rocm93c1Vuc3VwcG9ydGVkT3BlcmF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmlCdWlsZGVyKCkud2l0aFRyYW5zZm9ybShUcmFuc2Zvcm1Qcm90b3MuREVGQVVMVF9DT01QUkVTU19TUEVDKS5idWlsZCgpOworICAgIGJ5dGVbXSBjb250ZW50ID0gU3RyZWFtVXRpbHMubWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoKTsKKyAgICBTdHJlYW1VdGlscy5jcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgY29udGVudCk7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIFVuc3VwcG9ydGVkRmlsZVN0b3JhZ2VPcGVyYXRpb24uY2xhc3MsCisgICAgICAgICgpIC0+IHN0b3JhZ2Uub3Blbih1cmksIFBhcmNlbEZpbGVEZXNjcmlwdG9yT3BlbmVyLmNyZWF0ZSgpKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUGlwZXNUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1BpcGVzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEzYTRiM2MKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1BpcGVzVGVzdC5qYXZhCkBAIC0wLDAgKzEsNTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKKworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24uVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLnRoaXJkcGFydHkucm9ib2xlY3RyaWMuR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGVtcG9yYXJ5Rm9sZGVyOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuYW5ub3RhdGlvbi5Db25maWc7CisKKy8qKiBCYXNpYyB0ZXN0IHRvIGVuc3VyZSB0aGF0IG5hbWVkIHBpcGVzIGFyZSBvbmx5IGF0dGVtcHRlZCBhdCBjb21wYXRpYmxlIHNkayBsZXZlbHMuICovCitAUnVuV2l0aChHb29nbGVSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgUGlwZXNUZXN0IHsKKworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5Rm9sZGVyIHRtcEZvbGRlciA9IG5ldyBUZW1wb3JhcnlGb2xkZXIoKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIlBpcGVzVGVzdCI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEF0b21pY0ludGVnZXIgRklGT19DT1VOVEVSID0gbmV3IEF0b21pY0ludGVnZXIoKTsKKworICBAVGVzdAorICBAQ29uZmlnKHNkayA9IHtCdWlsZC5WRVJTSU9OX0NPREVTLktJVEtBVH0pCisgIHB1YmxpYyB2b2lkIG1ha2VGaWZvX2JlbG93TG9sbGlwb3BfdGhyb3dzVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgVW5zdXBwb3J0ZWRGaWxlU3RvcmFnZU9wZXJhdGlvbi5jbGFzcywKKyAgICAgICAgKCkgLT4gUGlwZXMubWFrZUZpZm8odG1wRm9sZGVyLm5ld0ZvbGRlcigpLCBUQUcsIEZJRk9fQ09VTlRFUikpOworICB9CisKKyAgQFRlc3QKKyAgQENvbmZpZyhzZGsgPSB7QnVpbGQuVkVSU0lPTl9DT0RFUy5MT0xMSVBPUH0pCisgIHB1YmxpYyB2b2lkIG1ha2VGaWZvX29uTG9sbGlwb3BfZG9lc05vdFRocm93KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gTk9URTogdGhlIHJlc3VsdGFudCBwaXBlIGlzIGludmFsaWQgYmVjYXVzZSBSb2JvbGVjdHJpYyBkb2Vzbid0IGZ1bGx5IHN1cHBvcnQKKyAgICAvLyBPcy5ta0ZpZm8sIGJ1dCB3ZSdyZSBoYXBweSBhcyBsb25nIGFzIHRoZSBjYWxsIHN1Y2NlZWRzCisgICAgRmlsZSB1bnVzZWRGaWZvID0gUGlwZXMubWFrZUZpZm8odG1wRm9sZGVyLm5ld0ZvbGRlcigpLCBUQUcsIEZJRk9fQ09VTlRFUik7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmFuZG9tQWNjZXNzRmlsZU9wZW5lckFuZHJvaWRUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JhbmRvbUFjY2Vzc0ZpbGVPcGVuZXJBbmRyb2lkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFkZWI1M2MKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JhbmRvbUFjY2Vzc0ZpbGVPcGVuZXJBbmRyb2lkVGVzdC5qYXZhCkBAIC0wLDAgKzEsODIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkZpbGVVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5KYXZhRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5GaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uUmFuZG9tQWNjZXNzRmlsZTsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UZW1wb3JhcnlGb2xkZXI7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLkpVbml0NDsKKworQFJ1bldpdGgoSlVuaXQ0LmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIFJhbmRvbUFjY2Vzc0ZpbGVPcGVuZXJBbmRyb2lkVGVzdCB7CisKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeUZvbGRlciB0bXBGb2xkZXIgPSBuZXcgVGVtcG9yYXJ5Rm9sZGVyKCk7CisgIEBSdWxlIHB1YmxpYyBGaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyIGxlYWtDaGVja2VyID0gbmV3IEZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXIoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwU3RvcmFnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN0b3JhZ2UgPSBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZShJbW11dGFibGVMaXN0Lm9mKG5ldyBKYXZhRmlsZUJhY2tlbmQoKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc3VjY2VlZHNXaXRoU2ltcGxlUGF0aCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB1cmlUb05ld1RlbXBGaWxlKCkuYnVpbGQoKTsKKyAgICBieXRlW10gY29udGVudCA9IFN0cmVhbVV0aWxzLm1ha2VBcnJheU9mQnl0ZXNDb250ZW50KCk7CisgICAgU3RyZWFtVXRpbHMuY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIGNvbnRlbnQpOworCisgICAgUmFuZG9tQWNjZXNzRmlsZU9wZW5lciBvcGVuZXIgPSBSYW5kb21BY2Nlc3NGaWxlT3BlbmVyLmNyZWF0ZUZvclJlYWQoKTsKKyAgICBSYW5kb21BY2Nlc3NGaWxlIGZpbGUgPSBzdG9yYWdlLm9wZW4odXJpLCBvcGVuZXIpOworICAgIGFzc2VydFRoYXQoU3RyZWFtVXRpbHMucmVhZEZpbGVJbkJ5dGVzRnJvbVNvdXJjZShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUuZ2V0RkQoKSkpKQorICAgICAgICAuaXNFcXVhbFRvKGNvbnRlbnQpOworCisgICAgZmlsZS5jbG9zZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc3VjY2VlZHNXaXRoQ3JlYXRlRm9yUmVhZFdyaXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9CisgICAgICAgIEZpbGVVcmkuYnVpbGRlcigpCisgICAgICAgICAgICAuZnJvbUZpbGUodG1wRm9sZGVyLmdldFJvb3QoKSkKKyAgICAgICAgICAgIC5hcHBlbmRQYXRoKCJ0aGlzL2RvZXMvbm90L2V4aXN0L2Zvby5wYiIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIFJhbmRvbUFjY2Vzc0ZpbGVPcGVuZXIgb3BlbmVyID0gUmFuZG9tQWNjZXNzRmlsZU9wZW5lci5jcmVhdGVGb3JSZWFkV3JpdGUoKTsKKyAgICB0cnkgKFJhbmRvbUFjY2Vzc0ZpbGUgZmlsZSA9IHN0b3JhZ2Uub3Blbih1cmksIG9wZW5lcikpIHsKKyAgICAgIGZpbGUud3JpdGUoMTIzKTsKKyAgICAgIGZpbGUuc2VlaygwKTsKKyAgICAgIGFzc2VydFRoYXQoZmlsZS5yZWFkKCkpLmlzRXF1YWxUbygxMjMpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgRmlsZVVyaS5CdWlsZGVyIHVyaVRvTmV3VGVtcEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gRmlsZVVyaS5idWlsZGVyKCkuZnJvbUZpbGUodG1wRm9sZGVyLm5ld0ZpbGUoKSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZEJ5dGVBcnJheU9wZW5lclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZEJ5dGVBcnJheU9wZW5lclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMTFjMGY0Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9SZWFkQnl0ZUFycmF5T3BlbmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTEwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5jcmVhdGVGaWxlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLm1ha2VBcnJheU9mQnl0ZXNDb250ZW50OworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkZha2VGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNhbXBsZXMuQnl0ZUNvdW50aW5nTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuQ29tcHJlc3NUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLlRyYW5zZm9ybVByb3RvczsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgUmVhZEJ5dGVBcnJheU9wZW5lclRlc3QgeworCisgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlVcmkgdG1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworCisgIHByaXZhdGUgZmluYWwgRmFrZUZpbGVCYWNrZW5kIGZha2VCYWNrZW5kID0gbmV3IEZha2VGaWxlQmFja2VuZCgpOworCisgIHB1YmxpYyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2VXaXRoVHJhbnNmb3JtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICBBcnJheXMuYXNMaXN0KG5ldyBKYXZhRmlsZUJhY2tlbmQoKSksIEFycmF5cy5hc0xpc3QobmV3IENvbXByZXNzVHJhbnNmb3JtKCkpKTsKKyAgfQorCisgIHB1YmxpYyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2VXaXRoTW9uaXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIHJldHVybiBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgQXJyYXlzLmFzTGlzdChuZXcgSmF2YUZpbGVCYWNrZW5kKCkpLAorICAgICAgICBBcnJheXMuYXNMaXN0KCksCisgICAgICAgIEFycmF5cy5hc0xpc3QobmV3IEJ5dGVDb3VudGluZ01vbml0b3IoKSkpOworICB9CisKKyAgcHVibGljIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZVdpdGhGYWtlQmFja2VuZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHJldHVybiBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZShBcnJheXMuYXNMaXN0KGZha2VCYWNrZW5kKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkaXJlY3RGaWxlX3Byb2R1Y2VzQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aFRyYW5zZm9ybSgpOworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgYnl0ZVtdIGV4cGVjdGVkID0gbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgZXhwZWN0ZWQpOworCisgICAgUmVhZEJ5dGVBcnJheU9wZW5lciBvcGVuZXIgPSBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpOworICAgIGJ5dGVbXSBieXRlcyA9IHN0b3JhZ2Uub3Blbih1cmksIG9wZW5lcik7CisKKyAgICBhc3NlcnRUaGF0KGJ5dGVzKS5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd2l0aE1vbml0b3JfcHJvZHVjZXNBcnJheSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IHN0b3JhZ2VXaXRoTW9uaXRvcigpOworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgYnl0ZVtdIGV4cGVjdGVkID0gbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgZXhwZWN0ZWQpOworCisgICAgUmVhZEJ5dGVBcnJheU9wZW5lciBvcGVuZXIgPSBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpOworICAgIGJ5dGVbXSBieXRlcyA9IHN0b3JhZ2Uub3Blbih1cmksIG9wZW5lcik7CisKKyAgICBhc3NlcnRUaGF0KGJ5dGVzKS5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd2l0aFRyYW5zZm9ybV9wcm9kdWNlc0FycmF5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlID0gc3RvcmFnZVdpdGhUcmFuc2Zvcm0oKTsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaUJ1aWxkZXIoKS53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0NPTVBSRVNTX1NQRUMpLmJ1aWxkKCk7CisgICAgYnl0ZVtdIGV4cGVjdGVkID0gbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgZXhwZWN0ZWQpOworCisgICAgUmVhZEJ5dGVBcnJheU9wZW5lciBvcGVuZXIgPSBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpOworICAgIGJ5dGVbXSBieXRlcyA9IHN0b3JhZ2Uub3Blbih1cmksIG9wZW5lcik7CisKKyAgICBhc3NlcnRUaGF0KGJ5dGVzKS5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd2l0aEZha2VCYWNrZW5kX3Byb2R1Y2VzQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aEZha2VCYWNrZW5kKCk7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBieXRlW10gZXhwZWN0ZWQgPSBtYWtlQXJyYXlPZkJ5dGVzQ29udGVudCgpOworCisgICAgc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVCeXRlQXJyYXlPcGVuZXIuY3JlYXRlKGV4cGVjdGVkKSk7CisKKyAgICBieXRlW10gYnl0ZXMgPSBzdG9yYWdlLm9wZW4odXJpLCBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpKTsKKworICAgIGFzc2VydFRoYXQoYnl0ZXMpLmlzRXF1YWxUbyhleHBlY3RlZCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZEZpbGVPcGVuZXJBbmRyb2lkVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9SZWFkRmlsZU9wZW5lckFuZHJvaWRUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODYyNmY1YgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZEZpbGVPcGVuZXJBbmRyb2lkVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjM4IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5tYWtlQ29udGVudFRoYXRFeGNlZWRzT3NCdWZmZXJTaXplOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLnJlYWRGaWxlRnJvbVNvdXJjZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy53cml0ZUZpbGVUb1Npbms7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuUHJvY2VzczsKK2ltcG9ydCBhbmRyb2lkLnN5c3RlbS5PczsKK2ltcG9ydCBhbmRyb2lkLnN5c3RlbS5Pc0NvbnN0YW50czsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuRmlsZVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5VbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuQWx3YXlzVGhyb3dzVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc2FtcGxlcy5CeXRlQ291bnRpbmdNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5Db21wcmVzc1RyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuVHJhbnNmb3JtUHJvdG9zOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVsZXMuVGVtcG9yYXJ5Rm9sZGVyOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5KVW5pdDQ7CisKK0BSdW5XaXRoKEpVbml0NC5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBSZWFkRmlsZU9wZW5lckFuZHJvaWRUZXN0IHsKKworICBwcml2YXRlIGZpbmFsIFN0cmluZyBzbWFsbENvbnRlbnQgPSAiY29udGVudCI7CisgIHByaXZhdGUgZmluYWwgU3RyaW5nIGJpZ0NvbnRlbnQgPSBtYWtlQ29udGVudFRoYXRFeGNlZWRzT3NCdWZmZXJTaXplKCk7CisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworICBwcml2YXRlIEV4ZWN1dG9yU2VydmljZSBleGVjdXRvciA9IEV4ZWN1dG9ycy5uZXdDYWNoZWRUaHJlYWRQb29sKCk7CisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5Rm9sZGVyIHRtcEZvbGRlciA9IG5ldyBUZW1wb3JhcnlGb2xkZXIoKTsKKyAgQFJ1bGUgcHVibGljIEZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXIgbGVha0NoZWNrZXIgPSBuZXcgRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlcigpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXBTdG9yYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihuZXcgSmF2YUZpbGVCYWNrZW5kKCkpLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihuZXcgQ29tcHJlc3NUcmFuc2Zvcm0oKSwgbmV3IEFsd2F5c1Rocm93c1RyYW5zZm9ybSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjb21wcmVzc0FuZFJlYWRCaWdDb250ZW50RnJvbVBpcGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdXJpVG9OZXdUZW1wRmlsZSgpLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfQ09NUFJFU1NfU1BFQykuYnVpbGQoKTsKKyAgICB3cml0ZUZpbGVUb1Npbmsoc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpLCBiaWdDb250ZW50KTsKKyAgICBSZWFkRmlsZU9wZW5lciBvcGVuZXIgPQorICAgICAgICBSZWFkRmlsZU9wZW5lci5jcmVhdGUoKS53aXRoRmFsbGJhY2tUb1BpcGVVc2luZ0V4ZWN1dG9yKGV4ZWN1dG9yLCBjb250ZXh0KTsKKyAgICBGaWxlIHBpcGVkID0gc3RvcmFnZS5vcGVuKHVyaSwgb3BlbmVyKTsKKyAgICBhc3NlcnRUaGF0KHBpcGVkLmdldEFic29sdXRlUGF0aCgpKS5lbmRzV2l0aCgiLmZpZm8iKTsKKyAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ocGlwZWQpKSB7CisgICAgICBhc3NlcnRUaGF0KHJlYWRGaWxlRnJvbVNvdXJjZShpbikpLmlzRXF1YWxUbyhiaWdDb250ZW50KTsKKyAgICB9CisgICAgYXNzZXJ0VGhhdChwaXBlZC5leGlzdHMoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY29tcHJlc3NBbmRSZWFkU21hbGxDb250ZW50RnJvbVBpcGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdXJpVG9OZXdUZW1wRmlsZSgpLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfQ09NUFJFU1NfU1BFQykuYnVpbGQoKTsKKyAgICB3cml0ZUZpbGVUb1Npbmsoc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpLCBzbWFsbENvbnRlbnQpOworICAgIFJlYWRGaWxlT3BlbmVyIG9wZW5lciA9CisgICAgICAgIFJlYWRGaWxlT3BlbmVyLmNyZWF0ZSgpLndpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoZXhlY3V0b3IsIGNvbnRleHQpOworICAgIEZpbGUgcGlwZWQgPSBzdG9yYWdlLm9wZW4odXJpLCBvcGVuZXIpOworICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGluID0gbmV3IEZpbGVJbnB1dFN0cmVhbShwaXBlZCkpIHsKKyAgICAgIGFzc2VydFRoYXQocmVhZEZpbGVGcm9tU291cmNlKGluKSkuaXNFcXVhbFRvKHNtYWxsQ29udGVudCk7CisgICAgfQorICAgIGFzc2VydFRoYXQocGlwZWQuZXhpc3RzKCkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNvbXByZXNzV2l0aFBhcnRpYWxSZWFkRnJvbVBpcGVfc2hvdWxkTm90TGVhaygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB1cmlUb05ld1RlbXBGaWxlKCkud2l0aFRyYW5zZm9ybShUcmFuc2Zvcm1Qcm90b3MuREVGQVVMVF9DT01QUkVTU19TUEVDKS5idWlsZCgpOworICAgIHdyaXRlRmlsZVRvU2luayhzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKSksIGJpZ0NvbnRlbnQpOworICAgIFJlYWRGaWxlT3BlbmVyIG9wZW5lciA9CisgICAgICAgIFJlYWRGaWxlT3BlbmVyLmNyZWF0ZSgpLndpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoZXhlY3V0b3IsIGNvbnRleHQpOworICAgIEZpbGUgcGlwZWQgPSBzdG9yYWdlLm9wZW4odXJpLCBvcGVuZXIpOworICAgIGFzc2VydFRoYXQocGlwZWQuZ2V0QWJzb2x1dGVQYXRoKCkpLmVuZHNXaXRoKCIuZmlmbyIpOworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKHBpcGVkKSkgeworICAgICAgaW4ucmVhZCgpOyAvLyBKdXN0IHJlYWQgMSBieXRlLgorICAgIH0KKyAgICBhc3NlcnRUaHJvd3MoSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IG9wZW5lci53YWl0Rm9yUHVtcCgpKTsKKyAgICBhc3NlcnRUaGF0KHBpcGVkLmV4aXN0cygpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjb21wcmVzc0FuZFJlYWRGcm9tUGlwZVdpdGhvdXRFeGVjdXRvcl9zaG91bGRGYWlsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHVyaVRvTmV3VGVtcEZpbGUoKS53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0NPTVBSRVNTX1NQRUMpLmJ1aWxkKCk7CisgICAgd3JpdGVGaWxlVG9TaW5rKHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSwgYmlnQ29udGVudCk7CisgICAgYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLm9wZW4odXJpLCBSZWFkRmlsZU9wZW5lci5jcmVhdGUoKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVhZEZyb21QbGFpbkZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdXJpVG9OZXdUZW1wRmlsZSgpLmJ1aWxkKCk7IC8vIE5vIHRyYW5zZm9ybXMuCisgICAgd3JpdGVGaWxlVG9TaW5rKHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSwgYmlnQ29udGVudCk7CisgICAgRmlsZSBkaXJlY3QgPQorICAgICAgICBzdG9yYWdlLm9wZW4oCisgICAgICAgICAgICB1cmksIFJlYWRGaWxlT3BlbmVyLmNyZWF0ZSgpLndpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoZXhlY3V0b3IsIGNvbnRleHQpKTsKKyAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZGlyZWN0KSkgeworICAgICAgYXNzZXJ0VGhhdChkaXJlY3QuZ2V0QWJzb2x1dGVQYXRoKCkpLnN0YXJ0c1dpdGgodG1wRm9sZGVyLmdldFJvb3QoKS50b1N0cmluZygpKTsKKyAgICAgIGFzc2VydFRoYXQocmVhZEZpbGVGcm9tU291cmNlKGluKSkuaXNFcXVhbFRvKGJpZ0NvbnRlbnQpOworICAgIH0KKyAgICBhc3NlcnRUaGF0KGRpcmVjdC5leGlzdHMoKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZWFkaW5nRnJvbVBpcGVXaXRoRXhjZXB0aW9uX3Nob3VsZFJldHVybkVtcHR5UGlwZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIEEgcHJldmlvdXMgaW1wbGVtZW50YXRpb24gaGFkIGEgcmFjZSBjb25kaXRpb24gd2hlcmUgaXQgd2FzIHBvc3NpYmxlIHRvIHJlYWQgZnJvbQorICAgIC8vIGFuIHVucmVsYXRlZCBmaWxlIGRlc2NyaXB0b3IgaWYgYW4gZXhjZXB0aW9uIHdhcyB0aHJvd24gaW4gYmFja2dyb3VuZCBwdW1wIHRocmVhZC4KKyAgICBGaWxlVXJpLkJ1aWxkZXIgdXJpQnVpbGRlciA9IHVyaVRvTmV3VGVtcEZpbGUoKTsKKyAgICB3cml0ZUZpbGVUb1Npbmsoc3RvcmFnZS5vcGVuKHVyaUJ1aWxkZXIuYnVpbGQoKSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpLCBiaWdDb250ZW50KTsKKyAgICBSZWFkRmlsZU9wZW5lciBvcGVuZXIgPQorICAgICAgICBSZWFkRmlsZU9wZW5lci5jcmVhdGUoKS53aXRoRmFsbGJhY2tUb1BpcGVVc2luZ0V4ZWN1dG9yKGV4ZWN1dG9yLCBjb250ZXh0KTsKKyAgICBGaWxlIGZpbGUgPQorICAgICAgICBzdG9yYWdlLm9wZW4oCisgICAgICAgICAgICB1cmlCdWlsZGVyLmJ1aWxkKCkuYnVpbGRVcG9uKCkuZW5jb2RlZEZyYWdtZW50KCJ0cmFuc2Zvcm09YWx3YXlzdGhyb3dzIikuYnVpbGQoKSwKKyAgICAgICAgICAgIG9wZW5lcik7CisgICAgdHJ5IChGaWxlSW5wdXRTdHJlYW0gaW4gPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKSB7CisgICAgICBhc3NlcnRUaGF0KHJlYWRGaWxlRnJvbVNvdXJjZShpbikpLmlzRW1wdHkoKTsKKyAgICB9CisgICAgYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBvcGVuZXIud2FpdEZvclB1bXAoKSk7CisgICAgYXNzZXJ0VGhhdChmaWxlLmV4aXN0cygpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBtdWx0aXBsZVN0cmVhbXNfc2hvdWxkQ3JlYXRlTXVsdGlwbGVGaWZvcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB1cmlUb05ld1RlbXBGaWxlKCkud2l0aFRyYW5zZm9ybShUcmFuc2Zvcm1Qcm90b3MuREVGQVVMVF9DT01QUkVTU19TUEVDKS5idWlsZCgpOworICAgIHdyaXRlRmlsZVRvU2luayhzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKSksIGJpZ0NvbnRlbnQpOworICAgIEZpbGUgcGlwZWQwID0KKyAgICAgICAgc3RvcmFnZS5vcGVuKAorICAgICAgICAgICAgdXJpLCBSZWFkRmlsZU9wZW5lci5jcmVhdGUoKS53aXRoRmFsbGJhY2tUb1BpcGVVc2luZ0V4ZWN1dG9yKGV4ZWN1dG9yLCBjb250ZXh0KSk7CisgICAgRmlsZSBwaXBlZDEgPQorICAgICAgICBzdG9yYWdlLm9wZW4oCisgICAgICAgICAgICB1cmksIFJlYWRGaWxlT3BlbmVyLmNyZWF0ZSgpLndpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoZXhlY3V0b3IsIGNvbnRleHQpKTsKKyAgICBGaWxlIHBpcGVkMiA9CisgICAgICAgIHN0b3JhZ2Uub3BlbigKKyAgICAgICAgICAgIHVyaSwgUmVhZEZpbGVPcGVuZXIuY3JlYXRlKCkud2l0aEZhbGxiYWNrVG9QaXBlVXNpbmdFeGVjdXRvcihleGVjdXRvciwgY29udGV4dCkpOworICAgIGFzc2VydFRoYXQocGlwZWQwLmdldEFic29sdXRlUGF0aCgpKS5lbmRzV2l0aCgiLTAuZmlmbyIpOworICAgIGFzc2VydFRoYXQocGlwZWQxLmdldEFic29sdXRlUGF0aCgpKS5lbmRzV2l0aCgiLTEuZmlmbyIpOworICAgIGFzc2VydFRoYXQocGlwZWQyLmdldEFic29sdXRlUGF0aCgpKS5lbmRzV2l0aCgiLTIuZmlmbyIpOworICAgIHRyeSAoRmlsZUlucHV0U3RyZWFtIGluMCA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ocGlwZWQwKTsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGluMSA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ocGlwZWQxKTsKKyAgICAgICAgRmlsZUlucHV0U3RyZWFtIGluMiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ocGlwZWQyKSkgeworICAgICAgYXNzZXJ0VGhhdChyZWFkRmlsZUZyb21Tb3VyY2UoaW4yKSkuaXNFcXVhbFRvKGJpZ0NvbnRlbnQpOworICAgICAgYXNzZXJ0VGhhdChyZWFkRmlsZUZyb21Tb3VyY2UoaW4wKSkuaXNFcXVhbFRvKGJpZ0NvbnRlbnQpOworICAgICAgYXNzZXJ0VGhhdChyZWFkRmlsZUZyb21Tb3VyY2UoaW4xKSkuaXNFcXVhbFRvKGJpZ0NvbnRlbnQpOworICAgIH0KKyAgICBhc3NlcnRUaGF0KHBpcGVkMC5leGlzdHMoKSkuaXNGYWxzZSgpOworICAgIGFzc2VydFRoYXQocGlwZWQxLmV4aXN0cygpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChwaXBlZDIuZXhpc3RzKCkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHN0YWxlRmlmb19pc0RlbGV0ZWRBbmRSZXBsYWNlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB1cmlUb05ld1RlbXBGaWxlKCkud2l0aFRyYW5zZm9ybShUcmFuc2Zvcm1Qcm90b3MuREVGQVVMVF9DT01QUkVTU19TUEVDKS5idWlsZCgpOworICAgIHdyaXRlRmlsZVRvU2luayhzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKSksIGJpZ0NvbnRlbnQpOworICAgIFJlYWRGaWxlT3BlbmVyIG9wZW5lciA9CisgICAgICAgIFJlYWRGaWxlT3BlbmVyLmNyZWF0ZSgpLndpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoZXhlY3V0b3IsIGNvbnRleHQpOworICAgIFN0cmluZyBzdGFsZUZpZm9OYW1lID0gIi5tb2JzdG9yZS1SZWFkRmlsZU9wZW5lci0iICsgUHJvY2Vzcy5teVBpZCgpICsgIi0wLmZpZm8iOworICAgIEZpbGUgc3RhbGVGaWZvID0gbmV3IEZpbGUoY29udGV4dC5nZXRDYWNoZURpcigpLCBzdGFsZUZpZm9OYW1lKTsKKyAgICBPcy5ta2ZpZm8oc3RhbGVGaWZvLmdldEFic29sdXRlUGF0aCgpLCBPc0NvbnN0YW50cy5TX0lSVVNSIHwgT3NDb25zdGFudHMuU19JV1VTUik7CisKKyAgICBGaWxlIHBpcGVkID0gc3RvcmFnZS5vcGVuKHVyaSwgb3BlbmVyKTsKKyAgICBhc3NlcnRUaGF0KHBpcGVkKS5pc0VxdWFsVG8oc3RhbGVGaWZvKTsKKyAgICB0cnkgKEZpbGVJbnB1dFN0cmVhbSBpbiA9IG5ldyBGaWxlSW5wdXRTdHJlYW0ocGlwZWQpKSB7CisgICAgICBhc3NlcnRUaGF0KHJlYWRGaWxlRnJvbVNvdXJjZShpbikpLmlzRXF1YWxUbyhiaWdDb250ZW50KTsKKyAgICB9CisgICAgYXNzZXJ0VGhhdChwaXBlZC5leGlzdHMoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2hvcnRDaXJjdWl0X3N1Y2NlZWRzV2l0aFNpbXBsZVBhdGgoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdXJpVG9OZXdUZW1wRmlsZSgpLmJ1aWxkKCk7CisgICAgd3JpdGVGaWxlVG9TaW5rKHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSwgc21hbGxDb250ZW50KTsKKyAgICBSZWFkRmlsZU9wZW5lciBvcGVuZXIgPSBSZWFkRmlsZU9wZW5lci5jcmVhdGUoKS53aXRoU2hvcnRDaXJjdWl0KCk7CisgICAgRmlsZSBmaWxlID0gc3RvcmFnZS5vcGVuKHVyaSwgb3BlbmVyKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlRnJvbVNvdXJjZShuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpKSkuaXNFcXVhbFRvKHNtYWxsQ29udGVudCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzaG9ydENpcmN1aXRfaXNSZWplY3RlZFdpdGhUcmFuc2Zvcm1zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHVyaVRvTmV3VGVtcEZpbGUoKS53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0NPTVBSRVNTX1NQRUMpLmJ1aWxkKCk7CisgICAgUmVhZEZpbGVPcGVuZXIgb3BlbmVyID0gUmVhZEZpbGVPcGVuZXIuY3JlYXRlKCkud2l0aFNob3J0Q2lyY3VpdCgpOworICAgIGFzc2VydFRocm93cyhVbnN1cHBvcnRlZEZpbGVTdG9yYWdlT3BlcmF0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLm9wZW4odXJpLCBvcGVuZXIpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHNob3J0Q2lyY3VpdF9zdWNjZWVkc1dpdGhNb25pdG9ycygpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZVdpdGhNb25pdG9yID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKG5ldyBKYXZhRmlsZUJhY2tlbmQoKSksCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKG5ldyBCeXRlQ291bnRpbmdNb25pdG9yKCkpKTsKKyAgICBVcmkgdXJpID0gdXJpVG9OZXdUZW1wRmlsZSgpLmJ1aWxkKCk7CisgICAgYnl0ZVtdIGNvbnRlbnQgPSBTdHJlYW1VdGlscy5tYWtlQXJyYXlPZkJ5dGVzQ29udGVudCgpOworICAgIFN0cmVhbVV0aWxzLmNyZWF0ZUZpbGUoc3RvcmFnZVdpdGhNb25pdG9yLCB1cmksIGNvbnRlbnQpOworCisgICAgUmVhZEZpbGVPcGVuZXIgb3BlbmVyID0gUmVhZEZpbGVPcGVuZXIuY3JlYXRlKCkud2l0aFNob3J0Q2lyY3VpdCgpOworICAgIEZpbGUgZmlsZSA9IHN0b3JhZ2VXaXRoTW9uaXRvci5vcGVuKHVyaSwgb3BlbmVyKTsKKyAgICBhc3NlcnRUaGF0KFN0cmVhbVV0aWxzLnJlYWRGaWxlSW5CeXRlc0Zyb21Tb3VyY2UobmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSkpLmlzRXF1YWxUbyhjb250ZW50KTsKKyAgfQorCisgIC8vIFRPRE8oYi82OTMxOTM1NSk6IHJlcGxhY2Ugd2l0aCBUZW1wb3JhcnlVcmkKKyAgcHJpdmF0ZSBGaWxlVXJpLkJ1aWxkZXIgdXJpVG9OZXdUZW1wRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHJldHVybiBGaWxlVXJpLmJ1aWxkZXIoKS5mcm9tRmlsZSh0bXBGb2xkZXIubmV3RmlsZSgpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9SZWFkUHJvdG9PcGVuZXJUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlYWRQcm90b09wZW5lclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kYjdjYWVmCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9SZWFkUHJvdG9PcGVuZXJUZXN0LmphdmEKQEAgLTAsMCArMSwxNTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5KYXZhRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5UZW1wb3JhcnlVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLkNvbXByZXNzVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5UcmFuc2Zvcm1Qcm90b3M7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5zdG9yYWdlLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVzdE1lc3NhZ2VQcm90by5FeHRlbmRhYmxlUHJvdG87CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5zdG9yYWdlLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVzdE1lc3NhZ2VQcm90by5FeHRlbnNpb25Qcm90bzsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLnN0b3JhZ2UuZmlsZS5jb21tb24udGVzdGluZy5UZXN0TWVzc2FnZVByb3RvLkZvb1Byb3RvOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIFJlYWRQcm90b09wZW5lclRlc3QgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZvb1Byb3RvIFRFU1RfUFJPVE8gPQorICAgICAgRm9vUHJvdG8ubmV3QnVpbGRlcigpLnNldFRleHQoImZvbyB0ZXh0Iikuc2V0Qm9vbGVhbih0cnVlKS5idWlsZCgpOworCisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworCisgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlVcmkgdG1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXBTdG9yYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgQXJyYXlzLmFzTGlzdChuZXcgSmF2YUZpbGVCYWNrZW5kKCkpLCBBcnJheXMuYXNMaXN0KG5ldyBDb21wcmVzc1RyYW5zZm9ybSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjcmVhdGVfZnJvbU1lc3NhZ2VQYXJzZXJfcmV0dXJuc09wZW5lcldpdGhDb3JyZWN0R2VuZXJpY1R5cGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlUHJvdG9PcGVuZXIuY3JlYXRlKFRFU1RfUFJPVE8pKTsKKworICAgIFJlYWRQcm90b09wZW5lcjxGb29Qcm90bz4gb3BlbmVyID0gUmVhZFByb3RvT3BlbmVyLmNyZWF0ZShGb29Qcm90by5wYXJzZXIoKSk7CisgICAgRm9vUHJvdG8gdW51c2VkVG9DaGVja0NvbXBpbGF0aW9uID0gc3RvcmFnZS5vcGVuKHVyaSwgb3BlbmVyKTsKKworICAgIC8vIEVuc3VyZSBKYXZhIGNvbXBpbGVyIGNhbiBpbmZlciB0aGUgY29ycmVjdCBnZW5lcmljIHdoZW4gT3BlbmVyIGlzIHBhc3NlZCBpbiBkaXJlY3RseQorICAgIHVudXNlZFRvQ2hlY2tDb21waWxhdGlvbiA9IHN0b3JhZ2Uub3Blbih1cmksIFJlYWRQcm90b09wZW5lci5jcmVhdGUoRm9vUHJvdG8ucGFyc2VyKCkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNyZWF0ZV9mcm9tTWVzc2FnZUluc3RhbmNlX3JldHVybnNPcGVuZXJXaXRoQ29ycmVjdEdlbmVyaWNUeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVByb3RvT3BlbmVyLmNyZWF0ZShURVNUX1BST1RPKSk7CisKKyAgICBSZWFkUHJvdG9PcGVuZXI8Rm9vUHJvdG8+IG9wZW5lciA9IFJlYWRQcm90b09wZW5lci5jcmVhdGUoVEVTVF9QUk9UTyk7CisgICAgRm9vUHJvdG8gdW51c2VkVG9DaGVja0NvbXBpbGF0aW9uID0gc3RvcmFnZS5vcGVuKHVyaSwgb3BlbmVyKTsKKworICAgIC8vIEVuc3VyZSBKYXZhIGNvbXBpbGVyIGNhbiBpbmZlciB0aGUgY29ycmVjdCBnZW5lcmljIHdoZW4gT3BlbmVyIGlzIHBhc3NlZCBpbiBkaXJlY3RseQorICAgIHVudXNlZFRvQ2hlY2tDb21waWxhdGlvbiA9IHN0b3JhZ2Uub3Blbih1cmksIFJlYWRQcm90b09wZW5lci5jcmVhdGUoVEVTVF9QUk9UTykpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3Blbl9yZWFkc0Z1bGxQcm90b0Zyb21GaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVByb3RvT3BlbmVyLmNyZWF0ZShURVNUX1BST1RPKSk7CisKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2Uub3Blbih1cmksIFJlYWRQcm90b09wZW5lci5jcmVhdGUoRm9vUHJvdG8ucGFyc2VyKCkpKSkuaXNFcXVhbFRvKFRFU1RfUFJPVE8pOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFByb3RvT3BlbmVyLmNyZWF0ZShURVNUX1BST1RPKSkpLmlzRXF1YWxUbyhURVNUX1BST1RPKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5fcmVhZHNFbXB0eVByb3RvRnJvbUZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGb29Qcm90byBlbXB0eVByb3RvID0gRm9vUHJvdG8uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVByb3RvT3BlbmVyLmNyZWF0ZShlbXB0eVByb3RvKSk7CisKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2Uub3Blbih1cmksIFJlYWRQcm90b09wZW5lci5jcmVhdGUoRm9vUHJvdG8ucGFyc2VyKCkpKSkuaXNFcXVhbFRvKGVtcHR5UHJvdG8pOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3Blbl9pbnZva2VzVHJhbnNmb3JtcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpQnVpbGRlcigpLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfQ09NUFJFU1NfU1BFQykuYnVpbGQoKTsKKyAgICBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVByb3RvT3BlbmVyLmNyZWF0ZShURVNUX1BST1RPKSk7CisKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2Uub3Blbih1cmksIFJlYWRQcm90b09wZW5lci5jcmVhdGUoRm9vUHJvdG8ucGFyc2VyKCkpKSkuaXNFcXVhbFRvKFRFU1RfUFJPVE8pOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3Blbl90aHJvd3NJT0V4Y2VwdGlvbk9uQmFkUGFyc2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlU3RyaW5nT3BlbmVyLmNyZWF0ZSgibm90IGEgcHJvdG8iKSk7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIEludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgKCkgLT4gc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFByb3RvT3BlbmVyLmNyZWF0ZShGb29Qcm90by5wYXJzZXIoKSkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHdpdGhSZWdpc3RyeV9yZWFkc0V4dGVuc2lvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgRXh0ZW5kYWJsZVByb3RvIGV4dGVuZGFibGUgPSBjcmVhdGVQcm90b1dpdGhFeHRlbnNpb24oKTsKKyAgICBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVByb3RvT3BlbmVyLmNyZWF0ZShleHRlbmRhYmxlKSk7CisKKyAgICBSZWFkUHJvdG9PcGVuZXI8RXh0ZW5kYWJsZVByb3RvPiBvcGVuZXIgPQorICAgICAgICBSZWFkUHJvdG9PcGVuZXIuY3JlYXRlKEV4dGVuZGFibGVQcm90by5wYXJzZXIoKSkKKyAgICAgICAgICAgIC53aXRoRXh0ZW5zaW9uUmVnaXN0cnkoRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmdldEdlbmVyYXRlZFJlZ2lzdHJ5KCkpOworCisgICAgRXh0ZW5kYWJsZVByb3RvIGFjdHVhbEV4dGVuZGFibGUgPSBzdG9yYWdlLm9wZW4odXJpLCBvcGVuZXIpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRXh0ZW5kYWJsZS5oYXNFeHRlbnNpb24oRXh0ZW5zaW9uUHJvdG8uZXh0ZW5zaW9uKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChhY3R1YWxFeHRlbmRhYmxlLmdldEV4dGVuc2lvbihFeHRlbnNpb25Qcm90by5leHRlbnNpb24pLmdldEZvbygpLmdldFRleHQoKSkKKyAgICAgICAgLmlzRXF1YWxUbygiZm9vIHRleHQiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHdpdGhPdXRSZWdpc3RyeV9mYWlsc1RvUmVhZHNFeHRlbnNpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIEV4dGVuZGFibGVQcm90byBleHRlbmRhYmxlID0gY3JlYXRlUHJvdG9XaXRoRXh0ZW5zaW9uKCk7CisgICAgc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVQcm90b09wZW5lci5jcmVhdGUoZXh0ZW5kYWJsZSkpOworCisgICAgUmVhZFByb3RvT3BlbmVyPEV4dGVuZGFibGVQcm90bz4gb3BlbmVyID0gUmVhZFByb3RvT3BlbmVyLmNyZWF0ZShFeHRlbmRhYmxlUHJvdG8ucGFyc2VyKCkpOworCisgICAgRXh0ZW5kYWJsZVByb3RvIGFjdHVhbEV4dGVuZGFibGUgPSBzdG9yYWdlLm9wZW4odXJpLCBvcGVuZXIpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRXh0ZW5kYWJsZS5oYXNFeHRlbnNpb24oRXh0ZW5zaW9uUHJvdG8uZXh0ZW5zaW9uKSkuaXNGYWxzZSgpOworICB9CisKKyAgcHJpdmF0ZSBFeHRlbmRhYmxlUHJvdG8gY3JlYXRlUHJvdG9XaXRoRXh0ZW5zaW9uKCkgeworICAgIEV4dGVuZGFibGVQcm90byBleHRlbmRhYmxlID0KKyAgICAgICAgRXh0ZW5kYWJsZVByb3RvLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEV4dGVuc2lvbigKKyAgICAgICAgICAgICAgICBFeHRlbnNpb25Qcm90by5leHRlbnNpb24sIEV4dGVuc2lvblByb3RvLm5ld0J1aWxkZXIoKS5zZXRGb28oVEVTVF9QUk9UTykuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHJldHVybiBleHRlbmRhYmxlOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlYWRTdHJlYW1PcGVuZXJUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlYWRTdHJlYW1PcGVuZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjk3YmU2ZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVhZFN0cmVhbU9wZW5lclRlc3QuamF2YQpAQCAtMCwwICsxLDcxIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ubW9jazsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by53aGVuOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5CYWNrZW5kOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgUmVhZFN0cmVhbU9wZW5lclRlc3QgeworCisgIHByaXZhdGUgZmluYWwgSW5wdXRTdHJlYW0gYmFja2VuZFN0cmVhbSA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShuZXcgYnl0ZVsxXSk7CisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworCisgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlVcmkgdG1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXBTdG9yYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQmFja2VuZCBtb2NrQmFja2VuZCA9IG1vY2soQmFja2VuZC5jbGFzcyk7CisgICAgd2hlbihtb2NrQmFja2VuZC5uYW1lKCkpLnRoZW5SZXR1cm4oImZpbGUiKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLm9wZW5Gb3JSZWFkKGFueSgpKSkudGhlblJldHVybihiYWNrZW5kU3RyZWFtKTsKKworICAgIHN0b3JhZ2UgPSBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZShBcnJheXMuYXNMaXN0KG1vY2tCYWNrZW5kKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuX3dpdGhvdXRUcmFuc2Zvcm1zX3JldHVybnNSYXdCYWNrZW5kU3RyZWFtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKworICAgIHRyeSAoSW5wdXRTdHJlYW0gcmVzdWx0ID0gc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIGFzc2VydFRoYXQocmVzdWx0KS5pc0VxdWFsVG8oYmFja2VuZFN0cmVhbSk7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3Blbl93aXRoQnVmZmVyZWRJb19yZXR1cm5zQnVmZmVyZWRJbnB1dFN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisKKyAgICB0cnkgKElucHV0U3RyZWFtIHJlc3VsdCA9IHN0b3JhZ2Uub3Blbih1cmksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkud2l0aEJ1ZmZlcmVkSW8oKSkpIHsKKyAgICAgIGFzc2VydFRoYXQocmVzdWx0KS5pc0luc3RhbmNlT2YoQnVmZmVyZWRJbnB1dFN0cmVhbS5jbGFzcyk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlY3Vyc2l2ZURlbGV0ZU9wZW5lclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVjdXJzaXZlRGVsZXRlT3BlbmVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmIzMTU0YzkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlY3Vyc2l2ZURlbGV0ZU9wZW5lclRlc3QuamF2YQpAQCAtMCwwICsxLDE0NiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLmRvVGhyb3c7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8uc3B5OworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkZha2VGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5CYWNrZW5kOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5MaXN0OworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5hbm5vdGF0aW9uLkNvbmZpZzsKKworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIFJlY3Vyc2l2ZURlbGV0ZU9wZW5lclRlc3QgeworCisgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlVcmkgdG1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworCisgIHByaXZhdGUgZmluYWwgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlID0KKyAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEFycmF5cy5hc0xpc3QobmV3IEphdmFGaWxlQmFja2VuZCgpKSk7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3Blbl9ub25FeGlzdGVudFVyaV90aHJvd3NFeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVyaSBkaXIgPSB0bXBVcmkubmV3RGlyZWN0b3J5VXJpKCk7CisgICAgVXJpIG1pc3NpbmcgPSBVcmkud2l0aEFwcGVuZGVkUGF0aChkaXIsICJhIik7CisgICAgYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLm9wZW4obWlzc2luZywgUmVjdXJzaXZlRGVsZXRlT3BlbmVyLmNyZWF0ZSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuX2ZpbGVfZGVsZXRlc0ZpbGUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVyaSBmaWxlID0gdG1wVXJpLm5ld1VyaSgpOworICAgIHN0b3JhZ2Uub3BlbihmaWxlLCBXcml0ZVN0cmluZ09wZW5lci5jcmVhdGUoImp1bmsiKSk7CisKKyAgICBzdG9yYWdlLm9wZW4oZmlsZSwgUmVjdXJzaXZlRGVsZXRlT3BlbmVyLmNyZWF0ZSgpKTsKKworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5leGlzdHMoZmlsZSkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5fZW1wdHlEaXJlY3RvcnlfZGVsZXRlc0RpcmVjdG9yeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgVXJpIGRpciA9IHRtcFVyaS5uZXdEaXJlY3RvcnlVcmkoKTsKKworICAgIHN0b3JhZ2Uub3BlbihkaXIsIFJlY3Vyc2l2ZURlbGV0ZU9wZW5lci5jcmVhdGUoKSk7CisKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZXhpc3RzKGRpcikpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5fbm9uRW1wdHlEaXJlY3RvcnlfZGVsZXRlc0NoaWxkcmVuVGhlbkRpcmVjdG9yeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgVXJpIGRpciA9IHRtcFVyaS5uZXdEaXJlY3RvcnlVcmkoKTsKKworICAgIC8vIFRPRE86IGNvbnNpZGVyIGFkZGluZyBGaWxlVXJpLmZyb21GaWxlVXJpIHRvIG1ha2UgdGhpcyBjbGVhbmVyCisgICAgVXJpIGZpbGUwID0gVXJpLndpdGhBcHBlbmRlZFBhdGgoZGlyLCAiYSIpOworICAgIFVyaSBmaWxlMSA9IFVyaS53aXRoQXBwZW5kZWRQYXRoKGRpciwgImIiKTsKKyAgICBzdG9yYWdlLm9wZW4oZmlsZTAsIFdyaXRlU3RyaW5nT3BlbmVyLmNyZWF0ZSgianVuayIpKTsKKyAgICBzdG9yYWdlLm9wZW4oZmlsZTEsIFdyaXRlU3RyaW5nT3BlbmVyLmNyZWF0ZSgianVuayIpKTsKKworICAgIHN0b3JhZ2Uub3BlbihkaXIsIFJlY3Vyc2l2ZURlbGV0ZU9wZW5lci5jcmVhdGUoKSk7CisKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZXhpc3RzKGZpbGUwKSkuaXNGYWxzZSgpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5leGlzdHMoZmlsZTEpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyhkaXIpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuX2RpcmVjdG9yeVRyZWVfcmVjdXJzZXNNdWx0aXBsZUxldmVscygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgVXJpIGRpciA9IHRtcFVyaS5uZXdEaXJlY3RvcnlVcmkoKTsKKworICAgIFVyaSBzdWJEaXIgPSBVcmkud2l0aEFwcGVuZGVkUGF0aChkaXIsICJzdWJEaXIiKTsKKyAgICBVcmkgc3ViU3ViRGlyID0gVXJpLndpdGhBcHBlbmRlZFBhdGgoc3ViRGlyLCAic3ViU3ViRGlyIik7CisgICAgVXJpIGVtcHR5U3ViRGlyID0gVXJpLndpdGhBcHBlbmRlZFBhdGgoZGlyLCAiZW1wdHlTdWJEaXIiKTsKKyAgICBzdG9yYWdlLmNyZWF0ZURpcmVjdG9yeShzdWJEaXIpOworICAgIHN0b3JhZ2UuY3JlYXRlRGlyZWN0b3J5KHN1YlN1YkRpcik7CisgICAgc3RvcmFnZS5jcmVhdGVEaXJlY3RvcnkoZW1wdHlTdWJEaXIpOworCisgICAgTGlzdDxVcmk+IGZpbGVVcmlzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgIT0gNTsgaSsrKSB7CisgICAgICBVcmkgdXJpID0gVXJpLndpdGhBcHBlbmRlZFBhdGgoZGlyLCBJbnRlZ2VyLnRvU3RyaW5nKGkpKTsKKyAgICAgIHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlU3RyaW5nT3BlbmVyLmNyZWF0ZShJbnRlZ2VyLnRvU3RyaW5nKGkpKSk7CisgICAgICBmaWxlVXJpcy5hZGQodXJpKTsKKyAgICB9CisKKyAgICBzdG9yYWdlLm9wZW4oZGlyLCBSZWN1cnNpdmVEZWxldGVPcGVuZXIuY3JlYXRlKCkpOworCisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyhkaXIpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyhzdWJEaXIpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyhzdWJTdWJEaXIpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyhlbXB0eVN1YkRpcikpLmlzRmFsc2UoKTsKKyAgICBmb3IgKFVyaSB1cmkgOiBmaWxlVXJpcykgeworICAgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyh1cmkpKS5pc0ZhbHNlKCk7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgQENvbmZpZyhzZGsgPSAxOSkgLy8gYWRkU3VwcHJlc3NlZCBpcyBvbmx5IGF2YWlsYWJsZSBvbiBTREsgMTkrCisgIHB1YmxpYyB2b2lkIG9wZW5fc3VwcHJlc3Nlc0V4Y2VwdGlvbnNVbnRpbEVuZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEJhY2tlbmQgc3B5QmFja2VuZCA9IHNweShuZXcgRmFrZUZpbGVCYWNrZW5kKCkpOworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEFycmF5cy5hc0xpc3Qoc3B5QmFja2VuZCkpOworCisgICAgVXJpIGRpciA9IHRtcFVyaS5uZXdEaXJlY3RvcnlVcmkoKTsKKworICAgIFVyaSBkZWxldGFibGVGaWxlMCA9IFVyaS53aXRoQXBwZW5kZWRQYXRoKGRpciwgImEiKTsKKyAgICBVcmkgdW5kZWxldGFibGVGaWxlID0gVXJpLndpdGhBcHBlbmRlZFBhdGgoZGlyLCAic3ViRGlyL2IiKTsKKyAgICBVcmkgZGVsZXRhYmxlRmlsZTEgPSBVcmkud2l0aEFwcGVuZGVkUGF0aChkaXIsICJzdWJEaXIvc3ViU3ViRGlyL2MiKTsKKyAgICBzdG9yYWdlLm9wZW4odW5kZWxldGFibGVGaWxlLCBXcml0ZVN0cmluZ09wZW5lci5jcmVhdGUoImEiKSk7CisgICAgc3RvcmFnZS5vcGVuKGRlbGV0YWJsZUZpbGUwLCBXcml0ZVN0cmluZ09wZW5lci5jcmVhdGUoImIiKSk7CisgICAgc3RvcmFnZS5vcGVuKGRlbGV0YWJsZUZpbGUxLCBXcml0ZVN0cmluZ09wZW5lci5jcmVhdGUoImMiKSk7CisKKyAgICBkb1Rocm93KElPRXhjZXB0aW9uLmNsYXNzKS53aGVuKHNweUJhY2tlbmQpLmRlbGV0ZUZpbGUodW5kZWxldGFibGVGaWxlKTsKKworICAgIElPRXhjZXB0aW9uIGV4cGVjdGVkID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLm9wZW4oZGlyLCBSZWN1cnNpdmVEZWxldGVPcGVuZXIuY3JlYXRlKCkpKTsKKworICAgIGFzc2VydFRoYXQoZXhwZWN0ZWQuZ2V0U3VwcHJlc3NlZCgpKS5oYXNMZW5ndGgoMyk7IC8vIG9uZSBmb3IgdGhlIGZpbGUsIHR3byBmb3IgdGhlIGRpcmVjdG9yaWVzCisKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZXhpc3RzKGRlbGV0YWJsZUZpbGUwKSkuaXNGYWxzZSgpOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5leGlzdHMoZGVsZXRhYmxlRmlsZTEpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmV4aXN0cyh1bmRlbGV0YWJsZUZpbGUpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuZXhpc3RzKGRpcikpLmlzVHJ1ZSgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlY3Vyc2l2ZVNpemVPcGVuZXJUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1JlY3Vyc2l2ZVNpemVPcGVuZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzU1NTFiZgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvUmVjdXJzaXZlU2l6ZU9wZW5lclRlc3QuamF2YQpAQCAtMCwwICsxLDE0MiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMuY3JlYXRlRmlsZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuRmlsZVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkR1bW15VHJhbnNmb3JtczsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuQ29tcHJlc3NUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLlRyYW5zZm9ybVByb3RvczsKK2ltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBSZWN1cnNpdmVTaXplT3BlbmVyVGVzdCB7CisKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeVVyaSB0bXBVcmkgPSBuZXcgVGVtcG9yYXJ5VXJpKCk7CisKKyAgcHJpdmF0ZSBmaW5hbCBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPQorICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgQXJyYXlzLmFzTGlzdChuZXcgSmF2YUZpbGVCYWNrZW5kKCkpLAorICAgICAgICAgIEFycmF5cy5hc0xpc3QobmV3IENvbXByZXNzVHJhbnNmb3JtKCksIER1bW15VHJhbnNmb3Jtcy5DQVBfRklMRU5BTUVfVFJBTlNGT1JNKSk7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3Blbl9ub25FeGlzdGVudFVyaV90aHJvd3NGaWxlTm90Rm91bmRFeGNlcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVyaSBtaXNzaW5nID0gdG1wVXJpLm5ld1VyaSgpOworICAgIGFzc2VydFRocm93cygKKyAgICAgICAgRmlsZU5vdEZvdW5kRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLm9wZW4obWlzc2luZywgUmVjdXJzaXZlU2l6ZU9wZW5lci5jcmVhdGUoKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3Blbl9maWxlX3Rocm93c0ZpbGVOb3RGb3VuZEV4Y2VwdGlvbigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgVXJpIGZpbGUgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCBmaWxlLCAiMTIzNDUiKTsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIEZpbGVOb3RGb3VuZEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc3RvcmFnZS5vcGVuKGZpbGUsIFJlY3Vyc2l2ZVNpemVPcGVuZXIuY3JlYXRlKCkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG9wZW5fZW1wdHlEaXJlY3RvcnlfcmV0dXJuczAoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVyaSBkaXIgPSB0bXBVcmkubmV3RGlyZWN0b3J5VXJpKCk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLm9wZW4oZGlyLCBSZWN1cnNpdmVTaXplT3BlbmVyLmNyZWF0ZSgpKSkuaXNFcXVhbFRvKDApOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3Blbl9ub25FbXB0eURpcmVjdG9yeV9yZXR1cm5zU2l6ZU9mQ2hpbGRyZW5GaWxlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgVXJpIGRpciA9IHRtcFVyaS5uZXdEaXJlY3RvcnlVcmkoKTsKKworICAgIC8vIFRPRE86IGNvbnNpZGVyIGFkZGluZyBGaWxlVXJpLmZyb21GaWxlVXJpIHRvIG1ha2UgdGhpcyBjbGVhbmVyCisgICAgY3JlYXRlRmlsZSgKKyAgICAgICAgc3RvcmFnZSwgRmlsZVVyaS5idWlsZGVyKCkuc2V0UGF0aChkaXIuZ2V0UGF0aCgpKS5hcHBlbmRQYXRoKCJmaWxlMCIpLmJ1aWxkKCksICIxMjM0NSIpOworICAgIGNyZWF0ZUZpbGUoCisgICAgICAgIHN0b3JhZ2UsIEZpbGVVcmkuYnVpbGRlcigpLnNldFBhdGgoZGlyLmdldFBhdGgoKSkuYXBwZW5kUGF0aCgiZmlsZTEiKS5idWlsZCgpLCAiNjc4Iik7CisKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2Uub3BlbihkaXIsIFJlY3Vyc2l2ZVNpemVPcGVuZXIuY3JlYXRlKCkpKS5pc0VxdWFsVG8oOCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuX2RpcmVjdG9yeVRyZWVfcmVjdXJzZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVyaSBkaXIgPSB0bXBVcmkubmV3RGlyZWN0b3J5VXJpKCk7CisgICAgVXJpIHN1YkRpciA9IEZpbGVVcmkuYnVpbGRlcigpLnNldFBhdGgoZGlyLmdldFBhdGgoKSkuYXBwZW5kUGF0aCgic3ViRGlyIikuYnVpbGQoKTsKKyAgICBVcmkgc3ViU3ViRGlyID0gRmlsZVVyaS5idWlsZGVyKCkuc2V0UGF0aChzdWJEaXIuZ2V0UGF0aCgpKS5hcHBlbmRQYXRoKCJzdWJTdWJEaXIiKS5idWlsZCgpOworICAgIFVyaSBlbXB0eVN1YkRpciA9IEZpbGVVcmkuYnVpbGRlcigpLnNldFBhdGgoZGlyLmdldFBhdGgoKSkuYXBwZW5kUGF0aCgiZW1wdHlTdWJEaXIiKS5idWlsZCgpOworCisgICAgLy8gVE9ETzogY29uc2lkZXIgYWRkaW5nIEZpbGVVcmkuZnJvbUZpbGVVcmkgdG8gbWFrZSB0aGlzIGNsZWFuZXIKKyAgICBzdG9yYWdlLmNyZWF0ZURpcmVjdG9yeShzdWJEaXIpOworICAgIHN0b3JhZ2UuY3JlYXRlRGlyZWN0b3J5KHN1YlN1YkRpcik7CisgICAgc3RvcmFnZS5jcmVhdGVEaXJlY3RvcnkoZW1wdHlTdWJEaXIpOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgRmlsZVVyaS5idWlsZGVyKCkuc2V0UGF0aChkaXIuZ2V0UGF0aCgpKS5hcHBlbmRQYXRoKCJhIikuYnVpbGQoKSwgIjEiKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIEZpbGVVcmkuYnVpbGRlcigpLnNldFBhdGgoZGlyLmdldFBhdGgoKSkuYXBwZW5kUGF0aCgiYiIpLmJ1aWxkKCksICIyIik7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCBGaWxlVXJpLmJ1aWxkZXIoKS5zZXRQYXRoKHN1YkRpci5nZXRQYXRoKCkpLmFwcGVuZFBhdGgoImMiKS5idWlsZCgpLCAiMyIpOworICAgIGNyZWF0ZUZpbGUoCisgICAgICAgIHN0b3JhZ2UsIEZpbGVVcmkuYnVpbGRlcigpLnNldFBhdGgoc3ViU3ViRGlyLmdldFBhdGgoKSkuYXBwZW5kUGF0aCgiZCIpLmJ1aWxkKCksICI0NSIpOworICAgIGNyZWF0ZUZpbGUoCisgICAgICAgIHN0b3JhZ2UsIEZpbGVVcmkuYnVpbGRlcigpLnNldFBhdGgoc3ViU3ViRGlyLmdldFBhdGgoKSkuYXBwZW5kUGF0aCgiZSIpLmJ1aWxkKCksICI2NyIpOworCisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLm9wZW4oZGlyLCBSZWN1cnNpdmVTaXplT3BlbmVyLmNyZWF0ZSgpKSkuaXNFcXVhbFRvKDcpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3Blbl9jYW5GaW5kQ2hpbGRSZWdhcmRsZXNzT2ZGaWxlbmFtZUVuY29kaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBVcmkgZGlyID0gdG1wVXJpLm5ld0RpcmVjdG9yeVVyaSgpOworICAgIFVyaSBkaXJXaXRoVHJhbnNmb3JtID0KKyAgICAgICAgRmlsZVVyaS5idWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRQYXRoKGRpci5nZXRQYXRoKCkpCisgICAgICAgICAgICAuYnVpbGQoKQorICAgICAgICAgICAgLmJ1aWxkVXBvbigpCisgICAgICAgICAgICAuZW5jb2RlZEZyYWdtZW50KCJ0cmFuc2Zvcm09Y2FwIikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFVyaSBjaGlsZFdpdGhUcmFuc2Zvcm0gPQorICAgICAgICBGaWxlVXJpLmJ1aWxkZXIoKQorICAgICAgICAgICAgLnNldFBhdGgoZGlyLmdldFBhdGgoKSkKKyAgICAgICAgICAgIC5hcHBlbmRQYXRoKCJ0aGlzLXdpbGwtYmUtYWxsLWNhcHMtb24tZGlzayIpCisgICAgICAgICAgICAuYnVpbGQoKQorICAgICAgICAgICAgLmJ1aWxkVXBvbigpCisgICAgICAgICAgICAuZW5jb2RlZEZyYWdtZW50KCJ0cmFuc2Zvcm09Y2FwIikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgY2hpbGRXaXRoVHJhbnNmb3JtLCAiMTIzNDUiKTsKKworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5vcGVuKGRpciwgUmVjdXJzaXZlU2l6ZU9wZW5lci5jcmVhdGUoKSkpLmlzRXF1YWxUbyg1KTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2Uub3BlbihkaXJXaXRoVHJhbnNmb3JtLCBSZWN1cnNpdmVTaXplT3BlbmVyLmNyZWF0ZSgpKSkuaXNFcXVhbFRvKDUpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3Blbl9yZXR1cm5zT25EaXNrU2l6ZU5vdExvZ2ljYWxUcmFuc2Zvcm1lZFNpemUoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIFVyaSBkaXIgPSB0bXBVcmkubmV3RGlyZWN0b3J5VXJpKCk7CisgICAgVXJpIGNoaWxkID0KKyAgICAgICAgRmlsZVVyaS5idWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRQYXRoKGRpci5nZXRQYXRoKCkpCisgICAgICAgICAgICAuYXBwZW5kUGF0aCgiZmlsZW5hbWUiKQorICAgICAgICAgICAgLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfQ09NUFJFU1NfU1BFQykKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFN0cmluZyBjb250ZW50ID0gInRoaXMgY29udGVudCBzaG91bGQgbm90IGJlIGRlY29tcHJlc3NlZCB3aGVuIGNhbGN1bGF0aW5nIG9uLWRpc2sgc2l6ZSI7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCBjaGlsZCwgY29udGVudCk7CisKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2Uub3BlbihkaXIsIFJlY3Vyc2l2ZVNpemVPcGVuZXIuY3JlYXRlKCkpKS5pc0xlc3NUaGFuKChsb25nKSBjb250ZW50Lmxlbmd0aCgpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TdHJlYW1NdXRhdGlvbk9wZW5lckFuZHJvaWRNYW5pZmVzdC54bWwgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1N0cmVhbU11dGF0aW9uT3BlbmVyQW5kcm9pZE1hbmlmZXN0LnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yODBmYzMzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TdHJlYW1NdXRhdGlvbk9wZW5lckFuZHJvaWRNYW5pZmVzdC54bWwKQEAgLTAsMCArMSwzMyBAQAorPCEtLQorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KKy0tPgorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KKzxtYW5pZmVzdCB4bWxuczphbmRyb2lkPSJodHRwOi8vc2NoZW1hcy5hbmRyb2lkLmNvbS9hcGsvcmVzL2FuZHJvaWQiCisgIHBhY2thZ2U9ImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycyI+CisgICAgPHVzZXMtc2RrCisgICAgICAgICAgICBhbmRyb2lkOm1pblNka1ZlcnNpb249IjE1IgorICAgICAgICAgICAgYW5kcm9pZDp0YXJnZXRTZGtWZXJzaW9uPSIyMyIvPgorICAgIDxhcHBsaWNhdGlvbj4KKyAgICAgICAgPHVzZXMtbGlicmFyeSBhbmRyb2lkOm5hbWU9ImFuZHJvaWQudGVzdC5ydW5uZXIiIC8+CisgICAgICAgIDxzZXJ2aWNlIGFuZHJvaWQ6ZW5hYmxlZD0idHJ1ZSIgYW5kcm9pZDpleHBvcnRlZD0iZmFsc2UiCisgICAgICAgICAgYW5kcm9pZDpwcm9jZXNzPSI6VGVzdEhlbHBlciIKKyAgICAgICAgICBhbmRyb2lkOm5hbWU9Ii5TdHJlYW1NdXRhdGlvbk9wZW5lckFuZHJvaWRUZXN0JFRlc3RIZWxwZXIiIC8+CisgICAgPC9hcHBsaWNhdGlvbj4KKyAgICA8aW5zdHJ1bWVudGF0aW9uCisgICAgICAgIGFuZHJvaWQ6bmFtZT0iY29tLmdvb2dsZS5hbmRyb2lkLmFwcHMuY29tbW9uLnRlc3RpbmcudGVzdHJ1bm5lci5Hb29nbGUzSW5zdHJ1bWVudGF0aW9uVGVzdFJ1bm5lciIKKyAgICAgICAgYW5kcm9pZDp0YXJnZXRQYWNrYWdlPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMiIC8+Cis8L21hbmlmZXN0PgpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TdHJlYW1NdXRhdGlvbk9wZW5lckFuZHJvaWRUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1N0cmVhbU11dGF0aW9uT3BlbmVyQW5kcm9pZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iY2ViMGRkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TdHJlYW1NdXRhdGlvbk9wZW5lckFuZHJvaWRUZXN0LmphdmEKQEAgLTAsMCArMSwzMDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLmNyZWF0ZUZpbGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMucmVhZEZpbGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0cy5VVEZfODsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLmFwcC5BY3Rpdml0eTsKK2ltcG9ydCBhbmRyb2lkLmFwcC5TZXJ2aWNlOworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Ccm9hZGNhc3RSZWNlaXZlcjsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuSW50ZW50OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5JbnRlbnRGaWx0ZXI7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuQmluZGVyOworaW1wb3J0IGFuZHJvaWQub3MuSUJpbmRlcjsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LnJ1bGUuU2VydmljZVRlc3RSdWxlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLkFzY2lpOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5CeXRlU3RyZWFtczsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bGVzLlRlc3ROYW1lOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVycy5KVW5pdDQ7CisKK0BSdW5XaXRoKEpVbml0NC5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJlYW1NdXRhdGlvbk9wZW5lckFuZHJvaWRUZXN0IHsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJUZXN0U3RyZWFtTXV0YXRpb25PcGVuZXJBbmRyb2lkIjsKKworICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeVVyaSB0bXBVcmkgPSBuZXcgVGVtcG9yYXJ5VXJpKCk7CisgIEBSdWxlIHB1YmxpYyBmaW5hbCBTZXJ2aWNlVGVzdFJ1bGUgc2VydmljZVJ1bGUgPSBuZXcgU2VydmljZVRlc3RSdWxlKCk7CisgIEBSdWxlIHB1YmxpYyBUZXN0TmFtZSB0ZXN0TmFtZSA9IG5ldyBUZXN0TmFtZSgpOworCisgIHB1YmxpYyBzdGF0aWMgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlKCkgeworICAgIHJldHVybiBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZShJbW11dGFibGVMaXN0Lm9mKG5ldyBKYXZhRmlsZUJhY2tlbmQoKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW50ZXJsZWF2ZU11dGF0aW9uc193aXRob3V0TG9ja2luZ19sYWNrc0lzb2xhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIHNlcnZpY2VSdWxlLnN0YXJ0U2VydmljZShuZXcgSW50ZW50KGNvbnRleHQsIFRlc3RIZWxwZXIuY2xhc3MpKTsKKworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IHN0b3JhZ2UoKTsKKyAgICBVcmkgZGlyVXJpID0gdG1wVXJpLm5ld0RpcmVjdG9yeVVyaSgpOworICAgIFVyaSB1cmkgPSBkaXJVcmkuYnVpbGRVcG9uKCkuYXBwZW5kUGF0aCgidGVzdGZpbGUiKS5idWlsZCgpOworCisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksICJjb250ZW50Iik7CisgICAgc2VuZFRvSGVscGVyKHVyaSk7CisKKyAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9IHN0b3JhZ2Uub3Blbih1cmksIFN0cmVhbU11dGF0aW9uT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgbXV0YXRvci5tdXRhdGUoCisgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICBhc3NlcnRUaGF0KHJlYWRGaWxlKHN0b3JhZ2UsIHVyaSkpLmlzRXF1YWxUbygiY29udGVudCIpOworCisgICAgICAgICAgICBTdHJpbmcgcmVhZCA9IG5ldyBTdHJpbmcoQnl0ZVN0cmVhbXMudG9CeXRlQXJyYXkoaW4pLCBVVEZfOCk7CisgICAgICAgICAgICBTdHJpbmcgd3JpdGUgPSBBc2NpaS50b1VwcGVyQ2FzZShyZWFkKTsKKyAgICAgICAgICAgIGFzc2VydFRoYXQod3JpdGUpLmlzRXF1YWxUbygiQ09OVEVOVCIpOworCisgICAgICAgICAgICBzZW5kVG9IZWxwZXIodXJpKTsKKworICAgICAgICAgICAgYXNzZXJ0VGhhdChyZWFkRmlsZShzdG9yYWdlLCB1cmkpKS5pc0VxdWFsVG8oInRuZXRub2MiKTsKKworICAgICAgICAgICAgb3V0LndyaXRlKHdyaXRlLmdldEJ5dGVzKFVURl84KSk7CisgICAgICAgICAgICAvLyBUaGlzIHdyaXRlIGhhc24ndCBjbG9zZWQsIHNvIHRoZSBkZXN0aW5hdGlvbiBmaWxlIGlzIHVuY2hhbmdlZC4gVGhpcyBtdXRhdGlvbiBpc24ndAorICAgICAgICAgICAgLy8gYXBwbGllZCB0byB0aGUgcmVzdWx0IG9mIHRoZSBmaXJzdCBvbmUgYW5kIGl0IHdpbGwgb3ZlcndyaXRlIGl0LgorICAgICAgICAgICAgYXNzZXJ0VGhhdChyZWFkRmlsZShzdG9yYWdlLCB1cmkpKS5pc0VxdWFsVG8oInRuZXRub2MiKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgIH0pOworICAgIH0KKworICAgIFN0cmluZyBhY3R1YWwgPSByZWFkRmlsZShzdG9yYWdlLCB1cmkpOworICAgIGFzc2VydFRoYXQoYWN0dWFsKS5pc0VxdWFsVG8oIkNPTlRFTlQiKTsgLy8gT25seSB0aGUgc2Vjb25kIG11dGF0aW9uIGlzIGFwcGxpZWQuCisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmNoaWxkcmVuKGRpclVyaSkpLmhhc1NpemUoMSk7CisgIH0KKworICAvKiogSGVscGVyIGZvciBpbnRlcmxlYXZlTXV0YXRpb25zX3dpdGhvdXRMb2NraW5nX2xhY2tzSXNvbGF0aW9uLiAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBJbnRlcmxlYXZlTXV0YXRpb25zV2l0aG91dExvY2tpbmdMYWNrc0lzb2xhdGlvbkJyb2FkY2FzdFJlY2VpdmVyCisgICAgICBleHRlbmRzIFRlc3RpbmdCcm9hZGNhc3RSZWNlaXZlciB7CisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgcnVuKCkgeworICAgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlID0gc3RvcmFnZSgpOworCisgICAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9CisgICAgICAgICAgc3RvcmFnZS5vcGVuKHVyaSwgU3RyZWFtTXV0YXRpb25PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICAgIG11dGF0b3IubXV0YXRlKAorICAgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICAgIFN0cmluZyByZWFkID0gbmV3IFN0cmluZyhCeXRlU3RyZWFtcy50b0J5dGVBcnJheShpbiksIFVURl84KTsKKyAgICAgICAgICAgICAgZG9uZS5zaWduYWwoKTsKKyAgICAgICAgICAgICAgcmVzdW1lLmF3YWl0KCk7CisgICAgICAgICAgICAgIG91dC53cml0ZShuZXcgU3RyaW5nQnVpbGRlcihyZWFkKS5yZXZlcnNlKCkudG9TdHJpbmcoKS5nZXRCeXRlcyhVVEZfOCkpOworICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgIH0pOworICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgIExvZy5lKFRBRywgImZhaWxlZCIsIGV4KTsKKyAgICAgICAgc2V0UmVzdWx0Q29kZShBY3Rpdml0eS5SRVNVTFRfQ0FOQ0VMRUQpOworICAgICAgfQorICAgICAgZG9uZS5zaWduYWwoKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbnRlcmxlYXZlTXV0YXRpb25zX3dpdGhMb2NraW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc2VydmljZVJ1bGUuc3RhcnRTZXJ2aWNlKG5ldyBJbnRlbnQoY29udGV4dCwgVGVzdEhlbHBlci5jbGFzcykpOworCisgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlID0gc3RvcmFnZSgpOworICAgIFVyaSBkaXJVcmkgPSB0bXBVcmkubmV3RGlyZWN0b3J5VXJpKCk7CisgICAgVXJpIHVyaSA9IGRpclVyaS5idWlsZFVwb24oKS5hcHBlbmRQYXRoKCJ0ZXN0ZmlsZSIpLmJ1aWxkKCk7CisKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgImNvbnRlbnQiKTsKKyAgICBzZW5kVG9IZWxwZXIodXJpKTsKKworICAgIC8vIEF0IGZpcnN0IHdlIGZhaWwgdG8gYWNxdWlyZSB0aGUgbG9jay4KKyAgICBMb2NrRmlsZU9wZW5lciBub25CbG9ja2luZ0xvY2tpbmcgPSBMb2NrRmlsZU9wZW5lci5jcmVhdGVFeGNsdXNpdmUoKS5ub25CbG9ja2luZyh0cnVlKTsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElPRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAoKSAtPiBzdG9yYWdlLm9wZW4odXJpLCBTdHJlYW1NdXRhdGlvbk9wZW5lci5jcmVhdGUoKS53aXRoTG9ja2luZyhub25CbG9ja2luZ0xvY2tpbmcpKSk7CisKKyAgICAvLyBQZWVrIGF0IHRoZSBmaWxlLCBpZ25vcmluZyBhZHZpc29yeSBsb2Nrcy4KKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlKHN0b3JhZ2UsIHVyaSkpLmlzRXF1YWxUbygiY29udGVudCIpOworCisgICAgc2VuZFRvSGVscGVyKHVyaSk7CisKKyAgICAvLyBOb3cgdGhlIGxvY2sgc2hvdWxkIGJlIGZyZWUgYW5kIHdlIGNhbiBwcm9jZWVkIHNhZmVseS4KKyAgICBMb2NrRmlsZU9wZW5lciBibG9ja2luZ0xvY2tpbmcgPSBMb2NrRmlsZU9wZW5lci5jcmVhdGVFeGNsdXNpdmUoKS5ub25CbG9ja2luZyh0cnVlKTsKKyAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9CisgICAgICAgIHN0b3JhZ2Uub3Blbih1cmksIFN0cmVhbU11dGF0aW9uT3BlbmVyLmNyZWF0ZSgpLndpdGhMb2NraW5nKGJsb2NraW5nTG9ja2luZykpKSB7CisgICAgICBtdXRhdG9yLm11dGF0ZSgKKyAgICAgICAgICAoSW5wdXRTdHJlYW0gaW4sIE91dHB1dFN0cmVhbSBvdXQpIC0+IHsKKyAgICAgICAgICAgIFN0cmluZyByZWFkID0gbmV3IFN0cmluZyhCeXRlU3RyZWFtcy50b0J5dGVBcnJheShpbiksIFVURl84KTsKKyAgICAgICAgICAgIGFzc2VydFRoYXQocmVhZCkuaXNFcXVhbFRvKCJ0bmV0bm9jIik7CisgICAgICAgICAgICBTdHJpbmcgd3JpdGUgPSBBc2NpaS50b1VwcGVyQ2FzZShyZWFkKTsKKyAgICAgICAgICAgIG91dC53cml0ZSh3cml0ZS5nZXRCeXRlcyhVVEZfOCkpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgfSk7CisgICAgfQorICAgIFN0cmluZyBhY3R1YWwgPSByZWFkRmlsZShzdG9yYWdlLCB1cmkpOworICAgIGFzc2VydFRoYXQoYWN0dWFsKS5pc0VxdWFsVG8oIlRORVROT0MiKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuY2hpbGRyZW4oZGlyVXJpKSkuaGFzU2l6ZSgyKTsgLy8gZGF0YSBmaWxlICsgbG9jayBmaWxlCisgIH0KKworICAvKiogSGVscGVyIGZvciBpbnRlcmxlYXZlTXV0YXRpb25zX3dpdGhMb2NraW5nLiAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBJbnRlcmxlYXZlTXV0YXRpb25zV2l0aExvY2tpbmdCcm9hZGNhc3RSZWNlaXZlcgorICAgICAgZXh0ZW5kcyBUZXN0aW5nQnJvYWRjYXN0UmVjZWl2ZXIgeworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IHN0b3JhZ2UoKTsKKyAgICAgIHRyeSB7CisgICAgICAgIExvY2tGaWxlT3BlbmVyIGxvY2tpbmcgPSBMb2NrRmlsZU9wZW5lci5jcmVhdGVFeGNsdXNpdmUoKTsKKyAgICAgICAgdHJ5IChTdHJlYW1NdXRhdGlvbk9wZW5lci5NdXRhdG9yIG11dGF0b3IgPQorICAgICAgICAgICAgc3RvcmFnZS5vcGVuKHVyaSwgU3RyZWFtTXV0YXRpb25PcGVuZXIuY3JlYXRlKCkud2l0aExvY2tpbmcobG9ja2luZykpKSB7CisgICAgICAgICAgbXV0YXRvci5tdXRhdGUoCisgICAgICAgICAgICAgIChJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIG91dCkgLT4geworICAgICAgICAgICAgICAgIFN0cmluZyByZWFkID0gbmV3IFN0cmluZyhCeXRlU3RyZWFtcy50b0J5dGVBcnJheShpbiksIFVURl84KTsKKyAgICAgICAgICAgICAgICBkb25lLnNpZ25hbCgpOworICAgICAgICAgICAgICAgIHJlc3VtZS5hd2FpdCgpOworICAgICAgICAgICAgICAgIG91dC53cml0ZShuZXcgU3RyaW5nQnVpbGRlcihyZWFkKS5yZXZlcnNlKCkudG9TdHJpbmcoKS5nZXRCeXRlcyhVVEZfOCkpOworICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICB9KTsKKyAgICAgICAgfQorICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7CisgICAgICAgIExvZy5lKFRBRywgImZhaWxlZCIsIGV4KTsKKyAgICAgICAgc2V0UmVzdWx0Q29kZShBY3Rpdml0eS5SRVNVTFRfQ0FOQ0VMRUQpOworICAgICAgfQorICAgICAgZG9uZS5zaWduYWwoKTsKKyAgICB9CisgIH0KKworICAvLyBUZXN0aW5nIGluZnJhc3RydWN0dXJlIGZyb20gaGVyZSBkb3duLgorICAvLyBUT0RPKGIvMTIwODU5MTk4KTogUmVmYWN0b3IgaW50byBzaGFyZWQgY29kZS4KKyAgcHJpdmF0ZSBhYnN0cmFjdCBzdGF0aWMgY2xhc3MgVGVzdGluZ0Jyb2FkY2FzdFJlY2VpdmVyIGV4dGVuZHMgQnJvYWRjYXN0UmVjZWl2ZXIKKyAgICAgIGltcGxlbWVudHMgUnVubmFibGUgeworICAgIHByb3RlY3RlZCBmaW5hbCBMYXRjaCByZXN1bWUgPSBuZXcgTGF0Y2goKTsKKyAgICBwcm90ZWN0ZWQgZmluYWwgTGF0Y2ggZG9uZSA9IG5ldyBMYXRjaCgpOworICAgIHByb3RlY3RlZCBVcmkgdXJpOworICAgIHByaXZhdGUgVGhyZWFkIHRocmVhZCA9IG51bGw7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBvblJlY2VpdmUoQ29udGV4dCBjb250ZXh0LCBJbnRlbnQgaW50ZW50KSB7CisgICAgICBzZXRSZXN1bHRDb2RlKEFjdGl2aXR5LlJFU1VMVF9PSyk7CisgICAgICB1cmkgPSBVcmkucGFyc2UoaW50ZW50LmdldEV4dHJhcygpLmdldFN0cmluZygidXJpIikpOworICAgICAgaWYgKHRocmVhZCA9PSBudWxsKSB7CisgICAgICAgIHRocmVhZCA9IG5ldyBUaHJlYWQodGhpcyk7CisgICAgICAgIHRocmVhZC5zdGFydCgpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgcmVzdW1lLnNpZ25hbCgpOworICAgICAgfQorICAgICAgZG9uZS5hd2FpdCgpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIHJ1bigpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBjbGFzcyBUZXN0SGVscGVyIGV4dGVuZHMgU2VydmljZSB7CisgICAgcHJpdmF0ZSBmaW5hbCBCcm9hZGNhc3RSZWNlaXZlciB3aXRob3V0TG9ja2luZyA9CisgICAgICAgIG5ldyBJbnRlcmxlYXZlTXV0YXRpb25zV2l0aG91dExvY2tpbmdMYWNrc0lzb2xhdGlvbkJyb2FkY2FzdFJlY2VpdmVyKCk7CisgICAgcHJpdmF0ZSBmaW5hbCBCcm9hZGNhc3RSZWNlaXZlciB3aXRoTG9ja2luZyA9CisgICAgICAgIG5ldyBJbnRlcmxlYXZlTXV0YXRpb25zV2l0aExvY2tpbmdCcm9hZGNhc3RSZWNlaXZlcigpOworICAgIHByaXZhdGUgZmluYWwgSUJpbmRlciBkdW1teUJpbmRlciA9IG5ldyBCaW5kZXIoKSB7fTsKKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyBJQmluZGVyIG9uQmluZChJbnRlbnQgaW50ZW50KSB7CisgICAgICByZXR1cm4gZHVtbXlCaW5kZXI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgb25DcmVhdGUoKSB7CisgICAgICByZWdpc3RlclJlY2VpdmVyKAorICAgICAgICAgIHdpdGhvdXRMb2NraW5nLCBuZXcgSW50ZW50RmlsdGVyKCJpbnRlcmxlYXZlTXV0YXRpb25zX3dpdGhvdXRMb2NraW5nX2xhY2tzSXNvbGF0aW9uIikpOworICAgICAgcmVnaXN0ZXJSZWNlaXZlcih3aXRoTG9ja2luZywgbmV3IEludGVudEZpbHRlcigiaW50ZXJsZWF2ZU11dGF0aW9uc193aXRoTG9ja2luZyIpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBvbkRlc3Ryb3koKSB7CisgICAgICB1bnJlZ2lzdGVyUmVjZWl2ZXIod2l0aG91dExvY2tpbmcpOworICAgICAgdW5yZWdpc3RlclJlY2VpdmVyKHdpdGhMb2NraW5nKTsKKyAgICB9CisgIH0KKworICAvKiogQSBicm9hZGNhc3QgcmVjZWl2ZXIgdGhhdCBhbGxvd3MgY2FsbGVyIHRvIHdhaXQgdW50aWwgaXQgcmVjZWl2ZXMgYW4gaW50ZW50LiAqLworICBwcml2YXRlIHN0YXRpYyBjbGFzcyBOb3RpZnlpbmdCcm9hZGNhc3RSZWNlaXZlciBleHRlbmRzIEJyb2FkY2FzdFJlY2VpdmVyIHsKKyAgICBwcml2YXRlIGZpbmFsIExhdGNoIHJlY2VpdmVkID0gbmV3IExhdGNoKCk7CisgICAgcHJpdmF0ZSBib29sZWFuIHN1Y2Nlc3MgPSB0cnVlOworCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgb25SZWNlaXZlKENvbnRleHQgY29udGV4dCwgSW50ZW50IGludGVudCkgeworICAgICAgc3VjY2VzcyA9IChnZXRSZXN1bHRDb2RlKCkgPT0gQWN0aXZpdHkuUkVTVUxUX09LKTsKKyAgICAgIHJlY2VpdmVkLnNpZ25hbCgpOworICAgIH0KKworICAgIHB1YmxpYyB2b2lkIGF3YWl0RGVsaXZlcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAgIHJlY2VpdmVkLmF3YWl0KCk7CisgICAgICBpZiAoIXN1Y2Nlc3MpIHsKKyAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiYnJvYWRjYXN0IGhhbmRsZXIgZmFpbGVkIik7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqIEEgc2ltcGxlIGxhdGNoIHRoYXQgcmVzZXRzIGl0c2VsZiBhZnRlciBhd2FpdC4gKi8KKyAgcHJpdmF0ZSBzdGF0aWMgY2xhc3MgTGF0Y2ggeworICAgIGJvb2xlYW4gc2lnbmFsZWQgPSBmYWxzZTsKKworICAgIHN5bmNocm9uaXplZCB2b2lkIHNpZ25hbCgpIHsKKyAgICAgIHNpZ25hbGVkID0gdHJ1ZTsKKyAgICAgIG5vdGlmeSgpOworICAgIH0KKworICAgIHN5bmNocm9uaXplZCB2b2lkIGF3YWl0KCkgeworICAgICAgd2hpbGUgKCFzaWduYWxlZCkgeworICAgICAgICB0cnkgeworICAgICAgICAgIHdhaXQoKTsKKyAgICAgICAgfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAvLyBJZ25vcmUuCisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHNpZ25hbGVkID0gZmFsc2U7CisgICAgfQorICB9CisKKyAgLyoqIFNlbmRzIHBhcmFtcyB0byBoZWxwZXIgYW5kIHdhaXQgZm9yIGl0IHRvIGZpbmlzaCBwcm9jZXNzaW5nIHRoZW0uICovCisgIHByaXZhdGUgdm9pZCBzZW5kVG9IZWxwZXIoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBJbnRlbnQgaW50ZW50ID0gbmV3IEludGVudCh0ZXN0TmFtZS5nZXRNZXRob2ROYW1lKCkpOworICAgIGludGVudC5wdXRFeHRyYSgidXJpIiwgdXJpLnRvU3RyaW5nKCkpOworICAgIE5vdGlmeWluZ0Jyb2FkY2FzdFJlY2VpdmVyIHJlY2VpdmVyID0gbmV3IE5vdGlmeWluZ0Jyb2FkY2FzdFJlY2VpdmVyKCk7CisgICAgY29udGV4dC5zZW5kT3JkZXJlZEJyb2FkY2FzdCgKKyAgICAgICAgaW50ZW50LCBudWxsLCByZWNlaXZlciwgbnVsbCwgQWN0aXZpdHkuUkVTVUxUX0ZJUlNUX1VTRVIsIG51bGwsIG51bGwpOworICAgIHRyeSB7CisgICAgICByZWNlaXZlci5hd2FpdERlbGl2ZXJ5KCk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgIHRocm93IGV4OworICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgeworICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKGV4KTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvU3RyZWFtTXV0YXRpb25PcGVuZXJUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1N0cmVhbU11dGF0aW9uT3BlbmVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc5OTJiNzcKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1N0cmVhbU11dGF0aW9uT3BlbmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsNDM3IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5jcmVhdGVGaWxlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHMuVVRGXzg7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJlaGF2aW9ycy5TeW5jaW5nQmVoYXZpb3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5UZW1wb3JhcnlVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5Xcml0ZXNUaHJvd1RyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuQ29tcHJlc3NUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLlRyYW5zZm9ybVByb3RvRnJhZ21lbnRzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuQXNjaWk7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uaW8uQnl0ZVN0cmVhbXM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuVHJhbnNmb3JtUHJvdG87CitpbXBvcnQgamF2YS5pby5EYXRhSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvdW50RG93bkxhdGNoOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Nb2NraXRvOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBTdHJlYW1NdXRhdGlvbk9wZW5lclRlc3QgeworCisgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlVcmkgdG1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworCisgIHB1YmxpYyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2VXaXRoVHJhbnNmb3JtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICBBcnJheXMuYXNMaXN0KG5ldyBKYXZhRmlsZUJhY2tlbmQoKSksCisgICAgICAgIEFycmF5cy5hc0xpc3QobmV3IENvbXByZXNzVHJhbnNmb3JtKCksIG5ldyBXcml0ZXNUaHJvd1RyYW5zZm9ybSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBva0lmRmlsZURvZXNOb3RFeGlzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IHN0b3JhZ2VXaXRoVHJhbnNmb3JtKCk7CisgICAgVXJpIGRpclVyaSA9IHRtcFVyaS5uZXdEaXJlY3RvcnlVcmkoKTsKKyAgICBVcmkgdXJpID0gZGlyVXJpLmJ1aWxkVXBvbigpLmFwcGVuZFBhdGgoInRlc3RmaWxlIikuYnVpbGQoKTsKKyAgICBTdHJpbmcgY29udGVudCA9ICJjb250ZW50IjsKKworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5jaGlsZHJlbihkaXJVcmkpKS5pc0VtcHR5KCk7CisgICAgdHJ5IChTdHJlYW1NdXRhdGlvbk9wZW5lci5NdXRhdG9yIG11dGF0b3IgPSBzdG9yYWdlLm9wZW4odXJpLCBTdHJlYW1NdXRhdGlvbk9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIG11dGF0b3IubXV0YXRlKAorICAgICAgICAgIChJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIG91dCkgLT4geworICAgICAgICAgICAgYnl0ZVtdIHJlYWQgPSBCeXRlU3RyZWFtcy50b0J5dGVBcnJheShpbik7CisgICAgICAgICAgICBhc3NlcnRUaGF0KHJlYWQpLmhhc0xlbmd0aCgwKTsKKyAgICAgICAgICAgIG91dC53cml0ZShjb250ZW50LmdldEJ5dGVzKFVURl84KSk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICB9KTsKKyAgICB9CisKKyAgICBSZWFkQnl0ZUFycmF5T3BlbmVyIG9wZW5lciA9IFJlYWRCeXRlQXJyYXlPcGVuZXIuY3JlYXRlKCk7CisgICAgU3RyaW5nIGFjdHVhbCA9IG5ldyBTdHJpbmcoc3RvcmFnZS5vcGVuKHVyaSwgb3BlbmVyKSwgVVRGXzgpOworCisgICAgYXNzZXJ0VGhhdChhY3R1YWwpLmlzRXF1YWxUbyhjb250ZW50KTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHdpbGxGYWlsVG9PdmVyd3JpdGVEaXJlY3RvcnkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aFRyYW5zZm9ybSgpOworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3RGlyZWN0b3J5VXJpKCk7CisgICAgU3RyaW5nIGNvbnRlbnQgPSAiY29udGVudCI7CisKKyAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9IHN0b3JhZ2Uub3Blbih1cmksIFN0cmVhbU11dGF0aW9uT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgIElPRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgIG11dGF0b3IubXV0YXRlKAorICAgICAgICAgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICAgICAgICAgIG91dC53cml0ZShjb250ZW50LmdldEJ5dGVzKFVURl84KSk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgICAgICAgICAgfSkpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNhbk11dGF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IHN0b3JhZ2VXaXRoVHJhbnNmb3JtKCk7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBTdHJpbmcgY29udGVudCA9ICJjb250ZW50IjsKKyAgICBTdHJpbmcgZXhwZWN0ZWQgPSBBc2NpaS50b1VwcGVyQ2FzZShjb250ZW50KTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgY29udGVudCk7CisKKyAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9IHN0b3JhZ2Uub3Blbih1cmksIFN0cmVhbU11dGF0aW9uT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgbXV0YXRvci5tdXRhdGUoCisgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICBTdHJpbmcgcmVhZCA9IG5ldyBTdHJpbmcoQnl0ZVN0cmVhbXMudG9CeXRlQXJyYXkoaW4pLCBVVEZfOCk7CisgICAgICAgICAgICBvdXQud3JpdGUoQXNjaWkudG9VcHBlckNhc2UocmVhZCkuZ2V0Qnl0ZXMoVVRGXzgpKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgIH0pOworICAgIH0KKworICAgIFJlYWRCeXRlQXJyYXlPcGVuZXIgb3BlbmVyID0gUmVhZEJ5dGVBcnJheU9wZW5lci5jcmVhdGUoKTsKKyAgICBTdHJpbmcgYWN0dWFsID0gbmV3IFN0cmluZyhzdG9yYWdlLm9wZW4odXJpLCBvcGVuZXIpLCBVVEZfOCk7CisKKyAgICBhc3NlcnRUaGF0KGFjdHVhbCkuaXNFcXVhbFRvKGV4cGVjdGVkKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNhbk11dGF0ZV9idXROb3RDb21taXQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aFRyYW5zZm9ybSgpOworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgU3RyaW5nIGNvbnRlbnQgPSAiY29udGVudCI7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIGNvbnRlbnQpOworCisgICAgdHJ5IChTdHJlYW1NdXRhdGlvbk9wZW5lci5NdXRhdG9yIG11dGF0b3IgPSBzdG9yYWdlLm9wZW4odXJpLCBTdHJlYW1NdXRhdGlvbk9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIG11dGF0b3IubXV0YXRlKAorICAgICAgICAgIChJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIG91dCkgLT4geworICAgICAgICAgICAgU3RyaW5nIHJlYWQgPSBuZXcgU3RyaW5nKEJ5dGVTdHJlYW1zLnRvQnl0ZUFycmF5KGluKSwgVVRGXzgpOworICAgICAgICAgICAgb3V0LndyaXRlKEFzY2lpLnRvVXBwZXJDYXNlKHJlYWQpLmdldEJ5dGVzKFVURl84KSk7CisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgICAgfSk7CisgICAgfQorCisgICAgUmVhZEJ5dGVBcnJheU9wZW5lciBvcGVuZXIgPSBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpOworICAgIFN0cmluZyBhY3R1YWwgPSBuZXcgU3RyaW5nKHN0b3JhZ2Uub3Blbih1cmksIG9wZW5lciksIFVURl84KTsKKworICAgIGFzc2VydFRoYXQoYWN0dWFsKS5pc0VxdWFsVG8oY29udGVudCk7IC8vIFVuY2hhbmdlZC4KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNhbk11dGF0ZV9yZXBlYXRlZGx5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlID0gc3RvcmFnZVdpdGhUcmFuc2Zvcm0oKTsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIFN0cmluZyBjb250ZW50ID0gImNvbnRlbnQiOworICAgIFN0cmluZyBleHBlY3RlZCA9ICJUTkVUTk9DIjsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgY29udGVudCk7CisKKyAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9IHN0b3JhZ2Uub3Blbih1cmksIFN0cmVhbU11dGF0aW9uT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgbXV0YXRvci5tdXRhdGUoCisgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICBTdHJpbmcgcmVhZCA9IG5ldyBTdHJpbmcoQnl0ZVN0cmVhbXMudG9CeXRlQXJyYXkoaW4pLCBVVEZfOCk7CisgICAgICAgICAgICBvdXQud3JpdGUoQXNjaWkudG9VcHBlckNhc2UocmVhZCkuZ2V0Qnl0ZXMoVVRGXzgpKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgIH0pOworICAgICAgbXV0YXRvci5tdXRhdGUoCisgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICBTdHJpbmcgcmVhZCA9IG5ldyBTdHJpbmcoQnl0ZVN0cmVhbXMudG9CeXRlQXJyYXkoaW4pLCBVVEZfOCk7CisgICAgICAgICAgICBvdXQud3JpdGUobmV3IFN0cmluZ0J1aWxkZXIocmVhZCkucmV2ZXJzZSgpLnRvU3RyaW5nKCkuZ2V0Qnl0ZXMoVVRGXzgpKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgIH0pOworICAgIH0KKworICAgIFJlYWRCeXRlQXJyYXlPcGVuZXIgb3BlbmVyID0gUmVhZEJ5dGVBcnJheU9wZW5lci5jcmVhdGUoKTsKKyAgICBTdHJpbmcgYWN0dWFsID0gbmV3IFN0cmluZyhzdG9yYWdlLm9wZW4odXJpLCBvcGVuZXIpLCBVVEZfOCk7CisKKyAgICBhc3NlcnRUaGF0KGFjdHVhbCkuaXNFcXVhbFRvKGV4cGVjdGVkKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNhbk11dGF0ZV93aXRoU3luYygpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IHN0b3JhZ2VXaXRoVHJhbnNmb3JtKCk7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBTdHJpbmcgY29udGVudCA9ICJjb250ZW50IjsKKyAgICBTdHJpbmcgZXhwZWN0ZWQgPSBBc2NpaS50b1VwcGVyQ2FzZShjb250ZW50KTsKKyAgICBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVN0cmluZ09wZW5lci5jcmVhdGUoY29udGVudCkpOworCisgICAgU3luY2luZ0JlaGF2aW9yIHN5bmNpbmcgPSBNb2NraXRvLnNweShuZXcgU3luY2luZ0JlaGF2aW9yKCkpOworICAgIHRyeSAoU3RyZWFtTXV0YXRpb25PcGVuZXIuTXV0YXRvciBtdXRhdG9yID0KKyAgICAgICAgc3RvcmFnZS5vcGVuKHVyaSwgU3RyZWFtTXV0YXRpb25PcGVuZXIuY3JlYXRlKCkud2l0aEJlaGF2aW9ycyhzeW5jaW5nKSkpIHsKKyAgICAgIG11dGF0b3IubXV0YXRlKAorICAgICAgICAgIChJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIG91dCkgLT4geworICAgICAgICAgICAgU3RyaW5nIHJlYWQgPSBuZXcgU3RyaW5nKEJ5dGVTdHJlYW1zLnRvQnl0ZUFycmF5KGluKSwgVVRGXzgpOworICAgICAgICAgICAgb3V0LndyaXRlKEFzY2lpLnRvVXBwZXJDYXNlKHJlYWQpLmdldEJ5dGVzKFVURl84KSk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICB9KTsKKyAgICB9CisgICAgTW9ja2l0by52ZXJpZnkoc3luY2luZykuc3luYygpOworCisgICAgU3RyaW5nIGFjdHVhbCA9IHN0b3JhZ2Uub3Blbih1cmksIFJlYWRTdHJpbmdPcGVuZXIuY3JlYXRlKCkpOworICAgIGFzc2VydFRoYXQoYWN0dWFsKS5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb2tJZkZpbGVEb2VzTm90RXhpc3Rfd2l0aEV4Y2x1c2l2ZUxvY2soKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aFRyYW5zZm9ybSgpOworICAgIFVyaSBkaXJVcmkgPSB0bXBVcmkubmV3RGlyZWN0b3J5VXJpKCk7CisgICAgVXJpIHVyaSA9IGRpclVyaS5idWlsZFVwb24oKS5hcHBlbmRQYXRoKCJ0ZXN0ZmlsZSIpLmJ1aWxkKCk7CisgICAgU3RyaW5nIGNvbnRlbnQgPSAiY29udGVudCI7CisKKyAgICBMb2NrRmlsZU9wZW5lciBsb2NraW5nID0gTG9ja0ZpbGVPcGVuZXIuY3JlYXRlRXhjbHVzaXZlKCk7CisgICAgdHJ5IChTdHJlYW1NdXRhdGlvbk9wZW5lci5NdXRhdG9yIG11dGF0b3IgPQorICAgICAgICBzdG9yYWdlLm9wZW4odXJpLCBTdHJlYW1NdXRhdGlvbk9wZW5lci5jcmVhdGUoKS53aXRoTG9ja2luZyhsb2NraW5nKSkpIHsKKyAgICAgIG11dGF0b3IubXV0YXRlKAorICAgICAgICAgIChJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIG91dCkgLT4geworICAgICAgICAgICAgYXNzZXJ0VGhhdChzdG9yYWdlLm9wZW4odXJpLCBMb2NrRmlsZU9wZW5lci5jcmVhdGVFeGNsdXNpdmUoKS5ub25CbG9ja2luZyh0cnVlKSkpCisgICAgICAgICAgICAgICAgLmlzTnVsbCgpOworICAgICAgICAgICAgYXNzZXJ0VGhhdChzdG9yYWdlLm9wZW4odXJpLCBMb2NrRmlsZU9wZW5lci5jcmVhdGVSZWFkT25seVNoYXJlZCgpLm5vbkJsb2NraW5nKHRydWUpKSkKKyAgICAgICAgICAgICAgICAuaXNOdWxsKCk7CisgICAgICAgICAgICBieXRlW10gcmVhZCA9IEJ5dGVTdHJlYW1zLnRvQnl0ZUFycmF5KGluKTsKKyAgICAgICAgICAgIGFzc2VydFRoYXQocmVhZCkuaGFzTGVuZ3RoKDApOworICAgICAgICAgICAgb3V0LndyaXRlKGNvbnRlbnQuZ2V0Qnl0ZXMoVVRGXzgpKTsKKyAgICAgICAgICAgIHJldHVybiB0cnVlOworICAgICAgICAgIH0pOworICAgIH0KKworICAgIFJlYWRCeXRlQXJyYXlPcGVuZXIgb3BlbmVyID0gUmVhZEJ5dGVBcnJheU9wZW5lci5jcmVhdGUoKTsKKyAgICBTdHJpbmcgYWN0dWFsID0gbmV3IFN0cmluZyhzdG9yYWdlLm9wZW4odXJpLCBvcGVuZXIpLCBVVEZfOCk7CisKKyAgICBhc3NlcnRUaGF0KGFjdHVhbCkuaXNFcXVhbFRvKGNvbnRlbnQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY2FuTXV0YXRlX3dpdGhFeGNsdXNpdmVMb2NrKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlID0gc3RvcmFnZVdpdGhUcmFuc2Zvcm0oKTsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIFN0cmluZyBjb250ZW50ID0gImNvbnRlbnQiOworICAgIFN0cmluZyBleHBlY3RlZCA9IEFzY2lpLnRvVXBwZXJDYXNlKGNvbnRlbnQpOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgdXJpLCBjb250ZW50KTsKKworICAgIExvY2tGaWxlT3BlbmVyIGxvY2tpbmcgPSBMb2NrRmlsZU9wZW5lci5jcmVhdGVFeGNsdXNpdmUoKTsKKyAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9CisgICAgICAgIHN0b3JhZ2Uub3Blbih1cmksIFN0cmVhbU11dGF0aW9uT3BlbmVyLmNyZWF0ZSgpLndpdGhMb2NraW5nKGxvY2tpbmcpKSkgeworICAgICAgbXV0YXRvci5tdXRhdGUoCisgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICBhc3NlcnRUaGF0KHN0b3JhZ2Uub3Blbih1cmksIExvY2tGaWxlT3BlbmVyLmNyZWF0ZUV4Y2x1c2l2ZSgpLm5vbkJsb2NraW5nKHRydWUpKSkKKyAgICAgICAgICAgICAgICAuaXNOdWxsKCk7CisgICAgICAgICAgICBhc3NlcnRUaGF0KHN0b3JhZ2Uub3Blbih1cmksIExvY2tGaWxlT3BlbmVyLmNyZWF0ZVJlYWRPbmx5U2hhcmVkKCkubm9uQmxvY2tpbmcodHJ1ZSkpKQorICAgICAgICAgICAgICAgIC5pc051bGwoKTsKKyAgICAgICAgICAgIFN0cmluZyByZWFkID0gbmV3IFN0cmluZyhCeXRlU3RyZWFtcy50b0J5dGVBcnJheShpbiksIFVURl84KTsKKyAgICAgICAgICAgIG91dC53cml0ZShBc2NpaS50b1VwcGVyQ2FzZShyZWFkKS5nZXRCeXRlcyhVVEZfOCkpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgfSk7CisgICAgfQorCisgICAgUmVhZEJ5dGVBcnJheU9wZW5lciBvcGVuZXIgPSBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpOworICAgIFN0cmluZyBhY3R1YWwgPSBuZXcgU3RyaW5nKHN0b3JhZ2Uub3Blbih1cmksIG9wZW5lciksIFVURl84KTsKKworICAgIGFzc2VydFRoYXQoYWN0dWFsKS5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcm9sbHNCYWNrX2FmdGVySU9FeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aFRyYW5zZm9ybSgpOworICAgIFVyaSBkaXJVcmkgPSB0bXBVcmkubmV3RGlyZWN0b3J5VXJpKCk7CisgICAgVXJpIHVyaSA9IGRpclVyaS5idWlsZFVwb24oKS5hcHBlbmRQYXRoKCJ0ZXN0ZmlsZSIpLmJ1aWxkKCk7CisgICAgU3RyaW5nIGNvbnRlbnQgPSAiY29udGVudCI7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIGNvbnRlbnQpOworCisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmNoaWxkcmVuKGRpclVyaSkpLmhhc1NpemUoMSk7CisKKyAgICBVcmkgdXJpRm9yUGFydGlhbFdyaXRlID0KKyAgICAgICAgdXJpLmJ1aWxkVXBvbigpLmVuY29kZWRGcmFnbWVudCgidHJhbnNmb3JtPXdyaXRldGhyb3dzKHdyaXRlX2xlbmd0aD0xKSIpLmJ1aWxkKCk7CisgICAgdHJ5IChTdHJlYW1NdXRhdGlvbk9wZW5lci5NdXRhdG9yIG11dGF0b3IgPQorICAgICAgICBzdG9yYWdlLm9wZW4odXJpRm9yUGFydGlhbFdyaXRlLCBTdHJlYW1NdXRhdGlvbk9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIG11dGF0b3IubXV0YXRlKAorICAgICAgICAgIChJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIG91dCkgLT4geworICAgICAgICAgICAgYXNzZXJ0VGhhdChzdG9yYWdlLmNoaWxkcmVuKGRpclVyaSkpLmhhc1NpemUoMik7CisgICAgICAgICAgICBTdHJpbmcgcmVhZCA9IG5ldyBTdHJpbmcoQnl0ZVN0cmVhbXMudG9CeXRlQXJyYXkoaW4pLCBVVEZfOCk7CisgICAgICAgICAgICBvdXQud3JpdGUoQXNjaWkudG9VcHBlckNhc2UocmVhZCkuZ2V0Qnl0ZXMoVVRGXzgpKTsKKyAgICAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbigic29tZXRoaW5nIHdlbnQgd3JvbmciKTsKKyAgICAgICAgICB9KTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBleCkgeworICAgICAgLy8gSWdub3JlLgorICAgIH0KKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuY2hpbGRyZW4oZGlyVXJpKSkuaGFzU2l6ZSgxKTsKKworICAgIFJlYWRCeXRlQXJyYXlPcGVuZXIgb3BlbmVyID0gUmVhZEJ5dGVBcnJheU9wZW5lci5jcmVhdGUoKTsKKyAgICBTdHJpbmcgYWN0dWFsID0gbmV3IFN0cmluZyhzdG9yYWdlLm9wZW4odXJpLCBvcGVuZXIpLCBVVEZfOCk7CisKKyAgICBhc3NlcnRUaGF0KGFjdHVhbCkuaXNFcXVhbFRvKGNvbnRlbnQpOyAvLyBTdGlsbCBvcmlnaW5hbCBjb250ZW50LgorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcm9sbHNCYWNrX2FmdGVyUnVudGltZUV4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IHN0b3JhZ2VXaXRoVHJhbnNmb3JtKCk7CisgICAgVXJpIGRpclVyaSA9IHRtcFVyaS5uZXdEaXJlY3RvcnlVcmkoKTsKKyAgICBVcmkgdXJpID0gZGlyVXJpLmJ1aWxkVXBvbigpLmFwcGVuZFBhdGgoInRlc3RmaWxlIikuYnVpbGQoKTsKKyAgICBTdHJpbmcgY29udGVudCA9ICJjb250ZW50IjsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgY29udGVudCk7CisKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuY2hpbGRyZW4oZGlyVXJpKSkuaGFzU2l6ZSgxKTsKKyAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9IHN0b3JhZ2Uub3Blbih1cmksIFN0cmVhbU11dGF0aW9uT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgbXV0YXRvci5tdXRhdGUoCisgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICBhc3NlcnRUaGF0KHN0b3JhZ2UuY2hpbGRyZW4oZGlyVXJpKSkuaGFzU2l6ZSgyKTsKKyAgICAgICAgICAgIFN0cmluZyByZWFkID0gbmV3IFN0cmluZyhCeXRlU3RyZWFtcy50b0J5dGVBcnJheShpbiksIFVURl84KTsKKyAgICAgICAgICAgIG91dC53cml0ZShBc2NpaS50b1VwcGVyQ2FzZShyZWFkKS5nZXRCeXRlcyhVVEZfOCkpOworICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oInNvbWV0aGluZyB3ZW50IHdyb25nIik7CisgICAgICAgICAgfSk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKKyAgICAgIC8vIElnbm9yZSBSdW50aW1lRXhjZXB0aW9uIHdyYXBwZWQgaW4gSU9FeGNlcHRpb24uCisgICAgfQorICAgIGFzc2VydFRoYXQoc3RvcmFnZS5jaGlsZHJlbihkaXJVcmkpKS5oYXNTaXplKDEpOworCisgICAgUmVhZEJ5dGVBcnJheU9wZW5lciBvcGVuZXIgPSBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpOworICAgIFN0cmluZyBhY3R1YWwgPSBuZXcgU3RyaW5nKHN0b3JhZ2Uub3Blbih1cmksIG9wZW5lciksIFVURl84KTsKKworICAgIGFzc2VydFRoYXQoYWN0dWFsKS5pc0VxdWFsVG8oY29udGVudCk7IC8vIFN0aWxsIG9yaWdpbmFsIGNvbnRlbnQuCisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBva0lmU3RyZWFtc0FyZVdyYXBwZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aFRyYW5zZm9ybSgpOworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisKKyAgICAvLyBXcml0ZSBwYXRoCisgICAgdHJ5IChTdHJlYW1NdXRhdGlvbk9wZW5lci5NdXRhdG9yIG11dGF0b3IgPSBzdG9yYWdlLm9wZW4odXJpLCBTdHJlYW1NdXRhdGlvbk9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIG11dGF0b3IubXV0YXRlKAorICAgICAgICAgIChJbnB1dFN0cmVhbSBpbiwgT3V0cHV0U3RyZWFtIG91dCkgLT4geworICAgICAgICAgICAgdHJ5IChEYXRhT3V0cHV0U3RyZWFtIGRvcyA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKG91dCkpIHsKKyAgICAgICAgICAgICAgZG9zLndyaXRlTG9uZyg0Mik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICB9KTsKKyAgICB9CisKKyAgICAvLyBSZWFkIHBhdGggKHNsaWdodGx5LW92ZXJsb2FkZWQgdXNlIG9mIFN0cmVhbU11dGF0aW9uT3BlbmVyLCBzaW5jZSB3ZSdyZSBub3QgZG9pbmcgYSBtdXRhdGlvbikKKyAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9IHN0b3JhZ2Uub3Blbih1cmksIFN0cmVhbU11dGF0aW9uT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgbXV0YXRvci5tdXRhdGUoCisgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICB0cnkgKERhdGFJbnB1dFN0cmVhbSBkaXMgPSBuZXcgRGF0YUlucHV0U3RyZWFtKGluKSkgeworICAgICAgICAgICAgICBhc3NlcnRUaGF0KGRpcy5yZWFkTG9uZygpKS5pc0VxdWFsVG8oNDIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgfSk7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY2FuTXV0YXRlX3dpdGhUcmFuc2Zvcm1zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlID0gc3RvcmFnZVdpdGhUcmFuc2Zvcm0oKTsKKyAgICBVcmkgZGlyVXJpID0gdG1wVXJpLm5ld0RpcmVjdG9yeVVyaSgpOworICAgIFVyaSB1cmkgPQorICAgICAgICBUcmFuc2Zvcm1Qcm90b0ZyYWdtZW50cy5hZGRPclJlcGxhY2VUcmFuc2Zvcm0oCisgICAgICAgICAgICBkaXJVcmkuYnVpbGRVcG9uKCkuYXBwZW5kUGF0aCgidGVzdGZpbGUiKS5idWlsZCgpLAorICAgICAgICAgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRDb21wcmVzcyhUcmFuc2Zvcm1Qcm90by5Db21wcmVzc1RyYW5zZm9ybS5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICBTdHJpbmcgY29udGVudCA9ICJjb250ZW50IjsKKyAgICBTdHJpbmcgZXhwZWN0ZWQgPSBBc2NpaS50b1VwcGVyQ2FzZShjb250ZW50KTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgY29udGVudCk7CisKKyAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9IHN0b3JhZ2Uub3Blbih1cmksIFN0cmVhbU11dGF0aW9uT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgbXV0YXRvci5tdXRhdGUoCisgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICBTdHJpbmcgcmVhZCA9IG5ldyBTdHJpbmcoQnl0ZVN0cmVhbXMudG9CeXRlQXJyYXkoaW4pLCBVVEZfOCk7CisgICAgICAgICAgICBieXRlW10gcGxhaW50ZXh0ID0gQXNjaWkudG9VcHBlckNhc2UocmVhZCkuZ2V0Qnl0ZXMoVVRGXzgpOworICAgICAgICAgICAgb3V0LndyaXRlKHBsYWludGV4dCk7CisgICAgICAgICAgICBvdXQuZmx1c2goKTsKKworICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGUgdG1wZmlsZSBpcyBjb21wcmVzc2VkLgorICAgICAgICAgICAgVXJpIHRtcCA9IG51bGw7CisgICAgICAgICAgICBmb3IgKFVyaSBjaGlsZFVyaSA6IHN0b3JhZ2UuY2hpbGRyZW4oZGlyVXJpKSkgeworICAgICAgICAgICAgICBpZiAoY2hpbGRVcmkuZ2V0UGF0aCgpLmNvbnRhaW5zKCIubW9ic3RvcmVfdG1wIikpIHsKKyAgICAgICAgICAgICAgICB0bXAgPSBjaGlsZFVyaTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYXNzZXJ0VGhhdCh0bXApLmlzTm90TnVsbCgpOworICAgICAgICAgICAgYnl0ZVtdIGNvbXByZXNzZWQgPSBzdG9yYWdlLm9wZW4odG1wLCBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpKTsKKyAgICAgICAgICAgIGFzc2VydFRoYXQoY29tcHJlc3NlZC5sZW5ndGgpLmlzR3JlYXRlclRoYW4oMCk7CisgICAgICAgICAgICBhc3NlcnRUaGF0KGNvbXByZXNzZWQpLmlzTm90RXF1YWxUbyhwbGFpbnRleHQpOworICAgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICAgICAgfSk7CisgICAgfQorCisgICAgUmVhZEJ5dGVBcnJheU9wZW5lciBvcGVuZXIgPSBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpOworICAgIFN0cmluZyBhY3R1YWwgPSBuZXcgU3RyaW5nKHN0b3JhZ2Uub3Blbih1cmksIG9wZW5lciksIFVURl84KTsKKworICAgIGFzc2VydFRoYXQoYWN0dWFsKS5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbXVsdGlUaHJlYWRXaXRob3V0TG9ja19sYWNrc0lzb2xhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IHN0b3JhZ2VXaXRoVHJhbnNmb3JtKCk7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBDb3VudERvd25MYXRjaCBsYXRjaCA9IG5ldyBDb3VudERvd25MYXRjaCgxKTsKKyAgICBDb3VudERvd25MYXRjaCBsYXRjaDIgPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisgICAgQ291bnREb3duTGF0Y2ggbGF0Y2gzID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworICAgIFRocmVhZCB0aHJlYWQgPQorICAgICAgICBuZXcgVGhyZWFkKAorICAgICAgICAgICAgKCkgLT4geworICAgICAgICAgICAgICB0cnkgKFN0cmVhbU11dGF0aW9uT3BlbmVyLk11dGF0b3IgbXV0YXRvciA9CisgICAgICAgICAgICAgICAgICBzdG9yYWdlLm9wZW4odXJpLCBTdHJlYW1NdXRhdGlvbk9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgICAgICAgICAgICBtdXRhdG9yLm11dGF0ZSgKKyAgICAgICAgICAgICAgICAgICAgKElucHV0U3RyZWFtIGluLCBPdXRwdXRTdHJlYW0gb3V0KSAtPiB7CisgICAgICAgICAgICAgICAgICAgICAgbGF0Y2guY291bnREb3duKCk7CisgICAgICAgICAgICAgICAgICAgICAgb3V0LndyaXRlKCJvdGhlci10aHJlYWQiLmdldEJ5dGVzKFVURl84KSk7CisgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGxhdGNoMi5hd2FpdCgpOworICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGV4KSB7CisgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oZXgpOworICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgICAgICAgICAgbGF0Y2gzLmNvdW50RG93bigpOworICAgICAgICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZXgpIHsKKyAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihleCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgIHRocmVhZC5zZXREYWVtb24odHJ1ZSk7CisgICAgdGhyZWFkLnN0YXJ0KCk7CisgICAgbGF0Y2guYXdhaXQoKTsKKworICAgIHRyeSAoU3RyZWFtTXV0YXRpb25PcGVuZXIuTXV0YXRvciBtdXRhdG9yID0gc3RvcmFnZS5vcGVuKHVyaSwgU3RyZWFtTXV0YXRpb25PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICBtdXRhdG9yLm11dGF0ZSgKKyAgICAgICAgICAoSW5wdXRTdHJlYW0gaW4sIE91dHB1dFN0cmVhbSBvdXQpIC0+IHsKKyAgICAgICAgICAgIG91dC53cml0ZSgidGhpcy10aHJlYWQiLmdldEJ5dGVzKFVURl84KSk7CisgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgICAgICB9KTsKKyAgICB9CisKKyAgICBSZWFkQnl0ZUFycmF5T3BlbmVyIG9wZW5lciA9IFJlYWRCeXRlQXJyYXlPcGVuZXIuY3JlYXRlKCk7CisgICAgYXNzZXJ0VGhhdChuZXcgU3RyaW5nKHN0b3JhZ2Uub3Blbih1cmksIG9wZW5lciksIFVURl84KSkuaXNFcXVhbFRvKCJ0aGlzLXRocmVhZCIpOworCisgICAgbGF0Y2gyLmNvdW50RG93bigpOworICAgIGxhdGNoMy5hd2FpdCgpOworCisgICAgYXNzZXJ0VGhhdChuZXcgU3RyaW5nKHN0b3JhZ2Uub3Blbih1cmksIG9wZW5lciksIFVURl84KSkuaXNFcXVhbFRvKCJvdGhlci10aHJlYWQiKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TdHJpbmdPcGVuZXJUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1N0cmluZ09wZW5lclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZmVmNjM1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TdHJpbmdPcGVuZXJUZXN0LmphdmEKQEAgLTAsMCArMSw3NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuSmF2YUZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmVoYXZpb3JzLlN5bmNpbmdCZWhhdmlvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbC5DaGFyc2V0czsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2tpdG87CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIFN0cmluZ09wZW5lclRlc3QgeworCisgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZTsKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeVVyaSB0bXBVcmkgPSBuZXcgVGVtcG9yYXJ5VXJpKCk7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcFN0b3JhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9yYWdlID0gbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoQXJyYXlzLmFzTGlzdChuZXcgSmF2YUZpbGVCYWNrZW5kKCkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHdpdGhNb25pdG9yX3dyaXRlc1N0cmluZygpIHRocm93cyBFeGNlcHRpb24geworCisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBTdHJpbmcgZXhwZWN0ZWQgPSAiVGhlIGZpdmUgYm94aW5nIHdpemFyZHMganVtcCBxdWlja2x5IjsKKyAgICBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVN0cmluZ09wZW5lci5jcmVhdGUoZXhwZWN0ZWQpKTsKKyAgICBhc3NlcnRUaGF0KHN0b3JhZ2Uub3Blbih1cmksIFJlYWRTdHJpbmdPcGVuZXIuY3JlYXRlKCkpKS5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd3JpdGVzU3RyaW5nX3dpdGhEaWZmZXJlbnRDaGFyc2V0cygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgU3RyaW5nIGV4cGVjdGVkID0gIlRoZSBmaXZlIGJveGluZyB3aXphcmRzIGp1bXAgcXVpY2tseSI7CisKKyAgICBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVN0cmluZ09wZW5lci5jcmVhdGUoZXhwZWN0ZWQpLndpdGhDaGFyc2V0KENoYXJzZXRzLlVTX0FTQ0lJKSk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyaW5nT3BlbmVyLmNyZWF0ZSgpLndpdGhDaGFyc2V0KENoYXJzZXRzLlVTX0FTQ0lJKSkpCisgICAgICAgIC5pc0VxdWFsVG8oZXhwZWN0ZWQpOworCisgICAgc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVTdHJpbmdPcGVuZXIuY3JlYXRlKGV4cGVjdGVkKS53aXRoQ2hhcnNldChDaGFyc2V0cy5JU09fODg1OV8xKSk7CisgICAgYXNzZXJ0VGhhdChzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyaW5nT3BlbmVyLmNyZWF0ZSgpLndpdGhDaGFyc2V0KENoYXJzZXRzLklTT184ODU5XzEpKSkKKyAgICAgICAgLmlzRXF1YWxUbyhleHBlY3RlZCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbnZva2VzX2F1dG9TeW5jKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaTEgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgU3luY2luZ0JlaGF2aW9yIHN5bmNpbmcgPSBNb2NraXRvLnNweShuZXcgU3luY2luZ0JlaGF2aW9yKCkpOworICAgIHN0b3JhZ2Uub3Blbih1cmkxLCBXcml0ZVN0cmluZ09wZW5lci5jcmVhdGUoInNvbWUgc3RyaW5nIikud2l0aEJlaGF2aW9ycyhzeW5jaW5nKSk7CisgICAgTW9ja2l0by52ZXJpZnkoc3luY2luZykuc3luYygpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1N5c3RlbUxpYnJhcnlPcGVuZXJBbmRyb2lkVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TeXN0ZW1MaWJyYXJ5T3BlbmVyQW5kcm9pZFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMWI3MDI5Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9TeXN0ZW1MaWJyYXJ5T3BlbmVyQW5kcm9pZFRlc3QuamF2YQpAQCAtMCwwICsxLDExNSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuYXBwcy5jb21tb24udGVzdGluZy51dGlsLkFuZHJvaWRUZXN0VXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5KYXZhRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5GaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVtcG9yYXJ5VXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5Db21wcmVzc1RyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuVHJhbnNmb3JtUHJvdG9zOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5CeXRlU3RyZWFtczsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuQ2FsbGFibGU7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lcnMuSlVuaXQ0OworCitAUnVuV2l0aChKVW5pdDQuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgU3lzdGVtTGlicmFyeU9wZW5lckFuZHJvaWRUZXN0IHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgU09fRElSID0KKyAgICAgICJ0aGlyZF9wYXJ0eS9qYXZhX3NyYy9hbmRyb2lkX2xpYnMvbW9iaWxlZGF0YWRvd25sb2FkL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEhFTExPMU5BVElWRV9TTyA9IFNPX0RJUiArICJsaWJoZWxsbzFuYXRpdmUuc28iOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSEVMTE8yTkFUSVZFX1NPID0gU09fRElSICsgImxpYmhlbGxvMm5hdGl2ZS5zbyI7CisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeVVyaSB0bXBVcmkgPSBuZXcgVGVtcG9yYXJ5VXJpKCk7CisgIEBSdWxlIHB1YmxpYyBGaWxlRGVzY3JpcHRvckxlYWtDaGVja2VyIGxlYWtDaGVja2VyID0gbmV3IEZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXIoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIGluaXRpYWxpemVTdG9yYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihuZXcgSmF2YUZpbGVCYWNrZW5kKCkpLCBJbW11dGFibGVMaXN0Lm9mKG5ldyBDb21wcmVzc1RyYW5zZm9ybSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuRnJvbUZpbGVXaXRob3V0Q2FjaGVfc2hvdWxkTG9hZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICBBbmRyb2lkVGVzdFV0aWwuZ2V0VGVzdERhdGFJbnB1dFN0cmVhbShjb250ZXh0LmdldENvbnRlbnRSZXNvbHZlcigpLCBIRUxMTzFOQVRJVkVfU08pOworICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICBCeXRlU3RyZWFtcy5jb3B5KGluLCBvdXQpOworICAgICAgc3RvcmFnZS5vcGVuKHVyaSwgU3lzdGVtTGlicmFyeU9wZW5lci5jcmVhdGUoKSk7CisgICAgICBhc3NlcnRUaGF0KEhlbGxvTmF0aXZlLnNheUhlbGxvKCkpLmlzRXF1YWxUbygiaGVsbG8xIik7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3BlbkNvbXByZXNzZWRGcm9tRmlsZVdpdGhvdXRDYWNoZV9zaG91bGRGYWlsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmlCdWlsZGVyKCkud2l0aFRyYW5zZm9ybShUcmFuc2Zvcm1Qcm90b3MuREVGQVVMVF9DT01QUkVTU19TUEVDKS5idWlsZCgpOworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPQorICAgICAgICAgICAgQW5kcm9pZFRlc3RVdGlsLmdldFRlc3REYXRhSW5wdXRTdHJlYW0oY29udGV4dC5nZXRDb250ZW50UmVzb2x2ZXIoKSwgSEVMTE8xTkFUSVZFX1NPKTsKKyAgICAgICAgT3V0cHV0U3RyZWFtIG91dCA9IHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgQnl0ZVN0cmVhbXMuY29weShpbiwgb3V0KTsKKyAgICB9CisgICAgYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLm9wZW4odXJpLCBTeXN0ZW1MaWJyYXJ5T3BlbmVyLmNyZWF0ZSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvcGVuQ29tcHJlc3NlZEZyb21GaWxlV2l0aENhY2hlX3Nob3VsZFN1Y2NlZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaUJ1aWxkZXIoKS53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0NPTVBSRVNTX1NQRUMpLmJ1aWxkKCk7CisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgICAgICBBbmRyb2lkVGVzdFV0aWwuZ2V0VGVzdERhdGFJbnB1dFN0cmVhbShjb250ZXh0LmdldENvbnRlbnRSZXNvbHZlcigpLCBIRUxMTzJOQVRJVkVfU08pOworICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICBCeXRlU3RyZWFtcy5jb3B5KGluLCBvdXQpOworICAgIH0KKyAgICBVcmkgY2FjaGVEaXIgPSB0bXBVcmkuZ2V0Um9vdFVyaSgpOworCisgICAgQ2FsbGFibGU8SW50ZWdlcj4gY291bnRMaWJzID0KKyAgICAgICAgKCkgLT4geworICAgICAgICAgIGludCBudW1MaWJzID0gMDsKKyAgICAgICAgICBmb3IgKFVyaSBjaGlsZCA6IHN0b3JhZ2UuY2hpbGRyZW4oY2FjaGVEaXIpKSB7CisgICAgICAgICAgICBpZiAoY2hpbGQuZ2V0UGF0aCgpLmVuZHNXaXRoKCIuc28iKSkgeworICAgICAgICAgICAgICBudW1MaWJzKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIHJldHVybiBudW1MaWJzOworICAgICAgICB9OworICAgIGFzc2VydFRoYXQoY291bnRMaWJzLmNhbGwoKSkuaXNFcXVhbFRvKDApOyAvLyBJbml0aWFsbHksIG5vIGxpYnJhcmllcworCisgICAgc3RvcmFnZS5vcGVuKHVyaSwgU3lzdGVtTGlicmFyeU9wZW5lci5jcmVhdGUoKS53aXRoQ2FjaGVEaXJlY3RvcnkoY2FjaGVEaXIpKTsKKyAgICBhc3NlcnRUaGF0KEhlbGxvTmF0aXZlLnNheUhlbGxvKCkpLmlzRXF1YWxUbygiaGVsbG8yIik7CisgICAgYXNzZXJ0VGhhdChjb3VudExpYnMuY2FsbCgpKS5pc0VxdWFsVG8oMSk7IC8vIE5vdyB3ZSBzZWUgdGhlIG9uZSBsaWJyYXJ5LgorCisgICAgc3RvcmFnZS5vcGVuKHVyaSwgU3lzdGVtTGlicmFyeU9wZW5lci5jcmVhdGUoKS53aXRoQ2FjaGVEaXJlY3RvcnkoY2FjaGVEaXIpKTsKKyAgICBhc3NlcnRUaGF0KGNvdW50TGlicy5jYWxsKCkpLmlzRXF1YWxUbygxKTsgLy8gVGhlIG9uZSBsaWJyYXJ5IGlzIGZvdW5kIGFnYWluLgorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1dyaXRlQnl0ZUFycmF5T3BlbmVyVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9Xcml0ZUJ5dGVBcnJheU9wZW5lclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43OGMzNzNlCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9Xcml0ZUJ5dGVBcnJheU9wZW5lclRlc3QuamF2YQpAQCAtMCwwICsxLDEzNCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMubWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQ7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMubWFrZUJ5dGVDb250ZW50VGhhdEV4Y2VlZHNPc0J1ZmZlclNpemU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMucmVhZEZpbGVJbkJ5dGVzRnJvbVNvdXJjZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ud2hlbjsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5KYXZhRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iZWhhdmlvcnMuU3luY2luZ0JlaGF2aW9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVtcG9yYXJ5VXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc2FtcGxlcy5CeXRlQ291bnRpbmdNb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLkNvbXByZXNzVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5UcmFuc2Zvcm1Qcm90b3M7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlJbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Nb2NrOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2tpdG87CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBXcml0ZUJ5dGVBcnJheU9wZW5lclRlc3QgeworCisgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlVcmkgdG1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworCisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgQE1vY2sgcHJpdmF0ZSBCYWNrZW5kIG1vY2tCYWNrZW5kOworCisgIHB1YmxpYyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2VXaXRoVHJhbnNmb3JtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICBBcnJheXMuYXNMaXN0KG5ldyBKYXZhRmlsZUJhY2tlbmQoKSksIEFycmF5cy5hc0xpc3QobmV3IENvbXByZXNzVHJhbnNmb3JtKCkpKTsKKyAgfQorCisgIHB1YmxpYyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2VXaXRoTW9uaXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIHJldHVybiBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgQXJyYXlzLmFzTGlzdChuZXcgSmF2YUZpbGVCYWNrZW5kKCkpLAorICAgICAgICBBcnJheXMuYXNMaXN0KCksCisgICAgICAgIEFycmF5cy5hc0xpc3QobmV3IEJ5dGVDb3VudGluZ01vbml0b3IoKSkpOworICB9CisKKyAgcHVibGljIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZVdpdGhNb2NrQmFja2VuZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHdoZW4obW9ja0JhY2tlbmQubmFtZSgpKS50aGVuUmV0dXJuKCJtb2NrIik7CisgICAgcmV0dXJuIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEFycmF5cy5hc0xpc3QobW9ja0JhY2tlbmQpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRpcmVjdEZpbGVfd3JpdGVzQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aFRyYW5zZm9ybSgpOworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgYnl0ZVtdIGV4cGVjdGVkID0gbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoKTsKKyAgICBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZUJ5dGVBcnJheU9wZW5lci5jcmVhdGUoZXhwZWN0ZWQpKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlSW5CeXRlc0Zyb21Tb3VyY2Uoc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpKQorICAgICAgICAuaXNFcXVhbFRvKGV4cGVjdGVkKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRpcmVjdEZpbGVfd3JpdGVzQXJyYXlUaGF0RXhjZWVkc09zQnVmZmVyU2l6ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IHN0b3JhZ2VXaXRoVHJhbnNmb3JtKCk7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKTsKKyAgICBieXRlW10gZXhwZWN0ZWQgPSBtYWtlQnl0ZUNvbnRlbnRUaGF0RXhjZWVkc09zQnVmZmVyU2l6ZSgpOworICAgIHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZShleHBlY3RlZCkpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVJbkJ5dGVzRnJvbVNvdXJjZShzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkpCisgICAgICAgIC5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd2l0aE1vbml0b3Jfd3JpdGVzQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aE1vbml0b3IoKTsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIGJ5dGVbXSBleHBlY3RlZCA9IG1ha2VBcnJheU9mQnl0ZXNDb250ZW50KCk7CisgICAgc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVCeXRlQXJyYXlPcGVuZXIuY3JlYXRlKGV4cGVjdGVkKSk7CisgICAgYXNzZXJ0VGhhdChyZWFkRmlsZUluQnl0ZXNGcm9tU291cmNlKHN0b3JhZ2Uub3Blbih1cmksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSkKKyAgICAgICAgLmlzRXF1YWxUbyhleHBlY3RlZCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB3aXRoVHJhbnNmb3JtX3Byb2R1Y2VzQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aFRyYW5zZm9ybSgpOworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpQnVpbGRlcigpLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfQ09NUFJFU1NfU1BFQykuYnVpbGQoKTsKKyAgICBieXRlW10gZXhwZWN0ZWQgPSBtYWtlQXJyYXlPZkJ5dGVzQ29udGVudCgpOworICAgIHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZShleHBlY3RlZCkpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVJbkJ5dGVzRnJvbVNvdXJjZShzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkpCisgICAgICAgIC5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd2l0aE1vY2tCYWNrZW5kX3Byb2R1Y2VzQXJyYXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2UgPSBzdG9yYWdlV2l0aE1vY2tCYWNrZW5kKCk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgibW9jazovIik7CisgICAgYnl0ZVtdIGV4cGVjdGVkID0gbWFrZUFycmF5T2ZCeXRlc0NvbnRlbnQoKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLm9wZW5Gb3JXcml0ZShhbnkoKSkpLnRoZW5SZXR1cm4obmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLm9wZW5Gb3JSZWFkKGFueSgpKSkudGhlblJldHVybihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZXhwZWN0ZWQpKTsKKworICAgIHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZShleHBlY3RlZCkpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVJbkJ5dGVzRnJvbVNvdXJjZShzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkpCisgICAgICAgIC5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW52b2tlc19hdXRvU3luYygpIHRocm93cyBFeGNlcHRpb24geworICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZSA9IHN0b3JhZ2VXaXRoVHJhbnNmb3JtKCk7CisgICAgVXJpIHVyaTEgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgU3luY2luZ0JlaGF2aW9yIHN5bmNpbmcgPSBNb2NraXRvLnNweShuZXcgU3luY2luZ0JlaGF2aW9yKCkpOworICAgIHN0b3JhZ2Uub3BlbigKKyAgICAgICAgdXJpMSwgV3JpdGVCeXRlQXJyYXlPcGVuZXIuY3JlYXRlKG1ha2VBcnJheU9mQnl0ZXNDb250ZW50KCkpLndpdGhCZWhhdmlvcnMoc3luY2luZykpOworICAgIE1vY2tpdG8udmVyaWZ5KHN5bmNpbmcpLnN5bmMoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9Xcml0ZUZpbGVPcGVuZXJBbmRyb2lkVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9Xcml0ZUZpbGVPcGVuZXJBbmRyb2lkVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyMmQ2OTIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL1dyaXRlRmlsZU9wZW5lckFuZHJvaWRUZXN0LmphdmEKQEAgLTAsMCArMSwyNjggQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVyczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLm1ha2VDb250ZW50VGhhdEV4Y2VlZHNPc0J1ZmZlclNpemU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMucmVhZEZpbGVGcm9tU291cmNlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLndyaXRlRmlsZVRvU2luazsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5Qcm9jZXNzOworaW1wb3J0IGFuZHJvaWQuc3lzdGVtLk9zOworaW1wb3J0IGFuZHJvaWQuc3lzdGVtLk9zQ29uc3RhbnRzOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5GaWxlVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuSmF2YUZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkZpbGVDb252ZXJ0aWJsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi5pbnRlcm5hbC5Gb3J3YXJkaW5nT3V0cHV0U3RyZWFtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuQWx3YXlzVGhyb3dzVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5CYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3Jtcy5Db21wcmVzc1RyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuVHJhbnNmb3JtUHJvdG9zOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UZW1wb3JhcnlGb2xkZXI7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLkpVbml0NDsKKworQFJ1bldpdGgoSlVuaXQ0LmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIFdyaXRlRmlsZU9wZW5lckFuZHJvaWRUZXN0IHsKKworICBwcml2YXRlIGZpbmFsIFN0cmluZyBiaWdDb250ZW50ID0gbWFrZUNvbnRlbnRUaGF0RXhjZWVkc09zQnVmZmVyU2l6ZSgpOworICBwcml2YXRlIGZpbmFsIFN0cmluZyBzbWFsbENvbnRlbnQgPSAiY29udGVudCI7CisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworICBwcml2YXRlIEV4ZWN1dG9yU2VydmljZSBleGVjdXRvciA9IEV4ZWN1dG9ycy5uZXdDYWNoZWRUaHJlYWRQb29sKCk7CisgIHByaXZhdGUgZmluYWwgQ29udGV4dCBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5Rm9sZGVyIHRtcEZvbGRlciA9IG5ldyBUZW1wb3JhcnlGb2xkZXIoKTsKKyAgQFJ1bGUgcHVibGljIEZpbGVEZXNjcmlwdG9yTGVha0NoZWNrZXIgbGVha0NoZWNrZXIgPSBuZXcgRmlsZURlc2NyaXB0b3JMZWFrQ2hlY2tlcigpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXBTdG9yYWdlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihuZXcgSmF2YUZpbGVCYWNrZW5kKCkpLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihuZXcgQ29tcHJlc3NUcmFuc2Zvcm0oKSwgbmV3IEFsd2F5c1Rocm93c1RyYW5zZm9ybSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjb21wcmVzc0FuZFdyaXRlVG9QaXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHVyaVRvTmV3VGVtcEZpbGUoKS53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0NPTVBSRVNTX1NQRUMpLmJ1aWxkKCk7CisgICAgRmlsZSBwaXBlZEZpbGU7CisgICAgdHJ5IChXcml0ZUZpbGVPcGVuZXIuRmlsZUNsb3NlciBwaXBlZCA9CisgICAgICAgIHN0b3JhZ2Uub3BlbigKKyAgICAgICAgICAgIHVyaSwgV3JpdGVGaWxlT3BlbmVyLmNyZWF0ZSgpLndpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoZXhlY3V0b3IsIGNvbnRleHQpKSkgeworICAgICAgcGlwZWRGaWxlID0gcGlwZWQuZmlsZSgpOworICAgICAgYXNzZXJ0VGhhdChwaXBlZEZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkpLmVuZHNXaXRoKCIuZmlmbyIpOworICAgICAgd3JpdGVGaWxlVG9TaW5rKG5ldyBGaWxlT3V0cHV0U3RyZWFtKHBpcGVkRmlsZSksIGJpZ0NvbnRlbnQpOworICAgIH0KKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlRnJvbVNvdXJjZShzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkpCisgICAgICAgIC5pc0VxdWFsVG8oYmlnQ29udGVudCk7CisgICAgYXNzZXJ0VGhhdChwaXBlZEZpbGUuZXhpc3RzKCkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNvbXByZXNzQnV0RG9udFdyaXRlVG9QaXBlX3Nob3VsZE5vdExlYWsoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdXJpVG9OZXdUZW1wRmlsZSgpLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfQ09NUFJFU1NfU1BFQykuYnVpbGQoKTsKKyAgICBGaWxlIHBpcGVkRmlsZTsKKyAgICB0cnkgKFdyaXRlRmlsZU9wZW5lci5GaWxlQ2xvc2VyIHBpcGVkID0KKyAgICAgICAgc3RvcmFnZS5vcGVuKAorICAgICAgICAgICAgdXJpLCBXcml0ZUZpbGVPcGVuZXIuY3JlYXRlKCkud2l0aEZhbGxiYWNrVG9QaXBlVXNpbmdFeGVjdXRvcihleGVjdXRvciwgY29udGV4dCkpKSB7CisgICAgICBwaXBlZEZpbGUgPSBwaXBlZC5maWxlKCk7CisgICAgICBhc3NlcnRUaGF0KHBpcGVkRmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSkuZW5kc1dpdGgoIi5maWZvIik7CisgICAgfQorICAgIGFzc2VydFRoYXQocGlwZWRGaWxlLmV4aXN0cygpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBzdGFsZUZpZm9faXNEZWxldGVkQW5kUmVwbGFjZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdXJpVG9OZXdUZW1wRmlsZSgpLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfQ09NUFJFU1NfU1BFQykuYnVpbGQoKTsKKworICAgIFN0cmluZyBzdGFsZUZpZm9OYW1lID0gIi5tb2JzdG9yZS1Xcml0ZUZpbGVPcGVuZXItIiArIFByb2Nlc3MubXlQaWQoKSArICItMC5maWZvIjsKKyAgICBGaWxlIHN0YWxlRmlmbyA9IG5ldyBGaWxlKGNvbnRleHQuZ2V0Q2FjaGVEaXIoKSwgc3RhbGVGaWZvTmFtZSk7CisgICAgT3MubWtmaWZvKHN0YWxlRmlmby5nZXRBYnNvbHV0ZVBhdGgoKSwgT3NDb25zdGFudHMuU19JUlVTUiB8IE9zQ29uc3RhbnRzLlNfSVdVU1IpOworCisgICAgRmlsZSBwaXBlZEZpbGU7CisgICAgdHJ5IChXcml0ZUZpbGVPcGVuZXIuRmlsZUNsb3NlciBwaXBlZCA9CisgICAgICAgIHN0b3JhZ2Uub3BlbigKKyAgICAgICAgICAgIHVyaSwgV3JpdGVGaWxlT3BlbmVyLmNyZWF0ZSgpLndpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoZXhlY3V0b3IsIGNvbnRleHQpKSkgeworICAgICAgcGlwZWRGaWxlID0gcGlwZWQuZmlsZSgpOworICAgICAgYXNzZXJ0VGhhdChwaXBlZEZpbGUpLmlzRXF1YWxUbyhzdGFsZUZpZm8pOworICAgICAgd3JpdGVGaWxlVG9TaW5rKG5ldyBGaWxlT3V0cHV0U3RyZWFtKHBpcGVkRmlsZSksIGJpZ0NvbnRlbnQpOworICAgIH0KKworICAgIGFzc2VydFRoYXQocmVhZEZpbGVGcm9tU291cmNlKHN0b3JhZ2Uub3Blbih1cmksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSkKKyAgICAgICAgLmlzRXF1YWxUbyhiaWdDb250ZW50KTsKKyAgICBhc3NlcnRUaGF0KHN0YWxlRmlmby5leGlzdHMoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgbXVsdGlwbGVTdHJlYW1zX3Nob3VsZENyZWF0ZU11bHRpcGxlRmlmb3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpMCA9IHVyaVRvTmV3VGVtcEZpbGUoKS53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0NPTVBSRVNTX1NQRUMpLmJ1aWxkKCk7CisgICAgVXJpIHVyaTEgPSB1cmlUb05ld1RlbXBGaWxlKCkud2l0aFRyYW5zZm9ybShUcmFuc2Zvcm1Qcm90b3MuREVGQVVMVF9DT01QUkVTU19TUEVDKS5idWlsZCgpOworICAgIFVyaSB1cmkyID0gdXJpVG9OZXdUZW1wRmlsZSgpLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfQ09NUFJFU1NfU1BFQykuYnVpbGQoKTsKKworICAgIFdyaXRlRmlsZU9wZW5lci5GaWxlQ2xvc2VyIHBpcGVkMCA9CisgICAgICAgIHN0b3JhZ2Uub3BlbigKKyAgICAgICAgICAgIHVyaTAsIFdyaXRlRmlsZU9wZW5lci5jcmVhdGUoKS53aXRoRmFsbGJhY2tUb1BpcGVVc2luZ0V4ZWN1dG9yKGV4ZWN1dG9yLCBjb250ZXh0KSk7CisgICAgV3JpdGVGaWxlT3BlbmVyLkZpbGVDbG9zZXIgcGlwZWQxID0KKyAgICAgICAgc3RvcmFnZS5vcGVuKAorICAgICAgICAgICAgdXJpMSwgV3JpdGVGaWxlT3BlbmVyLmNyZWF0ZSgpLndpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoZXhlY3V0b3IsIGNvbnRleHQpKTsKKyAgICBXcml0ZUZpbGVPcGVuZXIuRmlsZUNsb3NlciBwaXBlZDIgPQorICAgICAgICBzdG9yYWdlLm9wZW4oCisgICAgICAgICAgICB1cmkyLCBXcml0ZUZpbGVPcGVuZXIuY3JlYXRlKCkud2l0aEZhbGxiYWNrVG9QaXBlVXNpbmdFeGVjdXRvcihleGVjdXRvciwgY29udGV4dCkpOworCisgICAgYXNzZXJ0VGhhdChwaXBlZDAuZmlsZSgpLmdldEFic29sdXRlUGF0aCgpKS5lbmRzV2l0aCgiLTAuZmlmbyIpOworICAgIGFzc2VydFRoYXQocGlwZWQxLmZpbGUoKS5nZXRBYnNvbHV0ZVBhdGgoKSkuZW5kc1dpdGgoIi0xLmZpZm8iKTsKKyAgICBhc3NlcnRUaGF0KHBpcGVkMi5maWxlKCkuZ2V0QWJzb2x1dGVQYXRoKCkpLmVuZHNXaXRoKCItMi5maWZvIik7CisKKyAgICB3cml0ZUZpbGVUb1NpbmsobmV3IEZpbGVPdXRwdXRTdHJlYW0ocGlwZWQwLmZpbGUoKSksIGJpZ0NvbnRlbnQgKyAiMCIpOworICAgIHdyaXRlRmlsZVRvU2luayhuZXcgRmlsZU91dHB1dFN0cmVhbShwaXBlZDEuZmlsZSgpKSwgYmlnQ29udGVudCArICIxIik7CisgICAgd3JpdGVGaWxlVG9TaW5rKG5ldyBGaWxlT3V0cHV0U3RyZWFtKHBpcGVkMi5maWxlKCkpLCBiaWdDb250ZW50ICsgIjIiKTsKKworICAgIHBpcGVkMC5jbG9zZSgpOworICAgIHBpcGVkMS5jbG9zZSgpOworICAgIHBpcGVkMi5jbG9zZSgpOworCisgICAgYXNzZXJ0VGhhdChyZWFkRmlsZUZyb21Tb3VyY2Uoc3RvcmFnZS5vcGVuKHVyaTAsIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSkKKyAgICAgICAgLmlzRXF1YWxUbyhiaWdDb250ZW50ICsgIjAiKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlRnJvbVNvdXJjZShzdG9yYWdlLm9wZW4odXJpMSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKSkpKQorICAgICAgICAuaXNFcXVhbFRvKGJpZ0NvbnRlbnQgKyAiMSIpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGVGcm9tU291cmNlKHN0b3JhZ2Uub3Blbih1cmkyLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkpCisgICAgICAgIC5pc0VxdWFsVG8oYmlnQ29udGVudCArICIyIik7CisKKyAgICBhc3NlcnRUaGF0KHBpcGVkMC5maWxlKCkuZXhpc3RzKCkpLmlzRmFsc2UoKTsKKyAgICBhc3NlcnRUaGF0KHBpcGVkMS5maWxlKCkuZXhpc3RzKCkpLmlzRmFsc2UoKTsKKyAgICBhc3NlcnRUaGF0KHBpcGVkMi5maWxlKCkuZXhpc3RzKCkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNvbXByZXNzQW5kV3JpdGVUb1BpcGVXaXRob3V0RXhlY3V0b3Jfc2hvdWxkRmFpbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB1cmlUb05ld1RlbXBGaWxlKCkud2l0aFRyYW5zZm9ybShUcmFuc2Zvcm1Qcm90b3MuREVGQVVMVF9DT01QUkVTU19TUEVDKS5idWlsZCgpOworICAgIGFzc2VydFRocm93cyhJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVGaWxlT3BlbmVyLmNyZWF0ZSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB3cml0ZUJpZ0NvbnRlbnRXaXRoRXhjZXB0aW9uX3Nob3VsZFRocm93RVBpcGVBbmRQcm9wYWdhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0KKyAgICAgICAgdXJpVG9OZXdUZW1wRmlsZSgpLmJ1aWxkKCkuYnVpbGRVcG9uKCkuZW5jb2RlZEZyYWdtZW50KCJ0cmFuc2Zvcm09YWx3YXlzdGhyb3dzIikuYnVpbGQoKTsKKyAgICBXcml0ZUZpbGVPcGVuZXIuRmlsZUNsb3NlciBwaXBlZCA9CisgICAgICAgIHN0b3JhZ2Uub3BlbigKKyAgICAgICAgICAgIHVyaSwgV3JpdGVGaWxlT3BlbmVyLmNyZWF0ZSgpLndpdGhGYWxsYmFja1RvUGlwZVVzaW5nRXhlY3V0b3IoZXhlY3V0b3IsIGNvbnRleHQpKTsKKyAgICAvLyBUaHJvd3MgRVBJUEUgd2hpbGUgd3JpdGluZy4KKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiB3cml0ZUZpbGVUb1NpbmsobmV3IEZpbGVPdXRwdXRTdHJlYW0ocGlwZWQuZmlsZSgpKSwgYmlnQ29udGVudCkpOworICAgIC8vIFRocm93cyB1bmRlcmx5aW5nIGV4Y2VwdGlvbiB3aGVuIGNsb3NpbmcuCisgICAgYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBwaXBlZC5jbG9zZSgpKTsKKyAgICBhc3NlcnRUaGF0KHBpcGVkLmZpbGUoKS5leGlzdHMoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd3JpdGVTbWFsbENvbnRlbnRXaXRoRXhjZXB0aW9uX3Nob3VsZFByb3BhZ2F0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPQorICAgICAgICB1cmlUb05ld1RlbXBGaWxlKCkuYnVpbGQoKS5idWlsZFVwb24oKS5lbmNvZGVkRnJhZ21lbnQoInRyYW5zZm9ybT1hbHdheXN0aHJvd3MiKS5idWlsZCgpOworICAgIFdyaXRlRmlsZU9wZW5lci5GaWxlQ2xvc2VyIHBpcGVkID0KKyAgICAgICAgc3RvcmFnZS5vcGVuKAorICAgICAgICAgICAgdXJpLCBXcml0ZUZpbGVPcGVuZXIuY3JlYXRlKCkud2l0aEZhbGxiYWNrVG9QaXBlVXNpbmdFeGVjdXRvcihleGVjdXRvciwgY29udGV4dCkpOworICAgIC8vIFNtYWxsIGNvbnRlbnQgaXMgYnVmZmVyZWQgYW5kIHB1bXAgZmFpbHVyZSBpcyBpcyBub3QgdmlzaWJsZS4KKyAgICB3cml0ZUZpbGVUb1NpbmsobmV3IEZpbGVPdXRwdXRTdHJlYW0ocGlwZWQuZmlsZSgpKSwgc21hbGxDb250ZW50KTsKKyAgICAvLyBUaHJvd3MgdW5kZXJseWluZyBleGNlcHRpb24gd2hlbiBjbG9zaW5nLgorICAgIGFzc2VydFRocm93cyhJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gcGlwZWQuY2xvc2UoKSk7CisgICAgYXNzZXJ0VGhhdChwaXBlZC5maWxlKCkuZXhpc3RzKCkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHdyaXRlVG9QbGFpbkZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdXJpVG9OZXdUZW1wRmlsZSgpLmJ1aWxkKCk7IC8vIE5vIHRyYW5zZm9ybXMuCisgICAgdHJ5IChXcml0ZUZpbGVPcGVuZXIuRmlsZUNsb3NlciBkaXJlY3QgPQorICAgICAgICBzdG9yYWdlLm9wZW4oCisgICAgICAgICAgICB1cmksIFdyaXRlRmlsZU9wZW5lci5jcmVhdGUoKS53aXRoRmFsbGJhY2tUb1BpcGVVc2luZ0V4ZWN1dG9yKGV4ZWN1dG9yLCBjb250ZXh0KSkpIHsKKyAgICAgIGFzc2VydFRoYXQoZGlyZWN0LmZpbGUoKS5nZXRBYnNvbHV0ZVBhdGgoKSkuc3RhcnRzV2l0aCh0bXBGb2xkZXIuZ2V0Um9vdCgpLnRvU3RyaW5nKCkpOworICAgICAgd3JpdGVGaWxlVG9TaW5rKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGRpcmVjdC5maWxlKCkpLCBiaWdDb250ZW50KTsKKyAgICAgIGFzc2VydFRoYXQocmVhZEZpbGVGcm9tU291cmNlKHN0b3JhZ2Uub3Blbih1cmksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSkKKyAgICAgICAgICAuaXNFcXVhbFRvKGJpZ0NvbnRlbnQpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHdyaXRlVG9QbGFpbkZpbGVfc2hvdWxkTm90UHJlbWF0dXJlbHlDbG9zZVN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIE5vIHRyYW5zZm9ybXMsIHdyaXRlIHRvIHN0dWIgdGVzdCBiYWNrZW5kCisgICAgc3RvcmFnZSA9IG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEltbXV0YWJsZUxpc3Qub2YobmV3IEJ1ZmZlcmluZ0JhY2tlbmQoKSkpOworICAgIEZpbGUgZmlsZSA9IHRtcEZvbGRlci5uZXdGaWxlKCk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiYnVmZmVyOi8vLyIgKyBmaWxlLmdldEFic29sdXRlUGF0aCgpKTsKKworICAgIHRyeSAoV3JpdGVGaWxlT3BlbmVyLkZpbGVDbG9zZXIgZGlyZWN0ID0gc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVGaWxlT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgd3JpdGVGaWxlVG9TaW5rKG5ldyBGaWxlT3V0cHV0U3RyZWFtKGRpcmVjdC5maWxlKCkpLCBiaWdDb250ZW50KTsKKyAgICB9CisgICAgYXNzZXJ0VGhhdChyZWFkRmlsZUZyb21Tb3VyY2UobmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSkpLmlzRXF1YWxUbyhiaWdDb250ZW50KTsKKyAgfQorCisgIHByaXZhdGUgRmlsZVVyaS5CdWlsZGVyIHVyaVRvTmV3VGVtcEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICByZXR1cm4gRmlsZVVyaS5idWlsZGVyKCkuZnJvbUZpbGUodG1wRm9sZGVyLm5ld0ZpbGUoKSk7CisgIH0KKworICAvKiogQSBiYWNrZW5kIHRoYXQgdXNlcyB0ZW1wb3JhcnkgZmlsZXMgdG8gYnVmZmVyIElPIG9wZXJhdGlvbnMuICovCisgIHByaXZhdGUgc3RhdGljIGNsYXNzIEJ1ZmZlcmluZ0JhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHsKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgU3RyaW5nIG5hbWUoKSB7CisgICAgICByZXR1cm4gImJ1ZmZlciI7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIE91dHB1dFN0cmVhbSBvcGVuRm9yV3JpdGUoVXJpIHVyaSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICAgIEZpbGUgdGVtcEZpbGUgPSBuZXcgRmlsZSh1cmkuZ2V0UGF0aCgpICsgIi50bXAiKTsKKyAgICAgIEZpbGUgZmluYWxGaWxlID0gbmV3IEZpbGUodXJpLmdldFBhdGgoKSk7CisgICAgICByZXR1cm4gbmV3IEJ1ZmZlcmluZ091dHB1dFN0cmVhbShuZXcgRmlsZU91dHB1dFN0cmVhbSh0ZW1wRmlsZSksIHRlbXBGaWxlLCBmaW5hbEZpbGUpOworICAgIH0KKworICAgIHByaXZhdGUgc3RhdGljIGNsYXNzIEJ1ZmZlcmluZ091dHB1dFN0cmVhbSBleHRlbmRzIEZvcndhcmRpbmdPdXRwdXRTdHJlYW0KKyAgICAgICAgaW1wbGVtZW50cyBGaWxlQ29udmVydGlibGUgeworICAgICAgcHJpdmF0ZSBmaW5hbCBGaWxlIHRlbXBGaWxlOworICAgICAgcHJpdmF0ZSBmaW5hbCBGaWxlIGZpbmFsRmlsZTsKKworICAgICAgQnVmZmVyaW5nT3V0cHV0U3RyZWFtKE91dHB1dFN0cmVhbSBzdHJlYW0sIEZpbGUgdGVtcEZpbGUsIEZpbGUgZmluYWxGaWxlKSB7CisgICAgICAgIHN1cGVyKHN0cmVhbSk7CisgICAgICAgIHRoaXMudGVtcEZpbGUgPSB0ZW1wRmlsZTsKKyAgICAgICAgdGhpcy5maW5hbEZpbGUgPSBmaW5hbEZpbGU7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIEZpbGUgdG9GaWxlKCkgeworICAgICAgICByZXR1cm4gdGVtcEZpbGU7CisgICAgICB9CisKKyAgICAgIEBPdmVycmlkZQorICAgICAgcHVibGljIHZvaWQgY2xvc2UoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBvdXQuY2xvc2UoKTsKKyAgICAgICAgdGVtcEZpbGUucmVuYW1lVG8oZmluYWxGaWxlKTsKKyAgICAgIH0KKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvV3JpdGVQcm90b09wZW5lclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvV3JpdGVQcm90b09wZW5lclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOTUwZDJlCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9Xcml0ZVByb3RvT3BlbmVyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTE1IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmVoYXZpb3JzLlN5bmNpbmdCZWhhdmlvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLkZha2VGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXMuQ29tcHJlc3NUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5zdG9yYWdlLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVzdE1lc3NhZ2VQcm90by5Gb29Qcm90bzsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm1vY2tpdG8uTW9ja2l0bzsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgV3JpdGVQcm90b09wZW5lclRlc3QgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZvb1Byb3RvIFRFU1RfUFJPVE8gPQorICAgICAgRm9vUHJvdG8ubmV3QnVpbGRlcigpCisgICAgICAgICAgLnNldFRleHQoImFsbCB3b3JrIGFuZCBubyBwbGF5IG1ha2VzIGphY2sgYSBkdWxsIGJveSBhbGwgd29yayBhbmQgbm8gcGxheSBtYWtlcyBqYWNrIGEiKQorICAgICAgICAgIC5zZXRCb29sZWFuKHRydWUpCisgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisgIHByaXZhdGUgZmluYWwgRmFrZUZpbGVCYWNrZW5kIGJhY2tlbmQgPSBuZXcgRmFrZUZpbGVCYWNrZW5kKCk7CisKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeVVyaSB0bXBVcmkgPSBuZXcgVGVtcG9yYXJ5VXJpKCk7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcFN0b3JhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9yYWdlID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoQXJyYXlzLmFzTGlzdChiYWNrZW5kKSwgQXJyYXlzLmFzTGlzdChuZXcgQ29tcHJlc3NUcmFuc2Zvcm0oKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd3JpdGVzUHJvdG8oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlUHJvdG9PcGVuZXIuY3JlYXRlKFRFU1RfUFJPVE8pKTsKKworICAgIEZvb1Byb3RvIGFjdHVhbCA9IHN0b3JhZ2Uub3Blbih1cmksIFJlYWRQcm90b09wZW5lci5jcmVhdGUoRm9vUHJvdG8ucGFyc2VyKCkpKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbCkuaXNFcXVhbFRvKFRFU1RfUFJPVE8pOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd3JpdGVzUHJvdG9fd2l0aFRyYW5zZm9ybSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCkuYnVpbGRVcG9uKCkuZW5jb2RlZEZyYWdtZW50KCJ0cmFuc2Zvcm09Y29tcHJlc3MiKS5idWlsZCgpOworICAgIHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlUHJvdG9PcGVuZXIuY3JlYXRlKFRFU1RfUFJPVE8pKTsKKworICAgIEZvb1Byb3RvIGFjdHVhbCA9IHN0b3JhZ2Uub3Blbih1cmksIFJlYWRQcm90b09wZW5lci5jcmVhdGUoRm9vUHJvdG8ucGFyc2VyKCkpKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbCkuaXNFcXVhbFRvKFRFU1RfUFJPVE8pOworICAgIGFzc2VydFRoYXQoc3RvcmFnZS5maWxlU2l6ZSh1cmkpKS5pc0xlc3NUaGFuKFRFU1RfUFJPVE8uZ2V0U2VyaWFsaXplZFNpemUoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBmYWlsZWRXcml0ZV9ub0NoYW5nZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpKCk7CisgICAgc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVQcm90b09wZW5lci5jcmVhdGUoVEVTVF9QUk9UTykpOworCisgICAgRm9vUHJvdG8gbW9kaWZpZWRQcm90byA9IFRFU1RfUFJPVE8udG9CdWlsZGVyKCkuc2V0Qm9vbGVhbihmYWxzZSkuYnVpbGQoKTsKKyAgICBJT0V4Y2VwdGlvbiBleHBlY3RlZCA9IG5ldyBJT0V4Y2VwdGlvbigiZXhwZWN0ZWQiKTsKKyAgICBiYWNrZW5kLnNldEZhaWx1cmUoRmFrZUZpbGVCYWNrZW5kLk9wZXJhdGlvblR5cGUuV1JJVEVfU1RSRUFNLCBleHBlY3RlZCk7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVByb3RvT3BlbmVyLmNyZWF0ZShtb2RpZmllZFByb3RvKSkpOworCisgICAgRm9vUHJvdG8gYWN0dWFsID0gc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFByb3RvT3BlbmVyLmNyZWF0ZShGb29Qcm90by5wYXJzZXIoKSkpOworICAgIGFzc2VydFRoYXQoYWN0dWFsKS5pc0VxdWFsVG8oVEVTVF9QUk9UTyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBmYWlsZWRSZW5hbWVfbm9DaGFuZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpOworICAgIHN0b3JhZ2Uub3Blbih1cmksIFdyaXRlUHJvdG9PcGVuZXIuY3JlYXRlKFRFU1RfUFJPVE8pKTsKKworICAgIEZvb1Byb3RvIG1vZGlmaWVkUHJvdG8gPSBURVNUX1BST1RPLnRvQnVpbGRlcigpLnNldEJvb2xlYW4oZmFsc2UpLmJ1aWxkKCk7CisgICAgSU9FeGNlcHRpb24gZXhwZWN0ZWQgPSBuZXcgSU9FeGNlcHRpb24oImV4cGVjdGVkIik7CisgICAgYmFja2VuZC5zZXRGYWlsdXJlKEZha2VGaWxlQmFja2VuZC5PcGVyYXRpb25UeXBlLk1BTkFHRSwgZXhwZWN0ZWQpOworCisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVQcm90b09wZW5lci5jcmVhdGUobW9kaWZpZWRQcm90bykpKTsKKworICAgIEZvb1Byb3RvIGFjdHVhbCA9IHN0b3JhZ2Uub3Blbih1cmksIFJlYWRQcm90b09wZW5lci5jcmVhdGUoRm9vUHJvdG8ucGFyc2VyKCkpKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbCkuaXNFcXVhbFRvKFRFU1RfUFJPVE8pOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW52b2tlc19hdXRvU3luYygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkxID0gdG1wVXJpLm5ld1VyaSgpOworICAgIFN5bmNpbmdCZWhhdmlvciBzeW5jaW5nID0gTW9ja2l0by5zcHkobmV3IFN5bmNpbmdCZWhhdmlvcigpKTsKKyAgICBzdG9yYWdlLm9wZW4odXJpMSwgV3JpdGVQcm90b09wZW5lci5jcmVhdGUoVEVTVF9QUk9UTykud2l0aEJlaGF2aW9ycyhzeW5jaW5nKSk7CisgICAgTW9ja2l0by52ZXJpZnkoc3luY2luZykuc3luYygpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL2hlbGxvMW5hdGl2ZS5jYyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvaGVsbG8xbmF0aXZlLmNjCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZjYmU3YmMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzL2hlbGxvMW5hdGl2ZS5jYwpAQCAtMCwwICsxLDI0IEBACisvLyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisvLworLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisvLyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisvLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKy8vCisvLyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorLy8KKy8vIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKy8vIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisvLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKy8vIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKy8vIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorI2luY2x1ZGUgPGpuaS5oPgorCituYW1lc3BhY2UgeworCitleHRlcm4gIkMiIEpOSUVYUE9SVCBqc3RyaW5nIEpOSUNBTEwKK0phdmFfY29tX2dvb2dsZV9hbmRyb2lkX2xpYnJhcmllc19zdG9yYWdlX2ZpbGVfb3BlbmVyc19IZWxsb05hdGl2ZV9zYXlIZWxsbygKKyAgICBKTklFbnYqIGVudikgeworICByZXR1cm4gZW52LT5OZXdTdHJpbmdVVEYoImhlbGxvMSIpOworfQorCit9ICAvLyBuYW1lc3BhY2UKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvaGVsbG8ybmF0aXZlLmNjIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVycy9oZWxsbzJuYXRpdmUuY2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmUyMmI3MgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnMvaGVsbG8ybmF0aXZlLmNjCkBAIC0wLDAgKzEsMjQgQEAKKy8vIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKy8vCisvLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKy8vIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKy8vIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorLy8KKy8vICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisvLworLy8gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorLy8gZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKy8vIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorLy8gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisjaW5jbHVkZSA8am5pLmg+CisKK25hbWVzcGFjZSB7CisKK2V4dGVybiAiQyIgSk5JRVhQT1JUIGpzdHJpbmcgSk5JQ0FMTAorSmF2YV9jb21fZ29vZ2xlX2FuZHJvaWRfbGlicmFyaWVzX3N0b3JhZ2VfZmlsZV9vcGVuZXJzX0hlbGxvTmF0aXZlX3NheUhlbGxvKAorICAgIEpOSUVudiogZW52KSB7CisgIHJldHVybiBlbnYtPk5ld1N0cmluZ1VURigiaGVsbG8yIik7Cit9CisKK30gIC8vIG5hbWVzcGFjZQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcy9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NhbXBsZXMvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTY1MjM1NgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NhbXBsZXMvQlVJTEQKQEAgLTAsMCArMSwzNyBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbG9jYWxfdGVzdCIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWyIvLzpfX3N1YnBhY2thZ2VzX18iXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIlNhbXBsZXNUZXN0IiwKKyAgICBzaXplID0gInNtYWxsIiwKKyAgICBzcmNzID0gWyJTYW1wbGVzVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6ZmlsZV9hZGFwdGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOnN0cmVhbSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zYW1wbGVzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6Y29tcHJlc3MiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcy9TYW1wbGVzVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcy9TYW1wbGVzVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwODczNGUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zYW1wbGVzL1NhbXBsZXNUZXN0LmphdmEKQEAgLTAsMCArMSwxMTkgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc2FtcGxlczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLmNyZWF0ZUZpbGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMucmVhZEZpbGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0cy5VVEZfODsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkLnRleHQuVGV4dFV0aWxzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkZpbGVVcmlBZGFwdGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuSmF2YUZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLlNpemFibGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5UZW1wb3JhcnlVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLlJlYWRTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLkNvbXByZXNzVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0Lkxpc3RzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmlvLkJhc2VFbmNvZGluZzsKK2ltcG9ydCBjb20uZ29vZ2xlLnRoaXJkcGFydHkucm9ib2xlY3RyaWMuR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbVJlYWRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKKworQFJ1bldpdGgoR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIFNhbXBsZXNUZXN0IHsKKyAgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworICBCeXRlQ291bnRpbmdNb25pdG9yIGJ5dGVDb3VudGVyOworCisgIEBSdWxlIHB1YmxpYyBUZW1wb3JhcnlVcmkgdG1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0dXBGaWxlU3RvcmFnZSgpIHsKKyAgICBieXRlQ291bnRlciA9IG5ldyBCeXRlQ291bnRpbmdNb25pdG9yKCk7CisgICAgc3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihuZXcgSmF2YUZpbGVCYWNrZW5kKCksIG5ldyBCYXNlNjRCYWNrZW5kKCkpLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgICAgICBuZXcgQmFzZTY0VHJhbnNmb3JtKCksIG5ldyBDYXBpdGFsaXphdGlvblRyYW5zZm9ybSgpLCBuZXcgQ29tcHJlc3NUcmFuc2Zvcm0oKSksCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKGJ5dGVDb3VudGVyKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjYXBpdGFsaXplQW5kQmFzZTY0U2hvdWxkUm91bmRUcmlwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9IHRtcFVyaS5uZXdVcmkoKS5idWlsZFVwb24oKS5lbmNvZGVkRnJhZ21lbnQoInRyYW5zZm9ybT1jYXBpdGFsaXplK2Jhc2U2NCIpLmJ1aWxkKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksICJTT01FIEFMTCBDQVBTIFRFWFQiKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlKHN0b3JhZ2UsIHVyaSkpLmlzRXF1YWxUbygiU09NRSBBTEwgQ0FQUyBURVhUIik7CisKKyAgICAvLyBDaGVjayByYXcgZmlsZSBhbmQgbWFudWFsbHkgZGVjb2RlZCByZXN1bHQuCisgICAgTGlzdDxTdHJpbmc+IHBhdGggPSBMaXN0cy5uZXdBcnJheUxpc3QodXJpLmdldFBhdGhTZWdtZW50cygpKTsKKyAgICBTdHJpbmcgZmlsZW5hbWUgPSBwYXRoLmdldChwYXRoLnNpemUoKSAtIDEpOworICAgIGZpbGVuYW1lID0gZmlsZW5hbWUudG9Mb3dlckNhc2UoKTsgLy8gY2FwaXRhbGl6ZQorICAgIGZpbGVuYW1lID0gQmFzZUVuY29kaW5nLmJhc2U2NCgpLmVuY29kZShmaWxlbmFtZS5nZXRCeXRlcyhVVEZfOCkpOyAvLyBiYXNlNjQKKyAgICBwYXRoLnNldChwYXRoLnNpemUoKSAtIDEsIGZpbGVuYW1lKTsKKyAgICBVcmkgZW5jb2RlZFVyaSA9IHVyaS5idWlsZFVwb24oKS5wYXRoKFRleHRVdGlscy5qb2luKCIvIiwgcGF0aCkpLmJ1aWxkKCk7CisgICAgRmlsZSBlbmNvZGVkRmlsZSA9IEZpbGVVcmlBZGFwdGVyLmluc3RhbmNlKCkudG9GaWxlKGVuY29kZWRVcmkpOworICAgIEJ1ZmZlcmVkUmVhZGVyIHJhd1JlYWRlciA9CisgICAgICAgIG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIobmV3IEZpbGVJbnB1dFN0cmVhbShlbmNvZGVkRmlsZSksIFVURl84KSk7CisgICAgU3RyaW5nIGVuY29kZWRUZXh0ID0gcmF3UmVhZGVyLnJlYWRMaW5lKCk7CisgICAgYXNzZXJ0VGhhdChlbmNvZGVkVGV4dCkuaXNFcXVhbFRvKCJjMjl0WlNCaGJHd2dZMkZ3Y3lCMFpYaDAiKTsKKyAgICBTdHJpbmcgbG93ZXJjYXNlVGV4dCA9IG5ldyBTdHJpbmcoQmFzZUVuY29kaW5nLmJhc2U2NCgpLmRlY29kZShlbmNvZGVkVGV4dCksIFVURl84KTsKKyAgICBhc3NlcnRUaGF0KGxvd2VyY2FzZVRleHQpLmlzRXF1YWxUbygic29tZSBhbGwgY2FwcyB0ZXh0Iik7CisgICAgcmF3UmVhZGVyLmNsb3NlKCk7CisKKyAgICBhc3NlcnRUaGF0KGJ5dGVDb3VudGVyLnN0YXRzKCkpCisgICAgICAgIC5pc0VxdWFsVG8obmV3IGxvbmdbXSB7ZW5jb2RlZFRleHQubGVuZ3RoKCksIGVuY29kZWRUZXh0Lmxlbmd0aCgpfSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjYXBpdGFsaXplQW5kQmFzZTY0QW5kQ29tcHJlc3NTaG91bGRSb3VuZFRyaXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0KKyAgICAgICAgdG1wVXJpLm5ld1VyaSgpLmJ1aWxkVXBvbigpLmVuY29kZWRGcmFnbWVudCgidHJhbnNmb3JtPWNhcGl0YWxpemUrYmFzZTY0K2NvbXByZXNzIikuYnVpbGQoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgIlNPTUUgQUxMIENBUFMgVEVYVCIpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGUoc3RvcmFnZSwgdXJpKSkuaXNFcXVhbFRvKCJTT01FIEFMTCBDQVBTIFRFWFQiKTsKKyAgICBhc3NlcnRUaGF0KGJ5dGVDb3VudGVyLnN0YXRzKCkpLmlzRXF1YWxUbyhuZXcgbG9uZ1tdIHszMiwgMzJ9KTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJhc2U2NEJhY2tlbmRTaG91bGRSb3VuZFRyaXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpLmJ1aWxkVXBvbigpLnNjaGVtZSgiYmFzZTY0IikuYnVpbGQoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgIlNPTUUgQUxMIENBUFMgVEVYVCIpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGUoc3RvcmFnZSwgdXJpKSkuaXNFcXVhbFRvKCJTT01FIEFMTCBDQVBTIFRFWFQiKTsKKyAgICBhc3NlcnRUaGF0KGJ5dGVDb3VudGVyLnN0YXRzKCkpCisgICAgICAgIC5pc0VxdWFsVG8obmV3IGxvbmdbXSB7IlNPTUUgQUxMIENBUFMgVEVYVCIubGVuZ3RoKCksICJTT01FIEFMTCBDQVBTIFRFWFQiLmxlbmd0aCgpfSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjYXBpdGFsaXphdGlvblRyYW5zZm9ybV9zaG91bGRCZVNpemFibGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaSgpLmJ1aWxkVXBvbigpLmVuY29kZWRGcmFnbWVudCgidHJhbnNmb3JtPWNhcGl0YWxpemUiKS5idWlsZCgpOworICAgIFN0cmluZyB0ZXh0ID0gIlNPTUUgQUxMIENBUFMgVEVYVCI7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIHRleHQpOworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgYXNzZXJ0VGhhdChpbiBpbnN0YW5jZW9mIFNpemFibGUpLmlzVHJ1ZSgpOworICAgICAgYXNzZXJ0VGhhdCgoKFNpemFibGUpIGluKS5zaXplKCkpLmlzRXF1YWxUbyh0ZXh0Lmxlbmd0aCgpKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvQlVJTEQgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiNjZlNzEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL0JVSUxECkBAIC0wLDAgKzEsOTggQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIkBidWlsZF9iYXplbF9ydWxlc19hbmRyb2lkLy9hbmRyb2lkOnJ1bGVzLmJ6bCIsICJhbmRyb2lkX2xpYnJhcnkiLCAiYW5kcm9pZF9sb2NhbF90ZXN0IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiQnVmZmVyVHJhbnNmb3JtVGVzdCIsCisgICAgc2l6ZSA9ICJzbWFsbCIsCisgICAgc3JjcyA9IFsiQnVmZmVyVHJhbnNmb3JtVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvb3BlbmVyczpzdHJlYW0iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6YnVmZmVyIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiQ29tcHJlc3NUcmFuc2Zvcm1UZXN0IiwKKyAgICBzaXplID0gInNtYWxsIiwKKyAgICBzcmNzID0gWyJDb21wcmVzc1RyYW5zZm9ybVRlc3QuamF2YSJdLAorICAgIGRhdGEgPSBbCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvdGVzdGRhdGE6Z29sZGVuLmRlZmxhdGUiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc2FtcGxlcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOmNvbXByZXNzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6cHJvdG8iLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3J1bmZpbGVzIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiSW50ZWdyaXR5VHJhbnNmb3JtVGVzdCIsCisgICAgc2l6ZSA9ICJzbWFsbCIsCisgICAgc3JjcyA9IFsiSW50ZWdyaXR5VHJhbnNmb3JtVGVzdC5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmVoYXZpb3JzOmNvbXB1dGVfdXJpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbi90ZXN0aW5nIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyZWFtIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOmludGVncml0eSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOnByb3RvIiwKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIlRyYW5zZm9ybVByb3Rvc1Rlc3QiLAorICAgIHNpemUgPSAic21hbGwiLAorICAgIHNyY3MgPSBbIlRyYW5zZm9ybVByb3Rvc1Rlc3QuamF2YSJdLAorICAgIG1hbmlmZXN0ID0gIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGU6QW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjphbmRyb2lkX2xpYnJhcnlfcHJvdG9fZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zOnByb3RvIiwKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAY29tX2dvb2dsZV9wcm90b2J1Zi8vOnBhcnNlcnMiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJhbmRyb2lkX2xpYnJhcnlfcHJvdG9fZGF0YSIsCisgICAgbWFuaWZlc3QgPSAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZTpBbmRyb2lkTWFuaWZlc3QueG1sIiwKKyAgICByZXNvdXJjZV9maWxlcyA9IFsiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL3Rlc3RkYXRhOnRyYW5zZm9ybXMucGIiXSwKKykKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvQnVmZmVyVHJhbnNmb3JtVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy9CdWZmZXJUcmFuc2Zvcm1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGU2MDhiYgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvQnVmZmVyVHJhbnNmb3JtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTYwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5jcmVhdGVGaWxlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLnJlYWRGaWxlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHMuVVRGXzg7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuYW55OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLndoZW47CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuSmF2YUZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVtcG9yYXJ5VXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5Xcml0ZVN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5CYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLlRyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CitpbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm1vY2tpdG8uTW9jazsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvSlVuaXQ7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b1J1bGU7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIEJ1ZmZlclRyYW5zZm9ybVRlc3QgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBQTEFJTlRFWFQgPSAiVGhpcyBpcyBzb21lIHJlZ3VsYXIgb2xkIHBsYWludGV4dCBBQkMgMTIzICFAI1xuIjsKKworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5VXJpIHRtcFVyaSA9IG5ldyBUZW1wb3JhcnlVcmkoKTsKKyAgQFJ1bGUgcHVibGljIGZpbmFsIE1vY2tpdG9SdWxlIG1vY2tzID0gTW9ja2l0b0pVbml0LnJ1bGUoKTsKKworICBATW9jayBCYWNrZW5kIG1vY2tCYWNrZW5kOworCisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBzdG9yYWdlOworICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgbW9ja2VkU3RvcmFnZTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwU3RvcmFnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IEphdmFGaWxlQmFja2VuZCgpKSwgSW1tdXRhYmxlTGlzdC5vZihuZXcgQnVmZmVyVHJhbnNmb3JtKCkpKTsKKworICAgIHdoZW4obW9ja0JhY2tlbmQubmFtZSgpKS50aGVuUmV0dXJuKCJmaWxlIik7CisgICAgbW9ja2VkU3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihtb2NrQmFja2VuZCksIEltbXV0YWJsZUxpc3Qub2YobmV3IEJ1ZmZlclRyYW5zZm9ybSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBuYW1lX2lzQnVmZmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVHJhbnNmb3JtIHRyYW5zZm9ybSA9IG5ldyBCdWZmZXJUcmFuc2Zvcm0oKTsKKyAgICBhc3NlcnRUaGF0KHRyYW5zZm9ybS5uYW1lKCkpLmlzRXF1YWxUbygiYnVmZmVyIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB3cml0ZVRoZW5SZWFkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9CisgICAgICAgIHRtcFVyaS5uZXdVcmlCdWlsZGVyKCkuYnVpbGQoKS5idWlsZFVwb24oKS5lbmNvZGVkRnJhZ21lbnQoInRyYW5zZm9ybT1idWZmZXIiKS5idWlsZCgpOworCisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIFBMQUlOVEVYVCk7CisKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlKHN0b3JhZ2UsIHVyaSkpLmlzRXF1YWxUbyhQTEFJTlRFWFQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcGFyYW1faGFzRGVmYXVsdEJ1ZmZlclNpemUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0KKyAgICAgICAgdG1wVXJpLm5ld1VyaUJ1aWxkZXIoKS5idWlsZCgpLmJ1aWxkVXBvbigpLmVuY29kZWRGcmFnbWVudCgidHJhbnNmb3JtPWJ1ZmZlciIpLmJ1aWxkKCk7CisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhY2tlbmRPdXRwdXRTdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgd2hlbihtb2NrQmFja2VuZC5vcGVuRm9yV3JpdGUoYW55KFVyaS5jbGFzcykpKS50aGVuUmV0dXJuKGJhY2tlbmRPdXRwdXRTdHJlYW0pOworCisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtID0gbW9ja2VkU3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICBvdXRwdXRTdHJlYW0ud3JpdGUobmV3IGJ5dGVbODE5MV0pOworICAgICAgb3V0cHV0U3RyZWFtLndyaXRlKG5ldyBieXRlWzJdKTsKKworICAgICAgYXNzZXJ0VGhhdChiYWNrZW5kT3V0cHV0U3RyZWFtLnNpemUoKSkuaXNFcXVhbFRvKDgxOTEpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHBhcmFtX2NvbnRyb2xzQnVmZmVyU2l6ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPQorICAgICAgICB0bXBVcmkKKyAgICAgICAgICAgIC5uZXdVcmlCdWlsZGVyKCkKKyAgICAgICAgICAgIC5idWlsZCgpCisgICAgICAgICAgICAuYnVpbGRVcG9uKCkKKyAgICAgICAgICAgIC5lbmNvZGVkRnJhZ21lbnQoInRyYW5zZm9ybT1idWZmZXIoc2l6ZT0xMDApIikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYWNrZW5kT3V0cHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIHdoZW4obW9ja0JhY2tlbmQub3BlbkZvcldyaXRlKGFueShVcmkuY2xhc3MpKSkudGhlblJldHVybihiYWNrZW5kT3V0cHV0U3RyZWFtKTsKKworICAgIHRyeSAoT3V0cHV0U3RyZWFtIG91dHB1dFN0cmVhbSA9IG1vY2tlZFN0b3JhZ2Uub3Blbih1cmksIFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSkgeworICAgICAgb3V0cHV0U3RyZWFtLndyaXRlKG5ldyBieXRlWzk5XSk7CisgICAgICBvdXRwdXRTdHJlYW0ud3JpdGUobmV3IGJ5dGVbMl0pOworCisgICAgICBhc3NlcnRUaGF0KGJhY2tlbmRPdXRwdXRTdHJlYW0uc2l6ZSgpKS5pc0VxdWFsVG8oOTkpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHdyaXRlX2J1ZmZlcnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0KKyAgICAgICAgdG1wVXJpLm5ld1VyaUJ1aWxkZXIoKS5idWlsZCgpLmJ1aWxkVXBvbigpLmVuY29kZWRGcmFnbWVudCgidHJhbnNmb3JtPWJ1ZmZlciIpLmJ1aWxkKCk7CisgICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhY2tlbmRPdXRwdXRTdHJlYW0gPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CisgICAgd2hlbihtb2NrQmFja2VuZC5vcGVuRm9yV3JpdGUoYW55KFVyaS5jbGFzcykpKS50aGVuUmV0dXJuKGJhY2tlbmRPdXRwdXRTdHJlYW0pOworICAgIGJ5dGVbXSBleHBlY3RlZEJ1ZmZlciA9IG5ldyBieXRlWzgxOTJdOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgODsgaSsrKSB7CisgICAgICBleHBlY3RlZEJ1ZmZlcltpICogMTAyNF0gPSAoYnl0ZSkgaTsKKyAgICB9CisKKyAgICB0cnkgKE91dHB1dFN0cmVhbSBvdXRwdXRTdHJlYW0gPSBtb2NrZWRTdG9yYWdlLm9wZW4odXJpLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKSkpIHsKKyAgICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlWzEwMjRdOworICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspIHsKKyAgICAgICAgYnl0ZXNbMF0gPSAoYnl0ZSkgaTsKKyAgICAgICAgb3V0cHV0U3RyZWFtLndyaXRlKGJ5dGVzKTsKKyAgICAgICAgYXNzZXJ0VGhhdChiYWNrZW5kT3V0cHV0U3RyZWFtLnNpemUoKSkuaXNFcXVhbFRvKDApOworICAgICAgfQorICAgICAgb3V0cHV0U3RyZWFtLmZsdXNoKCk7CisKKyAgICAgIGFzc2VydFRoYXQoYmFja2VuZE91dHB1dFN0cmVhbS5zaXplKCkpLmlzRXF1YWxUbyg4MTkyKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBmbHVzaF9lbXB0aWVzQnVmZmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVXJpIHVyaSA9CisgICAgICAgIHRtcFVyaS5uZXdVcmlCdWlsZGVyKCkuYnVpbGQoKS5idWlsZFVwb24oKS5lbmNvZGVkRnJhZ21lbnQoInRyYW5zZm9ybT1idWZmZXIiKS5idWlsZCgpOworICAgIEJ5dGVBcnJheU91dHB1dFN0cmVhbSBiYWNrZW5kT3V0cHV0U3RyZWFtID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOworICAgIHdoZW4obW9ja0JhY2tlbmQub3BlbkZvcldyaXRlKGFueShVcmkuY2xhc3MpKSkudGhlblJldHVybihiYWNrZW5kT3V0cHV0U3RyZWFtKTsKKyAgICBieXRlW10gZXhwZWN0ZWRCdWZmZXIgPSBuZXcgYnl0ZVs4MTkyXTsKKyAgICBTeXN0ZW0uYXJyYXljb3B5KFBMQUlOVEVYVC5nZXRCeXRlcyhVVEZfOCksIDAsIGV4cGVjdGVkQnVmZmVyLCAwLCBQTEFJTlRFWFQubGVuZ3RoKCkpOworCisgICAgdHJ5IChPdXRwdXRTdHJlYW0gb3V0cHV0U3RyZWFtID0gbW9ja2VkU3RvcmFnZS5vcGVuKHVyaSwgV3JpdGVTdHJlYW1PcGVuZXIuY3JlYXRlKCkpKSB7CisgICAgICBvdXRwdXRTdHJlYW0ud3JpdGUoUExBSU5URVhULmdldEJ5dGVzKFVURl84KSk7CisgICAgICBhc3NlcnRUaGF0KGJhY2tlbmRPdXRwdXRTdHJlYW0uc2l6ZSgpKS5pc0VxdWFsVG8oMCk7CisgICAgICBvdXRwdXRTdHJlYW0uZmx1c2goKTsKKyAgICAgIGFzc2VydFRoYXQoYmFja2VuZE91dHB1dFN0cmVhbS5zaXplKCkpLmlzRXF1YWxUbyhQTEFJTlRFWFQubGVuZ3RoKCkpOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy9Db21wcmVzc1RyYW5zZm9ybVRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvQ29tcHJlc3NUcmFuc2Zvcm1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWY2ZTIwMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvQ29tcHJlc3NUcmFuc2Zvcm1UZXN0LmphdmEKQEAgLTAsMCArMSwxMTYgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUudHJhbnNmb3JtczsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLmNyZWF0ZUZpbGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuU3RyZWFtVXRpbHMucmVhZEZpbGU7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuRmlsZVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkphdmFGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlRlbXBvcmFyeVVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNhbXBsZXMuQnl0ZUNvdW50aW5nTW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLkpvaW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5kZXZ0b29scy5idWlsZC5ydW50aW1lLlJ1bmZpbGVzOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIENvbXByZXNzVHJhbnNmb3JtVGVzdCB7CisKKyAgcHJpdmF0ZSBCeXRlQ291bnRpbmdNb25pdG9yIGJ5dGVDb3VudGVyOworICBwcml2YXRlIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2Ugc3RvcmFnZTsKKworICBAUnVsZSBwdWJsaWMgVGVtcG9yYXJ5VXJpIHRtcFVyaSA9IG5ldyBUZW1wb3JhcnlVcmkoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldHVwRmlsZVN0b3JhZ2UoKSB7CisgICAgYnl0ZUNvdW50ZXIgPSBuZXcgQnl0ZUNvdW50aW5nTW9uaXRvcigpOworICAgIHN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IEphdmFGaWxlQmFja2VuZCgpKSwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IENvbXByZXNzVHJhbnNmb3JtKCkpLAorICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihieXRlQ291bnRlcikpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY291bnRlcldpdGhDb21wcmVzcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB1cmkgPSB0bXBVcmkubmV3VXJpQnVpbGRlcigpLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfQ09NUFJFU1NfU1BFQykuYnVpbGQoKTsKKyAgICBTdHJpbmcgdGV4dCA9ICJjb21wcmVzcyBtZSEiOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgdXJpLCB0ZXh0KTsKKyAgICBhc3NlcnRUaGF0KGJ5dGVDb3VudGVyLnN0YXRzKCkpLmlzRXF1YWxUbyhuZXcgbG9uZ1tdIHswLCAyMH0pOworICAgIGludCByYXRpbyA9IHRleHQubGVuZ3RoKCkgLyAyMDsKKyAgICBhc3NlcnRUaGF0KHJhdGlvKS5pc0VxdWFsVG8oMCk7CisKKyAgICByZWFkRmlsZShzdG9yYWdlLCB1cmkpOworICAgIGFzc2VydFRoYXQoYnl0ZUNvdW50ZXIuc3RhdHMoKSkuaXNFcXVhbFRvKG5ldyBsb25nW10gezIwLCAyMH0pOworCisgICAgdGV4dCA9IEpvaW5lci5vbigiXG4iKS5qb2luKENvbGxlY3Rpb25zLm5Db3BpZXMoMTAsIHRleHQpKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaSwgdGV4dCk7CisgICAgYXNzZXJ0VGhhdChieXRlQ291bnRlci5zdGF0cygpKS5pc0VxdWFsVG8obmV3IGxvbmdbXSB7MjAsIDQ0fSk7CisgICAgcmF0aW8gPSB0ZXh0Lmxlbmd0aCgpIC8gKDQ0IC0gMjApOworICAgIGFzc2VydFRoYXQocmF0aW8pLmlzRXF1YWxUbyg1KTsKKworICAgIHRleHQgPSBKb2luZXIub24oIlxuIikuam9pbihDb2xsZWN0aW9ucy5uQ29waWVzKDEwLCB0ZXh0KSk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmksIHRleHQpOworICAgIGFzc2VydFRoYXQoYnl0ZUNvdW50ZXIuc3RhdHMoKSkuaXNFcXVhbFRvKG5ldyBsb25nW10gezIwLCA3Nn0pOworICAgIHJhdGlvID0gdGV4dC5sZW5ndGgoKSAvICg3NiAtIDQ0KTsKKyAgICBhc3NlcnRUaGF0KHJhdGlvKS5pc0VxdWFsVG8oNDApOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY29tcHJlc3NHb2xkZW5GaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQXJiaXRyYXJ5IGRhdGEuCisgICAgU3RyaW5nIHRvV3JpdGUgPSAiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSI7CisKKyAgICBGaWxlVXJpLkJ1aWxkZXIgYnVpbGRlciA9IHRtcFVyaS5uZXdVcmlCdWlsZGVyKCk7CisgICAgVXJpIHVyaVdpdGhvdXRUcmFuc2Zvcm0gPSBidWlsZGVyLmJ1aWxkKCk7CisgICAgVXJpIHVyaVdpdGhUcmFuc2Zvcm0gPSBidWlsZGVyLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfQ09NUFJFU1NfU1BFQykuYnVpbGQoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVyaVdpdGhUcmFuc2Zvcm0sIHRvV3JpdGUpOworCisgICAgLy8gUmVhZCBiYWNrIHJhdyBieXRlcy4KKyAgICBTdHJpbmcgZmlsZUNvbnRlbnRzID0gcmVhZEZpbGUoc3RvcmFnZSwgdXJpV2l0aG91dFRyYW5zZm9ybSk7CisKKyAgICAvLyBVcGxvYWQgdGhlIHJlc3VsdCB0byBTcG9uZ2UgZm9yIGVhc3kgdXBkYXRpbmcuCisgICAgRmlsZSB1bmRlY2xhcmVkT3V0cHV0RGlyID0gZ2V0RGVmYXVsdFVuZGVjbGFyZWRPdXRwdXREaXIoKTsKKyAgICBGaWxlVXJpLkJ1aWxkZXIgc3BvbmdlQnVpbGRlciA9IEZpbGVVcmkuYnVpbGRlcigpOworICAgIHNwb25nZUJ1aWxkZXIuZnJvbUZpbGUodW5kZWNsYXJlZE91dHB1dERpcikuYXBwZW5kUGF0aCgiZ29sZGVuLmRlZmxhdGUiKTsKKyAgICBVcmkgdW5kZWNsYXJlZE91dHB1dFVyaSA9IHNwb25nZUJ1aWxkZXIuYnVpbGQoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIHVuZGVjbGFyZWRPdXRwdXRVcmksIGZpbGVDb250ZW50cyk7CisKKyAgICAvLyBDaGVjayBkYXRhIGFnYWluc3QgZ29sZGVuIGZpbGUuCisgICAgRmlsZSBnb2xkZW5GaWxlID0KKyAgICAgICAgUnVuZmlsZXMubG9jYXRpb24oCisgICAgICAgICAgICAidGhpcmRfcGFydHkvamF2YV9zcmMvYW5kcm9pZF9saWJzL21vYmlsZWRhdGFkb3dubG9hZC9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL3Rlc3RkYXRhL2dvbGRlbi5kZWZsYXRlIik7CisgICAgVXJpIGdvbGRlblVyaSA9IEZpbGVVcmkuZnJvbUZpbGUoZ29sZGVuRmlsZSk7CisgICAgYXNzZXJ0VGhhdChmaWxlQ29udGVudHMpLmlzRXF1YWxUbyhyZWFkRmlsZShzdG9yYWdlLCBnb2xkZW5VcmkpKTsKKyAgfQorCisgIC8vIENvcGllZCBmcm9tIFVuZGVjbGFyZWRPdXRwdXRzLmphdmEgLSB3ZSBjYW4ndCB1c2UgaXQgZGlyZWN0bHkgZHVlIHRvIGEgcHJvdG8gZGVwZW5kZW5jeQorICAvLyBjb25mbGljdC4KKyAgcHJpdmF0ZSBzdGF0aWMgRmlsZSBnZXREZWZhdWx0VW5kZWNsYXJlZE91dHB1dERpcigpIHsKKyAgICBTdHJpbmcgZGlyID0gU3lzdGVtLmdldGVudigiVEVTVF9VTkRFQ0xBUkVEX09VVFBVVFNfRElSIik7CisgICAgcmV0dXJuIG5ldyBGaWxlKGRpcik7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvSW50ZWdyaXR5VHJhbnNmb3JtVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy9JbnRlZ3JpdHlUcmFuc2Zvcm1UZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTQ2M2E1MwotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvSW50ZWdyaXR5VHJhbnNmb3JtVGVzdC5qYXZhCkBAIC0wLDAgKzEsMjUwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnRyYW5zZm9ybXM7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5TdHJlYW1VdGlscy5jcmVhdGVGaWxlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmNvbW1vbi50ZXN0aW5nLlN0cmVhbVV0aWxzLnJlYWRGaWxlOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBqYXZhLm5pby5jaGFyc2V0LlN0YW5kYXJkQ2hhcnNldHMuVVRGXzg7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkZpbGVVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5KYXZhRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iZWhhdmlvcnMuVXJpQ29tcHV0aW5nQmVoYXZpb3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5jb21tb24udGVzdGluZy5UZW1wb3JhcnlVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLkFwcGVuZFN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuUmVhZFN0cmVhbU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLm9wZW5lcnMuV3JpdGVTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5CeXRlU3RyZWFtczsKK2ltcG9ydCBjb20uZ29vZ2xlLnRoaXJkcGFydHkucm9ib2xlY3RyaWMuR29vZ2xlUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbVdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLldyaXRlcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5GdXR1cmU7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CisKK0BSdW5XaXRoKEdvb2dsZVJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBJbnRlZ3JpdHlUcmFuc2Zvcm1UZXN0IHsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1JJR1RFWFQgPSAiVGhpcyBpcyBzb21lIHJlZ3VsYXIgb2xkIHRleHQgQUJDIDEyMyAhQCMiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1JJR1RFWFRfU0hBMjU2X0I2NCA9ICJGb1IxSHJ4ZEFoWTA1REUvZ0FVajB5anB6WXBmV2IwZkpFK1hCcDhsWTBvPSI7CisKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeVVyaSB0bXBVcmkgPSBuZXcgVGVtcG9yYXJ5VXJpKCk7CisKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcFN0b3JhZ2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzdG9yYWdlID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKG5ldyBKYXZhRmlsZUJhY2tlbmQoKSksIEltbXV0YWJsZUxpc3Qub2YobmV3IEludGVncml0eVRyYW5zZm9ybSgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBuYW1lX2lzSW50ZWdyaXR5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVHJhbnNmb3JtIHRyYW5zZm9ybSA9IG5ldyBJbnRlZ3JpdHlUcmFuc2Zvcm0oKTsKKyAgICBhc3NlcnRUaGF0KHRyYW5zZm9ybS5uYW1lKCkpLmlzRXF1YWxUbygiaW50ZWdyaXR5Iik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB3cml0ZV9zaG91bGRDb21wdXRlQ2hlY2tzdW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBVcmkgdXJpID0gdG1wVXJpLm5ld1VyaUJ1aWxkZXIoKS53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0lOVEVHUklUWV9TUEVDKS5idWlsZCgpOworICAgIEZ1dHVyZTxVcmk+IHVyaUZ1dHVyZTsKKyAgICBVcmlDb21wdXRpbmdCZWhhdmlvciBjb21wdXRlVXJpID0gbmV3IFVyaUNvbXB1dGluZ0JlaGF2aW9yKHVyaSk7CisgICAgdHJ5IChPdXRwdXRTdHJlYW0gc2luayA9CisgICAgICAgICAgICBzdG9yYWdlLm9wZW4odXJpLCBXcml0ZVN0cmVhbU9wZW5lci5jcmVhdGUoKS53aXRoQmVoYXZpb3JzKGNvbXB1dGVVcmkpKTsKKyAgICAgICAgV3JpdGVyIHdyaXRlciA9IG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoc2luaywgVVRGXzgpKSB7CisgICAgICB3cml0ZXIud3JpdGUoT1JJR1RFWFQpOworICAgICAgdXJpRnV0dXJlID0gY29tcHV0ZVVyaS51cmlGdXR1cmUoKTsKKyAgICB9CisKKyAgICBVcmkgdXJpV2l0aEhhc2ggPSB1cmlGdXR1cmUuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KEludGVncml0eVRyYW5zZm9ybS5nZXREaWdlc3RJZlByZXNlbnQodXJpV2l0aEhhc2gpKS5pc0VxdWFsVG8oT1JJR1RFWFRfU0hBMjU2X0I2NCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjb25zdW1lU3RyZWFtX3Nob3VsZENvbXB1dGVDaGVja3N1bSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGVVcmkuQnVpbGRlciBidWlsZGVyID0gdG1wVXJpLm5ld1VyaUJ1aWxkZXIoKTsKKyAgICBjcmVhdGVGaWxlKHN0b3JhZ2UsIGJ1aWxkZXIuYnVpbGQoKSwgT1JJR1RFWFQpOworICAgIFVyaSB1cmkgPSBidWlsZGVyLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfSU5URUdSSVRZX1NQRUMpLmJ1aWxkKCk7CisKKyAgICBVcmlDb21wdXRpbmdCZWhhdmlvciBjb21wdXRlVXJpID0gbmV3IFVyaUNvbXB1dGluZ0JlaGF2aW9yKHVyaSk7CisgICAgRnV0dXJlPFVyaT4gdXJpRnV0dXJlOworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLndpdGhCZWhhdmlvcnMoY29tcHV0ZVVyaSkpKSB7CisgICAgICBCeXRlU3RyZWFtcy5leGhhdXN0KGluKTsKKyAgICAgIHVyaUZ1dHVyZSA9IGNvbXB1dGVVcmkudXJpRnV0dXJlKCk7CisgICAgfQorCisgICAgYXNzZXJ0VGhhdChJbnRlZ3JpdHlUcmFuc2Zvcm0uZ2V0RGlnZXN0SWZQcmVzZW50KHVyaUZ1dHVyZS5nZXQoKSkpCisgICAgICAgIC5pc0VxdWFsVG8oT1JJR1RFWFRfU0hBMjU2X0I2NCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjb25zdW1lU3RyZWFtX3Nob3VsZEJvdGhWZXJpZnlBbmRDb21wdXRlQ2hlY2tzdW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlVXJpLkJ1aWxkZXIgYnVpbGRlciA9IHRtcFVyaS5uZXdVcmlCdWlsZGVyKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCBidWlsZGVyLmJ1aWxkKCksIE9SSUdURVhUKTsKKyAgICBVcmkgdXJpID0gYnVpbGRlci53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0lOVEVHUklUWV9TUEVDKS5idWlsZCgpOworCisgICAgVXJpQ29tcHV0aW5nQmVoYXZpb3IgY29tcHV0ZVVyaSA9IG5ldyBVcmlDb21wdXRpbmdCZWhhdmlvcih1cmkpOworICAgIEZ1dHVyZTxVcmk+IHVyaUZ1dHVyZTsKKyAgICB0cnkgKElucHV0U3RyZWFtIGluID0gc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKS53aXRoQmVoYXZpb3JzKGNvbXB1dGVVcmkpKSkgeworICAgICAgQnl0ZVN0cmVhbXMuZXhoYXVzdChpbik7CisgICAgICB1cmlGdXR1cmUgPSBjb21wdXRlVXJpLnVyaUZ1dHVyZSgpOworICAgIH0KKworICAgIGFzc2VydFRoYXQoSW50ZWdyaXR5VHJhbnNmb3JtLmdldERpZ2VzdElmUHJlc2VudCh1cmlGdXR1cmUuZ2V0KCkpKQorICAgICAgICAuaXNFcXVhbFRvKE9SSUdURVhUX1NIQTI1Nl9CNjQpOworCisgICAgLy8gVHJ5IGFnYWluLCB1c2luZyB0aGUgdXJpV2l0aEhhc2ggYXMgaW5wdXQsIHNvIHRoYXQgaGFzaCBpcyB2ZXJpZmllZCBhbmQgY29tcHV0ZWQKKyAgICAvLyBzaW11bHRhbmVvdXNseS4KKyAgICBVcmlDb21wdXRpbmdCZWhhdmlvciBjb21wdXRlVXJpMiA9IG5ldyBVcmlDb21wdXRpbmdCZWhhdmlvcih1cmlGdXR1cmUuZ2V0KCkpOworICAgIEZ1dHVyZTxVcmk+IHVyaUZ1dHVyZTI7CisgICAgdHJ5IChJbnB1dFN0cmVhbSBpbiA9CisgICAgICAgIHN0b3JhZ2Uub3Blbih1cmlGdXR1cmUuZ2V0KCksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkud2l0aEJlaGF2aW9ycyhjb21wdXRlVXJpMikpKSB7CisgICAgICBCeXRlU3RyZWFtcy5leGhhdXN0KGluKTsKKyAgICAgIHVyaUZ1dHVyZTIgPSBjb21wdXRlVXJpMi51cmlGdXR1cmUoKTsKKyAgICB9CisKKyAgICBhc3NlcnRUaGF0KEludGVncml0eVRyYW5zZm9ybS5nZXREaWdlc3RJZlByZXNlbnQodXJpRnV0dXJlMi5nZXQoKSkpCisgICAgICAgIC5pc0VxdWFsVG8oT1JJR1RFWFRfU0hBMjU2X0I2NCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZWFkRnVsbHlfc2hvdWxkQ29tcHV0ZUNoZWNrc3VtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQnVmZmVyIGlzIGV4YWN0IGxlbmd0aCwgZG9lcyBub3QgcmVhY2ggRU9GLiBEZXBlbmRzIG9uIGNsb3NlKCkgdG8gY29tcHV0ZSBjaGVja3N1bS4KKyAgICBGaWxlVXJpLkJ1aWxkZXIgYnVpbGRlciA9IHRtcFVyaS5uZXdVcmlCdWlsZGVyKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCBidWlsZGVyLmJ1aWxkKCksIE9SSUdURVhUKTsKKyAgICBVcmkgdXJpID0gYnVpbGRlci53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0lOVEVHUklUWV9TUEVDKS5idWlsZCgpOworCisgICAgRnV0dXJlPFVyaT4gcmVzdWx0OworICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtPUklHVEVYVC5sZW5ndGgoKV07CisgICAgVXJpQ29tcHV0aW5nQmVoYXZpb3IgY29tcHV0ZVVyaSA9IG5ldyBVcmlDb21wdXRpbmdCZWhhdmlvcih1cmkpOworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW5wdXQgPQorICAgICAgICBzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLndpdGhCZWhhdmlvcnMoY29tcHV0ZVVyaSkpKSB7CisgICAgICBCeXRlU3RyZWFtcy5yZWFkRnVsbHkoaW5wdXQsIGJ1ZmZlcik7CisgICAgICByZXN1bHQgPSBjb21wdXRlVXJpLnVyaUZ1dHVyZSgpOworICAgIH0KKworICAgIGFzc2VydFRoYXQoYnVmZmVyKS5pc0VxdWFsVG8oT1JJR1RFWFQuZ2V0Qnl0ZXMoIlVURi04IikpOworICAgIGFzc2VydFRoYXQoSW50ZWdyaXR5VHJhbnNmb3JtLmdldERpZ2VzdElmUHJlc2VudChyZXN1bHQuZ2V0KCkpKS5pc0VxdWFsVG8oT1JJR1RFWFRfU0hBMjU2X0I2NCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZWFkV2l0aFdpdGhQcmVtYXR1cmVDbG9zZV9zaG91bGRDb21wdXRlRGlmZmVyZW50Q2hlY2tzdW0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUaGlzIGJlaGF2aW9yIGlzIG5vdCBuZWNlc3NhcmlseSB1c2VmdWwsIGJ1dCBpcyBoZXJlIHRvIGJlIGRvY3VtZW50ZWQuCisgICAgRmlsZVVyaS5CdWlsZGVyIGJ1aWxkZXIgPSB0bXBVcmkubmV3VXJpQnVpbGRlcigpOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgYnVpbGRlci5idWlsZCgpLCBPUklHVEVYVCk7CisgICAgVXJpIHVyaSA9IGJ1aWxkZXIud2l0aFRyYW5zZm9ybShUcmFuc2Zvcm1Qcm90b3MuREVGQVVMVF9JTlRFR1JJVFlfU1BFQykuYnVpbGQoKTsKKworICAgIGJ5dGVbXSBidWZmZXIgPSBuZXcgYnl0ZVtPUklHVEVYVC5sZW5ndGgoKSAtIDFdOyAvLyBGdWxsIGxlbmd0aCAtIDEuCisgICAgRnV0dXJlPFVyaT4gcmVzdWx0OworICAgIFVyaUNvbXB1dGluZ0JlaGF2aW9yIGNvbXB1dGVVcmkgPSBuZXcgVXJpQ29tcHV0aW5nQmVoYXZpb3IodXJpKTsKKyAgICB0cnkgKElucHV0U3RyZWFtIGlucHV0ID0KKyAgICAgICAgc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKS53aXRoQmVoYXZpb3JzKGNvbXB1dGVVcmkpKSkgeworICAgICAgQnl0ZVN0cmVhbXMucmVhZEZ1bGx5KGlucHV0LCBidWZmZXIpOworICAgICAgcmVzdWx0ID0gY29tcHV0ZVVyaS51cmlGdXR1cmUoKTsKKyAgICB9CisKKyAgICBhc3NlcnRUaGF0KGJ1ZmZlcikuaXNOb3RFcXVhbFRvKE9SSUdURVhULmdldEJ5dGVzKCJVVEYtOCIpKTsKKyAgICBhc3NlcnRUaGF0KEludGVncml0eVRyYW5zZm9ybS5nZXREaWdlc3RJZlByZXNlbnQocmVzdWx0LmdldCgpKSkKKyAgICAgICAgLmlzTm90RXF1YWxUbyhPUklHVEVYVF9TSEEyNTZfQjY0KTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlYWRfc2hvdWxkVmFsaWRhdGVDaGVja3N1bSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGVVcmkuQnVpbGRlciBidWlsZGVyID0gdG1wVXJpLm5ld1VyaUJ1aWxkZXIoKTsKKyAgICBVcmkgdXJpV2l0aG91dFRyYW5zZm9ybSA9IGJ1aWxkZXIuYnVpbGQoKTsKKyAgICBVcmkgdXJpID0gYnVpbGRlci53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0lOVEVHUklUWV9TUEVDKS5idWlsZCgpOworICAgIGNyZWF0ZUZpbGUoc3RvcmFnZSwgdXJpV2l0aG91dFRyYW5zZm9ybSwgT1JJR1RFWFQpOworCisgICAgRnV0dXJlPFVyaT4gdXJpRnV0dXJlOworICAgIFVyaUNvbXB1dGluZ0JlaGF2aW9yIGNvbXB1dGVVcmkgPSBuZXcgVXJpQ29tcHV0aW5nQmVoYXZpb3IodXJpKTsKKyAgICB0cnkgKElucHV0U3RyZWFtIGluID0gc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKS53aXRoQmVoYXZpb3JzKGNvbXB1dGVVcmkpKSkgeworICAgICAgQnl0ZVN0cmVhbXMuZXhoYXVzdChpbik7CisgICAgICB1cmlGdXR1cmUgPSBjb21wdXRlVXJpLnVyaUZ1dHVyZSgpOworICAgIH0KKworICAgIGFzc2VydFRoYXQoSW50ZWdyaXR5VHJhbnNmb3JtLmdldERpZ2VzdElmUHJlc2VudCh1cmlGdXR1cmUuZ2V0KCkpKQorICAgICAgICAuaXNFcXVhbFRvKE9SSUdURVhUX1NIQTI1Nl9CNjQpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGUoc3RvcmFnZSwgdXJpKSkuaXNFcXVhbFRvKE9SSUdURVhUKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlKHN0b3JhZ2UsIHVyaUZ1dHVyZS5nZXQoKSkpLmlzRXF1YWxUbyhPUklHVEVYVCk7CisKKyAgICB0cnkgKFdyaXRlciB3cml0ZXIgPQorICAgICAgICBuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKAorICAgICAgICAgICAgc3RvcmFnZS5vcGVuKHVyaVdpdGhvdXRUcmFuc2Zvcm0sIEFwcGVuZFN0cmVhbU9wZW5lci5jcmVhdGUoKSksIFVURl84KSkgeworICAgICAgd3JpdGVyLndyaXRlKCJwd25lZCIpOworICAgIH0KKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlKHN0b3JhZ2UsIHVyaSkpLmVuZHNXaXRoKCJwd25lZCIpOworICAgIGFzc2VydFRocm93cyhJT0V4Y2VwdGlvbi5jbGFzcywgKCkgLT4gcmVhZEZpbGUoc3RvcmFnZSwgdXJpRnV0dXJlLmdldCgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZWFkX3Nob3VsZFZhbGlkYXRlQ2hlY2tzdW1XaXRoUmVhZGluZ09uZUJ5dGVBdEFUaW1lKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRmlsZVVyaS5CdWlsZGVyIGJ1aWxkZXIgPSB0bXBVcmkubmV3VXJpQnVpbGRlcigpOworICAgIFVyaSB1cmlXaXRob3V0VHJhbnNmb3JtID0gYnVpbGRlci5idWlsZCgpOworICAgIFVyaSB1cmkgPSBidWlsZGVyLndpdGhUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG9zLkRFRkFVTFRfSU5URUdSSVRZX1NQRUMpLmJ1aWxkKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCB1cmlXaXRob3V0VHJhbnNmb3JtLCBPUklHVEVYVCk7CisKKyAgICBGdXR1cmU8VXJpPiB1cmlGdXR1cmU7CisgICAgVXJpQ29tcHV0aW5nQmVoYXZpb3IgY29tcHV0ZVVyaSA9IG5ldyBVcmlDb21wdXRpbmdCZWhhdmlvcih1cmkpOworICAgIHRyeSAoSW5wdXRTdHJlYW0gaW4gPSBzdG9yYWdlLm9wZW4odXJpLCBSZWFkU3RyZWFtT3BlbmVyLmNyZWF0ZSgpLndpdGhCZWhhdmlvcnMoY29tcHV0ZVVyaSkpKSB7CisgICAgICBCeXRlU3RyZWFtcy5leGhhdXN0KGluKTsKKyAgICAgIHVyaUZ1dHVyZSA9IGNvbXB1dGVVcmkudXJpRnV0dXJlKCk7CisgICAgfQorICAgIHRyeSAoV3JpdGVyIHdyaXRlciA9CisgICAgICAgIG5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIoCisgICAgICAgICAgICBzdG9yYWdlLm9wZW4odXJpV2l0aG91dFRyYW5zZm9ybSwgQXBwZW5kU3RyZWFtT3BlbmVyLmNyZWF0ZSgpKSwgVVRGXzgpKSB7CisgICAgICB3cml0ZXIud3JpdGUoInB3bmVkIik7CisgICAgfQorCisgICAgYXNzZXJ0VGhyb3dzKElPRXhjZXB0aW9uLmNsYXNzLCAoKSAtPiByZWFkRmlsZShzdG9yYWdlLCB1cmlGdXR1cmUuZ2V0KCkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHBhcnRpYWxSZWFkQW5kQ2xvc2Vfc2hvdWxkRmFpbFZhbGlkYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlVXJpLkJ1aWxkZXIgYnVpbGRlciA9IHRtcFVyaS5uZXdVcmlCdWlsZGVyKCk7CisgICAgY3JlYXRlRmlsZShzdG9yYWdlLCBidWlsZGVyLmJ1aWxkKCksIE9SSUdURVhUKTsKKyAgICBVcmkgdXJpID0gYnVpbGRlci53aXRoVHJhbnNmb3JtKFRyYW5zZm9ybVByb3Rvcy5ERUZBVUxUX0lOVEVHUklUWV9TUEVDKS5idWlsZCgpOworCisgICAgRnV0dXJlPFVyaT4gdXJpRnV0dXJlOworICAgIFVyaUNvbXB1dGluZ0JlaGF2aW9yIGNvbXB1dGVVcmkgPSBuZXcgVXJpQ29tcHV0aW5nQmVoYXZpb3IodXJpKTsKKyAgICB0cnkgKElucHV0U3RyZWFtIGluID0gc3RvcmFnZS5vcGVuKHVyaSwgUmVhZFN0cmVhbU9wZW5lci5jcmVhdGUoKS53aXRoQmVoYXZpb3JzKGNvbXB1dGVVcmkpKSkgeworICAgICAgQnl0ZVN0cmVhbXMuZXhoYXVzdChpbik7CisgICAgICB1cmlGdXR1cmUgPSBjb21wdXRlVXJpLnVyaUZ1dHVyZSgpOworICAgIH0KKworICAgIGFzc2VydFRoYXQoSW50ZWdyaXR5VHJhbnNmb3JtLmdldERpZ2VzdElmUHJlc2VudCh1cmlGdXR1cmUuZ2V0KCkpKQorICAgICAgICAuaXNFcXVhbFRvKE9SSUdURVhUX1NIQTI1Nl9CNjQpOworICAgIGFzc2VydFRoYXQocmVhZEZpbGUoc3RvcmFnZSwgdXJpKSkuaXNFcXVhbFRvKE9SSUdURVhUKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRGaWxlKHN0b3JhZ2UsIHVyaUZ1dHVyZS5nZXQoKSkpLmlzRXF1YWxUbyhPUklHVEVYVCk7CisKKyAgICAvLyBGaWxscyBhIGJ1ZmZlciB3aXRoIGZ1bGwgbGVuZ3RoIC0gMS4KKyAgICBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbT1JJR1RFWFQubGVuZ3RoKCkgLSAxXTsKKyAgICBJbnB1dFN0cmVhbSBpbnB1dCA9IHN0b3JhZ2Uub3Blbih1cmlGdXR1cmUuZ2V0KCksIFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCkpOworICAgIEJ5dGVTdHJlYW1zLnJlYWRGdWxseShpbnB1dCwgYnVmZmVyKTsKKyAgICBhc3NlcnRUaHJvd3MoSU9FeGNlcHRpb24uY2xhc3MsICgpIC0+IGlucHV0LmNsb3NlKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL1RyYW5zZm9ybVByb3Rvc1Rlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvVHJhbnNmb3JtUHJvdG9zVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5ZDVmMDIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL1RyYW5zZm9ybVByb3Rvc1Rlc3QuamF2YQpAQCAtMCwwICsxLDE1NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuVHJhbnNmb3JtUHJvdG87CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5jb250cmliLmFuZHJvaWQuUHJvdG9QYXJzZXJzOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgVHJhbnNmb3JtUHJvdG9zVGVzdCB7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZW1wdHlQcm90b19wcm9kdWNlc0VtcHR5VHJhbnNmb3JtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtcyBlbXB0eVRyYW5zZm9ybXMgPSBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm1zLmdldERlZmF1bHRJbnN0YW5jZSgpOworICAgIFN0cmluZyBmcmFnbWVudCA9IFRyYW5zZm9ybVByb3Rvcy50b0VuY29kZWRGcmFnbWVudChlbXB0eVRyYW5zZm9ybXMpOworICAgIGFzc2VydFRoYXQoZnJhZ21lbnQpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBVcmkucGFyc2UoImh0dHA6Ly9mb28uYmFyI3RyYW5zZm9ybT1mb28iKQorICAgICAgICAgICAgICAgIC5idWlsZFVwb24oKQorICAgICAgICAgICAgICAgIC5lbmNvZGVkRnJhZ21lbnQoZnJhZ21lbnQpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkKKyAgICAgICAgICAgICAgICAudG9TdHJpbmcoKSkKKyAgICAgICAgLmlzRXF1YWxUbygiaHR0cDovL2Zvby5iYXIiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1pc3NpbmdUcmFuc2Zvcm1fdGhyb3dzRXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtcyBpbnZhbGlkVHJhbnNmb3JtID0KKyAgICAgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRUcmFuc2Zvcm0oVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gVHJhbnNmb3JtUHJvdG9zLnRvRW5jb2RlZEZyYWdtZW50KGludmFsaWRUcmFuc2Zvcm0pKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNvbXByZXNzUHJvdG9fcHJvZHVjZXNDb21wcmVzc1RyYW5zZm9ybSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybXMgdHJhbnNmb3Jtc1Byb3RvID0KKyAgICAgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRUcmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q29tcHJlc3MoVHJhbnNmb3JtUHJvdG8uQ29tcHJlc3NUcmFuc2Zvcm0uZ2V0RGVmYXVsdEluc3RhbmNlKCkpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgU3RyaW5nIGZyYWdtZW50ID0gVHJhbnNmb3JtUHJvdG9zLnRvRW5jb2RlZEZyYWdtZW50KHRyYW5zZm9ybXNQcm90byk7CisgICAgYXNzZXJ0VGhhdChmcmFnbWVudCkuaXNFcXVhbFRvKCJ0cmFuc2Zvcm09Y29tcHJlc3MiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGVuY3J5cHRQcm90b19wcm9kdWNlc0VuY3J5cHRUcmFuc2Zvcm0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm1zIHRyYW5zZm9ybXNQcm90byA9CisgICAgICAgIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEVuY3J5cHQoVHJhbnNmb3JtUHJvdG8uRW5jcnlwdFRyYW5zZm9ybS5nZXREZWZhdWx0SW5zdGFuY2UoKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBTdHJpbmcgZnJhZ21lbnQgPSBUcmFuc2Zvcm1Qcm90b3MudG9FbmNvZGVkRnJhZ21lbnQodHJhbnNmb3Jtc1Byb3RvKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50KS5pc0VxdWFsVG8oInRyYW5zZm9ybT1lbmNyeXB0Iik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbnRlZ3JpdHlQcm90b19wcm9kdWNlc0ludGVncml0eVRyYW5zZm9ybSgpIHRocm93cyBFeGNlcHRpb24geworICAgIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybXMgdHJhbnNmb3Jtc1Byb3RvID0KKyAgICAgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRUcmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0SW50ZWdyaXR5KFRyYW5zZm9ybVByb3RvLkludGVncml0eVRyYW5zZm9ybS5nZXREZWZhdWx0SW5zdGFuY2UoKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBTdHJpbmcgZnJhZ21lbnQgPSBUcmFuc2Zvcm1Qcm90b3MudG9FbmNvZGVkRnJhZ21lbnQodHJhbnNmb3Jtc1Byb3RvKTsKKyAgICBhc3NlcnRUaGF0KGZyYWdtZW50KS5pc0VxdWFsVG8oInRyYW5zZm9ybT1pbnRlZ3JpdHkiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHppcFByb3RvX3Byb2R1Y2VzWmlwVHJhbnNmb3JtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtcyB0cmFuc2Zvcm1zUHJvdG8gPQorICAgICAgICBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm1zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZFRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRaaXAoVHJhbnNmb3JtUHJvdG8uWmlwVHJhbnNmb3JtLm5ld0J1aWxkZXIoKS5zZXRUYXJnZXQoImFiYyIpKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFN0cmluZyBmcmFnbWVudCA9IFRyYW5zZm9ybVByb3Rvcy50b0VuY29kZWRGcmFnbWVudCh0cmFuc2Zvcm1zUHJvdG8pOworICAgIGFzc2VydFRoYXQoZnJhZ21lbnQpLmlzRXF1YWxUbygidHJhbnNmb3JtPXppcCh0YXJnZXQ9YWJjKSIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY3VzdG9tUHJvdG9fcHJvZHVjZXNDdXN0b21UcmFuc2Zvcm0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm1zIHRyYW5zZm9ybXNQcm90byA9CisgICAgICAgIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgIFRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEN1c3RvbSgKKyAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybVByb3RvLkN1c3RvbVRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0TmFtZSgiY3VzdG9tIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQWxsU3VicGFyYW0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1Qcm90by5DdXN0b21UcmFuc2Zvcm0uU3ViUGFyYW0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldEtleSgia2V5MSIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFZhbHVlKCJ2YWx1ZTEiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3JtUHJvdG8uQ3VzdG9tVHJhbnNmb3JtLlN1YlBhcmFtLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRLZXkoImtleTIiKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRWYWx1ZSgiPT8hIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkpKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFN0cmluZyBmcmFnbWVudCA9IFRyYW5zZm9ybVByb3Rvcy50b0VuY29kZWRGcmFnbWVudCh0cmFuc2Zvcm1zUHJvdG8pOworICAgIGFzc2VydFRoYXQoZnJhZ21lbnQpLmlzRXF1YWxUbygidHJhbnNmb3JtPWN1c3RvbShrZXkxPXZhbHVlMSxrZXkyPSUzRCUzRiUyMSkiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRleHRQcm90b19wcm9kdWNlc011bHRpVHJhbnNmb3JtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtcyB0cmFuc2Zvcm1zUHJvdG8gPSBnZXRUcmFuc2Zvcm1zRnJvbVRleHRQcm90bygpOworICAgIFN0cmluZyBmcmFnbWVudCA9IFRyYW5zZm9ybVByb3Rvcy50b0VuY29kZWRGcmFnbWVudCh0cmFuc2Zvcm1zUHJvdG8pOworICAgIGFzc2VydFRoYXQoZnJhZ21lbnQpCisgICAgICAgIC5pc0VxdWFsVG8oInRyYW5zZm9ybT1jb21wcmVzcytlbmNyeXB0KGFlc19nY21fa2V5PWElMkJiYykraW50ZWdyaXR5KHNoYTI1Nj1hYiUyQmMpIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjYW5vbmljYWxFeGFtcGxlX2FkZFByb3RvVHJhbnNmb3JtVG9VcmkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBUcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm1zIHRyYW5zZm9ybXNQcm90byA9IGdldFRyYW5zZm9ybXNGcm9tVGV4dFByb3RvKCk7CisgICAgU3RyaW5nIGZyYWdtZW50ID0gVHJhbnNmb3JtUHJvdG9zLnRvRW5jb2RlZEZyYWdtZW50KHRyYW5zZm9ybXNQcm90byk7CisgICAgVXJpIHVyaSA9IFVyaS5wYXJzZSgiZmlsZTovdG1wL2Zvby50eHQiKS5idWlsZFVwb24oKS5lbmNvZGVkRnJhZ21lbnQoZnJhZ21lbnQpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdCh1cmkudG9TdHJpbmcoKSkKKyAgICAgICAgLmlzRXF1YWxUbygKKyAgICAgICAgICAgICJmaWxlOi90bXAvZm9vLnR4dCIKKyAgICAgICAgICAgICAgICArICIjdHJhbnNmb3JtPWNvbXByZXNzK2VuY3J5cHQoYWVzX2djbV9rZXk9YSUyQmJjKStpbnRlZ3JpdHkoc2hhMjU2PWFiJTJCYykiKTsKKyAgfQorCisgIHByaXZhdGUgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtcyBnZXRUcmFuc2Zvcm1zRnJvbVRleHRQcm90bygpIHsKKyAgICByZXR1cm4gUHJvdG9QYXJzZXJzLnBhcnNlRnJvbVJhd1JlcygKKyAgICAgICAgQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKSwKKyAgICAgICAgVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3Jtcy5wYXJzZXIoKSwKKyAgICAgICAgUi5yYXcudHJhbnNmb3Jtc19kYXRhX3BiKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy90ZXN0ZGF0YS9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvdGVzdGRhdGEvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjEzMjZlOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXMvdGVzdGRhdGEvQlVJTEQKQEAgLTAsMCArMSwzNCBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiLy90b29scy9idWlsZF9ydWxlcy90ZXh0X3RvX2JpbmFyeTpkZWYuYnpsIiwgInByb3RvX2RhdGEiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCitleHBvcnRzX2ZpbGVzKFsKKyAgICAjIE5PVEU6IGdlbmVyYXRlZCBieSBDb21wcmVzc1RyYW5zZm9ybVRlc3QjY29tcHJlc3NHb2xkZW5GaWxlCisgICAgImdvbGRlbi5kZWZsYXRlIiwKK10pCisKK3Byb3RvX2RhdGEoCisgICAgbmFtZSA9ICJ0cmFuc2Zvcm1zLnBiIiwKKyAgICBzcmMgPSAidHJhbnNmb3Jtcy5wYi50eHQiLAorICAgIG91dCA9ICJyZXMvcmF3L3RyYW5zZm9ybXNfZGF0YV9wYiIsCisgICAgcHJvdG9fZGVwcyA9IFsKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX3Byb3RvIiwKKyAgICBdLAorICAgIHByb3RvX25hbWUgPSAibW9ic3RvcmUucHJvdG8uVHJhbnNmb3JtcyIsCispCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL3Rlc3RkYXRhL2dvbGRlbi5kZWZsYXRlIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy90ZXN0ZGF0YS9nb2xkZW4uZGVmbGF0ZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNThjYzBkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy90ZXN0ZGF0YS9nb2xkZW4uZGVmbGF0ZQpCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS90cmFuc2Zvcm1zL3Rlc3RkYXRhL3RyYW5zZm9ybXMucGIudHh0IGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy90ZXN0ZGF0YS90cmFuc2Zvcm1zLnBiLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZmRkNTcxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvdHJhbnNmb3Jtcy90ZXN0ZGF0YS90cmFuc2Zvcm1zLnBiLnR4dApAQCAtMCwwICsxLDEzIEBACit0cmFuc2Zvcm0geworICBjb21wcmVzcyB7fQorfQordHJhbnNmb3JtIHsKKyAgZW5jcnlwdCB7CisgICAgYWVzX2djbV9rZXlfYmFzZTY0OiAiYStiYyIKKyAgfQorfQordHJhbnNmb3JtIHsKKyAgaW50ZWdyaXR5IHsKKyAgICBzaGEyNTY6ICJhYitjIgorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvQW5kcm9pZE1hbmlmZXN0LnhtbCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9BbmRyb2lkTWFuaWZlc3QueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyMTQwYzUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvQW5kcm9pZE1hbmlmZXN0LnhtbApAQCAtMCwwICsxLDMxIEBACis8IS0tCisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLS0+Cis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI/PgorPG1hbmlmZXN0IHhtbG5zOmFuZHJvaWQ9Imh0dHA6Ly9zY2hlbWFzLmFuZHJvaWQuY29tL2Fway9yZXMvYW5kcm9pZCIKKyAgICBwYWNrYWdlPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbCI+CisgIDwhLS0gU2V0IG1pblNka1ZlcnNpb24gdG8gMjEgYmVjYXVzZSBhbmRyb2lkLm9zLnN5bWxpbmsgaXMgb25seSBhdmFpbGFibGUgYWZ0ZXIgYXBpIGxldmVsIDIxLiAtLT4KKyAgPHVzZXMtc2RrIGFuZHJvaWQ6bWluU2RrVmVyc2lvbj0iMjEiIGFuZHJvaWQ6dGFyZ2V0U2RrVmVyc2lvbj0iMjkiLz4KKyAgPGFwcGxpY2F0aW9uPgorICAgICAgICA8dXNlcy1saWJyYXJ5IGFuZHJvaWQ6bmFtZT0iYW5kcm9pZC50ZXN0LnJ1bm5lciIgLz4KKworICA8L2FwcGxpY2F0aW9uPgorICAgIDxpbnN0cnVtZW50YXRpb24KKyAgICAgICAgYW5kcm9pZDpuYW1lPSJjb20uZ29vZ2xlLmFuZHJvaWQuYXBwcy5jb21tb24udGVzdGluZy50ZXN0cnVubmVyLkdvb2dsZTNJbnN0cnVtZW50YXRpb25UZXN0UnVubmVyIgorICAgICAgICBhbmRyb2lkOnRhcmdldFBhY2thZ2U9ImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsIiAvPgorPC9tYW5pZmVzdD4KKwpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0JVSUxEIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3MmFiOTEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvQlVJTEQKQEAgLTAsMCArMSwzMzggQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOnRlc3RfZGVmcy5iemwiLCAibWRkX2xvY2FsX3Rlc3QiKQorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIpCitsb2FkKCIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpidWlsZF9kZWZzLmJ6bCIsICJhbmRyb2lkX3Rlc3RfbXVsdGlfYXBpIikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworbWRkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyVGVzdCIsCisgICAgc3JjcyA9IFsiTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlclRlc3QuamF2YSJdLAorICAgIHRlc3RfY2xhc3MgPSAiY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlclRlc3QiLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6TWRkVGVzdFV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGaWxlU291cmNlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpTaWxlbnRGZWVkYmFjayIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6RXhwaXJhdGlvbkhhbmRsZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkZpbGVHcm91cE1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TWRkRXhjZXB0aW9ucyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TWlncmF0aW9ucyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TW9iaWxlRGF0YURvd25sb2FkTWFuYWdlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6U2hhcmVkRmlsZU1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOlNoYXJlZEZpbGVzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2V4cGVyaW1lbnRhdGlvbjpEb3dubG9hZFN0YWdlTWFuYWdlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZXhwZXJpbWVudGF0aW9uOk5vT3BEb3dubG9hZFN0YWdlTWFuYWdlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpFdmVudExvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpGaWxlR3JvdXBTdGF0c0xvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpMb2dnaW5nU3RhdGVTdG9yZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpOZXR3b3JrTG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOk5vT3BMb2dnaW5nU3RhdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6U3RvcmFnZUxvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOkZpbGVHcm91cFV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6U2hhcmVkUHJlZmVyZW5jZXNVdGlsIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6RmFrZVRpbWVTb3VyY2UiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpUZXN0RmxhZ3MiLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86cHJvdG9idWZfbGl0ZSIsCisgICAgICAgICJAbW9ja2l0byIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK21kZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiRGF0YUZpbGVHcm91cFZhbGlkYXRvclRlc3QiLAorICAgIHNyY3MgPSBbIkRhdGFGaWxlR3JvdXBWYWxpZGF0b3JUZXN0LmphdmEiXSwKKyAgICB0ZXN0X2NsYXNzID0gImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLkRhdGFGaWxlR3JvdXBWYWxpZGF0b3JUZXN0IiwKKyAgICBkZXBzID0gWworICAgICAgICAiOk1kZFRlc3RVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpEYXRhRmlsZUdyb3VwVmFsaWRhdG9yIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpNaWdyYXRpb25zIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpUZXN0RmxhZ3MiLAorICAgICAgICAiLy9wcm90bzp0cmFuc2Zvcm1famF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworbWRkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJNaWdyYXRpb25zVGVzdCIsCisgICAgc3JjcyA9IFsiTWlncmF0aW9uc1Rlc3QuamF2YSJdLAorICAgIHRlc3RfY2xhc3MgPSAiY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWlncmF0aW9uc1Rlc3QiLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6U2lsZW50RmVlZGJhY2siLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOk1pZ3JhdGlvbnMiLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCittZGRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkZpbGVHcm91cE1hbmFnZXJUZXN0IiwKKyAgICBzcmNzID0gWyJGaWxlR3JvdXBNYW5hZ2VyVGVzdC5qYXZhIl0sCisgICAgdGVzdF9jbGFzcyA9ICJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5GaWxlR3JvdXBNYW5hZ2VyVGVzdCIsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpNZGRUZXN0VXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6QWNjb3VudFNvdXJjZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6QWdncmVnYXRlRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpEb3dubG9hZEV4Y2VwdGlvbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RmlsZVNvdXJjZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6U2lsZW50RmVlZGJhY2siLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2FjY291bnQ6QWNjb3VudFV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpGaWxlR3JvdXBNYW5hZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpGaWxlR3JvdXBzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOk1kZEV4Y2VwdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOlNoYXJlZEZpbGVNYW5hZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6U2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyOkRvd25sb2FkZXJDYWxsYmFja0ltcGwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXI6TWRkRmlsZURvd25sb2FkZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2V4cGVyaW1lbnRhdGlvbjpEb3dubG9hZFN0YWdlTWFuYWdlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZXhwZXJpbWVudGF0aW9uOk5vT3BEb3dubG9hZFN0YWdlTWFuYWdlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpFdmVudExvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOkRpcmVjdG9yeVV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6RmlsZUdyb3VwVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOkZha2VUaW1lU291cmNlIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6VGVzdEZsYWdzIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86YW55X3Byb3RvIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86cHJvdG9idWZfbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV9wcm90b2J1Zi8vOndyYXBwZXJzX3Byb3RvIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkByb2JvbGVjdHJpYyIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK21kZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiRmlsZUdyb3Vwc01ldGFkYXRhVGVzdCIsCisgICAgc3JjcyA9IFsiRmlsZUdyb3Vwc01ldGFkYXRhVGVzdC5qYXZhIl0sCisgICAgdGVzdF9jbGFzcyA9ICJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5GaWxlR3JvdXBzTWV0YWRhdGFUZXN0IiwKKyAgICBkZXBzID0gWworICAgICAgICAiOk1kZFRlc3RVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpTaWxlbnRGZWVkYmFjayIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczphbmRyb2lkIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpGaWxlR3JvdXBzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOlNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkV2ZW50TG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6RGlyZWN0b3J5VXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpGaWxlR3JvdXBVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOkZpbGVHcm91cHNNZXRhZGF0YVV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6UHJvdG9Db252ZXJzaW9uVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpTaGFyZWRQcmVmZXJlbmNlc1V0aWwiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpGYWtlVGltZVNvdXJjZSIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOlRlc3RGbGFncyIsCisgICAgICAgICIvL3Byb3RvOmRvd25sb2FkX2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCittZGRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIkV4cGlyYXRpb25IYW5kbGVyVGVzdCIsCisgICAgc3JjcyA9IFsiRXhwaXJhdGlvbkhhbmRsZXJUZXN0LmphdmEiXSwKKyAgICB0ZXN0X2NsYXNzID0gImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLkV4cGlyYXRpb25IYW5kbGVyVGVzdCIsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpNZGRUZXN0VXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6U2lsZW50RmVlZGJhY2siLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2RlbHRhOkRlbHRhRGVjb2RlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkV4cGlyYXRpb25IYW5kbGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpGaWxlR3JvdXBzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOk1pZ3JhdGlvbnMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOlNoYXJlZEZpbGVNYW5hZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6U2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyOk1kZEZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkV2ZW50TG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6RGlyZWN0b3J5VXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOkZha2VUaW1lU291cmNlIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6VGVzdEZsYWdzIiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworbWRkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJTaGFyZWRGaWxlTWFuYWdlclRlc3QiLAorICAgIHNyY3MgPSBbIlNoYXJlZEZpbGVNYW5hZ2VyVGVzdC5qYXZhIl0sCisgICAgdGVzdF9jbGFzcyA9ICJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5TaGFyZWRGaWxlTWFuYWdlclRlc3QiLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6TWRkVGVzdFV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpGaWxlU291cmNlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpTaWxlbnRGZWVkYmFjayIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZGVsdGE6RGVsdGFEZWNvZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmFuZHJvaWQiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YmxvYl91cmkiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3RyYW5zZm9ybXM6Y29tcHJlc3MiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TWRkRXhjZXB0aW9ucyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TWlncmF0aW9ucyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6U2hhcmVkRmlsZU1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOlNoYXJlZEZpbGVzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOlNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlcjpEb3dubG9hZGVyQ2FsbGJhY2tJbXBsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9kb3dubG9hZGVyOk1kZEZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkV2ZW50TG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6RGlyZWN0b3J5VXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpGaWxlR3JvdXBVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOlNoYXJlZFByZWZlcmVuY2VzVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOlRlc3RGbGFncyIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAY29tX2dvb2dsZV9wcm90b2J1Zi8vOnByb3RvYnVmX2xpdGUiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCittZGRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIlNoYXJlZEZpbGVzTWV0YWRhdGFUZXN0IiwKKyAgICBzcmNzID0gWyJTaGFyZWRGaWxlc01ldGFkYXRhVGVzdC5qYXZhIl0sCisgICAgdGVzdF9jbGFzcyA9ICJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5TaGFyZWRGaWxlc01ldGFkYXRhVGVzdCIsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpNZGRUZXN0VXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6U2lsZW50RmVlZGJhY2siLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TWlncmF0aW9ucyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6U2hhcmVkRmlsZXNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6U2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkV2ZW50TG9nZ2VyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6U2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6U2hhcmVkUHJlZmVyZW5jZXNVdGlsIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6VGVzdEZsYWdzIiwKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAbW9ja2l0byIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk1kZFRlc3RVdGlsIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgc3JjcyA9IFsiTWRkVGVzdFV0aWwuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6U2hhcmVkRmlsZXNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vcHJvdG86ZG93bmxvYWRfY29uZmlnX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL3Byb3RvOnRyYW5zZm9ybV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfYW5kcm9pZF90ZXN0aW5nLy86dXRpbCIsCisgICAgICAgICJAY29tX2dvb2dsZV9wcm90b2J1Zi8vOnByb3RvYnVmX2xpdGUiLAorICAgICAgICAiQHRydXRoIiwKKyAgICAgICAgIkB1Yl91aWF1dG9tYXRvciIsCisgICAgXSwKKykKKworYW5kcm9pZF90ZXN0X211bHRpX2FwaSgKKyAgICBuYW1lID0gIk1kZElzb2xhdGVkU3RydWN0dXJlc1Rlc3QiLAorICAgIHNpemUgPSAibGFyZ2UiLAorICAgIHNyY3MgPSBbIk1kZElzb2xhdGVkU3RydWN0dXJlc1Rlc3QuamF2YSJdLAorICAgIG1hbmlmZXN0ID0gIkFuZHJvaWRNYW5pZmVzdC54bWwiLAorICAgIG11bHRpZGV4ID0gIm5hdGl2ZSIsCisgICAgdGFyZ2V0X2FwaXMgPSBbCisgICAgICAgICIyMSIsCisgICAgICAgICIyMiIsCisgICAgICAgICIyMyIsCisgICAgICAgICIyNCIsCisgICAgICAgICIyNSIsCisgICAgICAgICIyNiIsCisgICAgICAgICIyNyIsCisgICAgICAgICIyOCIsCisgICAgICAgICIyOSIsCisgICAgXSwKKyAgICBkZXBzID0gWworICAgICAgICAiOk1kZFRlc3RVdGlsIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpBZ2dyZWdhdGVFeGNlcHRpb24iLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpFeHBlcmltZW50YXRpb25Db25maWciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkZsYWdzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpTaWxlbnRGZWVkYmFjayIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvYWNjb3VudDpBY2NvdW50VXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kcyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczphbmRyb2lkIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2NvbW1vbiIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9jb21tb24vdGVzdGluZzpmYWtlX2ZpbGVfYmFja2VuZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9vcGVuZXJzOmJ5dGVzIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6ZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkZpbGVHcm91cE1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOkZpbGVHcm91cHNNZXRhZGF0YSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6TWRkRXhjZXB0aW9ucyIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWw6U2hhcmVkRmlsZU1hbmFnZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOlNoYXJlZEZpbGVzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOlNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbDpTaGFyZWRQcmVmZXJlbmNlc1NoYXJlZEZpbGVzTWV0YWRhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2Rvd25sb2FkZXI6RG93bmxvYWRlckNhbGxiYWNrSW1wbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZG93bmxvYWRlcjpNZGRGaWxlRG93bmxvYWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvZXhwZXJpbWVudGF0aW9uOk5vT3BEb3dubG9hZFN0YWdlTWFuYWdlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvbG9nZ2luZzpFdmVudExvZ2dlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsOkRpcmVjdG9yeVV0aWwiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWw6RmlsZUdyb3VwVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpTeW1saW5rVXRpbCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOkZha2VUaW1lU291cmNlIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6VGVzdEZsYWdzIiwKKyAgICAgICAgIi8vcHJvdG86dHJhbnNmb3JtX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAYW5kcm9pZF9zZGtfbGludXgiLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzphbnlfcHJvdG8iLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzpwcm90b2J1Zl9saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86d3JhcHBlcnNfcHJvdG8iLAorICAgICAgICAiQGp1bml0IiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9EYXRhRmlsZUdyb3VwVmFsaWRhdG9yVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL0RhdGFGaWxlR3JvdXBWYWxpZGF0b3JUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzhlZTgzZAotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9EYXRhRmlsZUdyb3VwVmFsaWRhdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjEzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1pZ3JhdGlvbnMuRmlsZUtleVZlcnNpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5UZXN0RmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5Db21wcmVzc1RyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5FbmNyeXB0VHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLlRyYW5zZm9ybVByb3RvLkludGVncml0eVRyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5aaXBUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5CYXNlRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGUuQW5kcm9pZFNoYXJpbmdDaGVja3N1bVR5cGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZS5BbmRyb2lkU2hhcmluZ1R5cGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZS5DaGVja3N1bVR5cGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwSW50ZXJuYWw7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EZWx0YUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EZWx0YUZpbGUuRGlmZkRlY29kZXI7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Eb3dubG9hZENvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Eb3dubG9hZENvbmRpdGlvbnMuRGV2aWNlTmV0d29ya1BvbGljeTsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCisvKioKKyAqIFVuaXQgdGVzdHMgZm9yIHtAbGluaworICogY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuRGF0YUZpbGVHcm91cFZhbGlkYXRvcn0uCisgKi8KK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBEYXRhRmlsZUdyb3VwVmFsaWRhdG9yVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfR1JPVVAgPSAidGVzdC1ncm91cCI7CisgIHByaXZhdGUgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIGZpbmFsIFRlc3RGbGFncyBmbGFncyA9IG5ldyBUZXN0RmxhZ3MoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworCisgICAgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9jb21wcmVzc2VkRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworICAgIE1pZ3JhdGlvbnMuc2V0TWlncmF0ZWRUb05ld0ZpbGVLZXkoY29udGV4dCwgdHJ1ZSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBmaWxlR3JvdXBCdWlsZGVyID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpLnRvQnVpbGRlcigpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwQnVpbGRlcgorICAgICAgICAgICAgLnNldEZpbGUoCisgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICBmaWxlR3JvdXBCdWlsZGVyLmdldEZpbGUoMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkZWRGaWxlQ2hlY2tzdW0oImRvd25sb2FkY2hlY2tzdW0iKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRUcmFuc2Zvcm1zKAorICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0Q29tcHJlc3MoQ29tcHJlc3NUcmFuc2Zvcm0uZ2V0RGVmYXVsdEluc3RhbmNlKCkpKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cCwgY29udGV4dCwgZmxhZ3MpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX2NvbXByZXNzZWRGaWxlX25vRG93bmxvYWRDaGVja3N1bSgpIHRocm93cyBFeGNlcHRpb24geworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworICAgIE1pZ3JhdGlvbnMuc2V0TWlncmF0ZWRUb05ld0ZpbGVLZXkoY29udGV4dCwgdHJ1ZSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBmaWxlR3JvdXBCdWlsZGVyID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpLnRvQnVpbGRlcigpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwQnVpbGRlcgorICAgICAgICAgICAgLnNldEZpbGUoCisgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICBmaWxlR3JvdXBCdWlsZGVyLmdldEZpbGUoMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLy8gU2V0IHZhbGlkIGRvd25sb2FkIHRyYW5zZm9ybXMgc28gaXQgd29uJ3QgZmFpbCB0cmFuc2Zvcm1zIHZhbGlkYXRpb24KKyAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkVHJhbnNmb3JtcygKKyAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZFRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3JtLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldENvbXByZXNzKENvbXByZXNzVHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKSkpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAsIGNvbnRleHQsIGZsYWdzKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfZW5jcnlwdEZpbGVUcmFuc2Zvcm0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBNaWdyYXRpb25zLnNldE1pZ3JhdGVkVG9OZXdGaWxlS2V5KGNvbnRleHQsIHRydWUpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGZpbGVHcm91cEJ1aWxkZXIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXBCdWlsZGVyCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRUcmFuc2Zvcm1zKAorICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0RW5jcnlwdChFbmNyeXB0VHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKSkpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZGVkRmlsZUNoZWNrc3VtKCJkb3dubG9hZGNoZWNrc3VtIikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cCwgY29udGV4dCwgZmxhZ3MpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX2ludGVncml0eUZpbGVUcmFuc2Zvcm0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBNaWdyYXRpb25zLnNldE1pZ3JhdGVkVG9OZXdGaWxlS2V5KGNvbnRleHQsIHRydWUpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGZpbGVHcm91cEJ1aWxkZXIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXBCdWlsZGVyCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRUcmFuc2Zvcm1zKAorICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0SW50ZWdyaXR5KEludGVncml0eVRyYW5zZm9ybS5nZXREZWZhdWx0SW5zdGFuY2UoKSkpKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bSgiZG93bmxvYWRjaGVja3N1bSIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAsIGNvbnRleHQsIGZsYWdzKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF96aXAoKSB7CisgICAgZmxhZ3MuZW5hYmxlWmlwRm9sZGVyID0gT3B0aW9uYWwub2YodHJ1ZSk7CisgICAgTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBGaWxlS2V5VmVyc2lvbi5VU0VfQ0hFQ0tTVU1fT05MWSk7CisgICAgTWlncmF0aW9ucy5zZXRNaWdyYXRlZFRvTmV3RmlsZUtleShjb250ZXh0LCB0cnVlKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBmaWxlR3JvdXBCdWlsZGVyID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpLnRvQnVpbGRlcigpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwQnVpbGRlcgorICAgICAgICAgICAgLnNldEZpbGUoCisgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICBmaWxlR3JvdXBCdWlsZGVyLmdldEZpbGUoMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkVHJhbnNmb3JtcygKKyAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZFRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3JtLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFppcChaaXBUcmFuc2Zvcm0ubmV3QnVpbGRlcigpLnNldFRhcmdldCgiKiIpLmJ1aWxkKCkpKSkKKyAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkZWRGaWxlQ2hlY2tzdW0oIkRPV05MT0FERURGSUxFQ0hFQ0tTVU0iKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cCwgY29udGV4dCwgZmxhZ3MpKS5pc1RydWUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX3ppcF9mZWF0dXJlT2ZmKCkgeworICAgIGZsYWdzLmVuYWJsZVppcEZvbGRlciA9IE9wdGlvbmFsLm9mKGZhbHNlKTsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBNaWdyYXRpb25zLnNldE1pZ3JhdGVkVG9OZXdGaWxlS2V5KGNvbnRleHQsIHRydWUpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGZpbGVHcm91cEJ1aWxkZXIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXBCdWlsZGVyCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRUcmFuc2Zvcm1zKAorICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0WmlwKFppcFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkuc2V0VGFyZ2V0KCIqIikuYnVpbGQoKSkpKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bSgiRE9XTkxPQURFREZJTEVDSEVDS1NVTSIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLCBjb250ZXh0LCBmbGFncykpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX3ppcF9ub0Rvd25sb2FkRmlsZUNoZWNrc3VtKCkgeworICAgIGZsYWdzLmVuYWJsZVppcEZvbGRlciA9IE9wdGlvbmFsLm9mKHRydWUpOworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworICAgIE1pZ3JhdGlvbnMuc2V0TWlncmF0ZWRUb05ld0ZpbGVLZXkoY29udGV4dCwgdHJ1ZSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsLkJ1aWxkZXIgZmlsZUdyb3VwQnVpbGRlciA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIKKyAgICAgICAgICAgIC5zZXRGaWxlKAorICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgZmlsZUdyb3VwQnVpbGRlci5nZXRGaWxlKDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFRyYW5zZm9ybXMoCisgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRUcmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRaaXAoWmlwVHJhbnNmb3JtLm5ld0J1aWxkZXIoKS5zZXRUYXJnZXQoIioiKS5idWlsZCgpKSkpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLCBjb250ZXh0LCBmbGFncykpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX3ppcF90YXJnZXRPbmVGaWxlKCkgeworICAgIGZsYWdzLmVuYWJsZVppcEZvbGRlciA9IE9wdGlvbmFsLm9mKHRydWUpOworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworICAgIE1pZ3JhdGlvbnMuc2V0TWlncmF0ZWRUb05ld0ZpbGVLZXkoY29udGV4dCwgdHJ1ZSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsLkJ1aWxkZXIgZmlsZUdyb3VwQnVpbGRlciA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIKKyAgICAgICAgICAgIC5zZXRGaWxlKAorICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgZmlsZUdyb3VwQnVpbGRlci5nZXRGaWxlKDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFRyYW5zZm9ybXMoCisgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRUcmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRaaXAoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWmlwVHJhbnNmb3JtLm5ld0J1aWxkZXIoKS5zZXRUYXJnZXQoImFiYy50eHQiKS5idWlsZCgpKSkpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZGVkRmlsZUNoZWNrc3VtKCJET1dOTE9BREVERklMRUNIRUNLU1VNIikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAsIGNvbnRleHQsIGZsYWdzKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfemlwX21vcmVUaGFuT25lVHJhbnNmb3JtcygpIHsKKyAgICBmbGFncy5lbmFibGVaaXBGb2xkZXIgPSBPcHRpb25hbC5vZih0cnVlKTsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBNaWdyYXRpb25zLnNldE1pZ3JhdGVkVG9OZXdGaWxlS2V5KGNvbnRleHQsIHRydWUpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGZpbGVHcm91cEJ1aWxkZXIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXBCdWlsZGVyCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdmFsaWQgZG93bmxvYWQgdHJhbnNmb3JtcyBzbyBpdCB3b24ndCBmYWlsIHRyYW5zZm9ybXMgdmFsaWRhdGlvbgorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRUcmFuc2Zvcm1zKAorICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0WmlwKFppcFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkuc2V0VGFyZ2V0KCIqIikuYnVpbGQoKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZFRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3JtLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldENvbXByZXNzKENvbXByZXNzVHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKSkpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLCBjb250ZXh0LCBmbGFncykpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX3JlYWRUcmFuc2Zvcm0oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBNaWdyYXRpb25zLnNldE1pZ3JhdGVkVG9OZXdGaWxlS2V5KGNvbnRleHQsIHRydWUpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGZpbGVHcm91cEJ1aWxkZXIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXBCdWlsZGVyCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0UmVhZFRyYW5zZm9ybXMoCisgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRUcmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRJbnRlZ3JpdHkoSW50ZWdyaXR5VHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKSkpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAsIGNvbnRleHQsIGZsYWdzKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9yZWFkVHJhbnNmb3JtX2ludmFsaWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBNaWdyYXRpb25zLnNldE1pZ3JhdGVkVG9OZXdGaWxlS2V5KGNvbnRleHQsIHRydWUpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGZpbGVHcm91cEJ1aWxkZXIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXBCdWlsZGVyCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0UmVhZFRyYW5zZm9ybXMoCisgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLm5ld0J1aWxkZXIoKS5hZGRUcmFuc2Zvcm0oVHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cCwgY29udGV4dCwgZmxhZ3MpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9pc1ZhbGlkR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBHcm91cCB3aXRoIGVtcHR5IG5hbWUuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCkuc2V0R3JvdXBOYW1lKCIiKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cCwgY29udGV4dCwgZmxhZ3MpKS5pc0ZhbHNlKCk7CisKKyAgICAvLyBHcm91cCB3aXRoIFNQTElUX0NIQVIgaW4gdGhlIG5hbWUuCisgICAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZSgiZ3JvdXB8bmFtZSIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAsIGNvbnRleHQsIGZsYWdzKSkuaXNGYWxzZSgpOworCisgICAgLy8gR3JvdXAgd2l0aCBlbXB0eSBmaWxlIGlkLgorICAgIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlKDAsIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKS5jbGVhckZpbGVJZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLCBjb250ZXh0LCBmbGFncykpLmlzRmFsc2UoKTsKKworICAgIC8vIEdyb3VwIHdpdGggU1BMSVRfQ0hBUiBpbiB0aGUgZmlsZSBpZC4KKyAgICBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZSgwLCBkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCkudG9CdWlsZGVyKCkuc2V0RmlsZUlkKCJmaWxlfGlkIikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAsIGNvbnRleHQsIGZsYWdzKSkuaXNGYWxzZSgpOworCisgICAgLy8gR3JvdXAgd2l0aCBlbXB0eSB1cmwuCisgICAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGUoMCwgZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLnRvQnVpbGRlcigpLmNsZWFyVXJsVG9Eb3dubG9hZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLCBjb250ZXh0LCBmbGFncykpLmlzRmFsc2UoKTsKKworICAgIC8vIEdyb3VwIHdpdGggZmlsZSBzaXplIDAuCisgICAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGUoMSwgZGF0YUZpbGVHcm91cC5nZXRGaWxlKDEpLnRvQnVpbGRlcigpLmNsZWFyQnl0ZVNpemUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cCwgY29udGV4dCwgZmxhZ3MpKS5pc1RydWUoKTsKKworICAgIC8vIEdyb3VwIHdpdGggZW1wdHkgY2hlY2tzdW0gYW5kIENoZWNrc3VtVHlwZSA9IERFRkFVTFQgaXMgaW52YWxpZC4KKyAgICBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZSgwLCBkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCkudG9CdWlsZGVyKCkuc2V0Q2hlY2tzdW0oIiIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLCBjb250ZXh0LCBmbGFncykpLmlzRmFsc2UoKTsKKworICAgIC8vIEdyb3VwIHdpdGggZW1wdHkgY2hlY2tzdW0gYW5kIENoZWNrc3VtVHlwZSA9IE5PTkUgaXMgdmFsaWQuCisgICAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGUoCisgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKCIiKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW1UeXBlKENoZWNrc3VtVHlwZS5OT05FKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cCwgY29udGV4dCwgZmxhZ3MpKS5pc1RydWUoKTsKKworICAgIC8vIEdyb3VwIHdpdGggZG93bmxvYWQgdHJhbnNmb3JtcyBidXQgd2l0aG91dCBkb3dubG9hZGVkIGZpbGUgY2hlY2tzdW0sIGFuZCBDaGVja3N1bVR5cGUgPQorICAgIC8vIERFRkFVTFQgaXMgaW52YWxpZC4KKyAgICBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW1UeXBlKENoZWNrc3VtVHlwZS5ERUZBVUxUKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRUcmFuc2Zvcm1zKAorICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm0ubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2V0Q29tcHJlc3MoQ29tcHJlc3NUcmFuc2Zvcm0uZ2V0RGVmYXVsdEluc3RhbmNlKCkpKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAsIGNvbnRleHQsIGZsYWdzKSkuaXNGYWxzZSgpOworCisgICAgLy8gR3JvdXAgd2l0aCBkb3dubG9hZCB0cmFuc2Zvcm1zIGJ1dCB3aXRob3V0IGRvd25sb2FkZWQgZmlsZSBjaGVja3N1bSwgYW5kIENoZWNrc3VtVHlwZSA9IE5PTkUKKyAgICAvLyBpcyB2YWxpZC4KKyAgICBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oIiIpCisgICAgICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bVR5cGUoQ2hlY2tzdW1UeXBlLk5PTkUpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFRyYW5zZm9ybXMoCisgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRUcmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRDb21wcmVzcyhDb21wcmVzc1RyYW5zZm9ybS5nZXREZWZhdWx0SW5zdGFuY2UoKSkpKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cCwgY29udGV4dCwgZmxhZ3MpKS5pc1RydWUoKTsKKworICAgIC8vIEdyb3VwIHdpdGggU1BMSVRfQ0hBUiBpbiB0aGUgY2hlY2tzdW0uCisgICAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGUoCisgICAgICAgICAgICAgICAgMCwKKyAgICAgICAgICAgICAgICBkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtVHlwZShDaGVja3N1bVR5cGUuREVGQVVMVCkKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKCJjaGVja3xzdW0iKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cCwgY29udGV4dCwgZmxhZ3MpKS5pc0ZhbHNlKCk7CisKKyAgICAvLyBHcm91cCB3aXRoIGR1cGxpY2F0ZSBmaWxlIGlkcy4KKyAgICBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgxKS5nZXRGaWxlSWQoKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAsIGNvbnRleHQsIGZsYWdzKSkuaXNGYWxzZSgpOworCisgICAgLy8gRm9yIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfRklSU1RfT05fV0lGSV9USEVOX09OX0FOWV9ORVRXT1JLCisgICAgLy8gZG93bmxvYWRfZmlyc3Rfb25fd2lmaV9wZXJpb2Rfc2VjcyBtdXN0IGJlID4gMC4KKyAgICBEb3dubG9hZENvbmRpdGlvbnMgZG93bmxvYWRDb25kaXRpb25zID0KKyAgICAgICAgRG93bmxvYWRDb25kaXRpb25zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERldmljZU5ldHdvcmtQb2xpY3koRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9GSVJTVF9PTl9XSUZJX1RIRU5fT05fQU5ZX05FVFdPUkspCisgICAgICAgICAgICAuc2V0RG93bmxvYWRGaXJzdE9uV2lmaVBlcmlvZFNlY3MoMCkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoZG93bmxvYWRDb25kaXRpb25zKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLCBjb250ZXh0LCBmbGFncykpLmlzRmFsc2UoKTsKKworICAgIC8vIEdyb3VwIHdpdGggc2hhcmVkIGFuZCBub3Qtc2hhcmVkIGZpbGVzLgorICAgIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlKAorICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmluZ1R5cGUoQW5kcm9pZFNoYXJpbmdUeXBlLkFORFJPSURfQkxPQl9XSEVOX0FWQUlMQUJMRSkKKyAgICAgICAgICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW1UeXBlKEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW1UeXBlLlNIQTJfMjU2KQorICAgICAgICAgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgic2hhMjU2X2ZpbGUwIikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAsIGNvbnRleHQsIGZsYWdzKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEFuZHJvaWRTaGFyZWRGaWxlKCkgeworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlU2hhcmVkRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBpbnZhbGlkR3JvdXAgPQorICAgICAgICBkYXRhRmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZSgwLCBkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCkudG9CdWlsZGVyKCkuc2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgiIikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGludmFsaWRHcm91cCwgY29udGV4dCwgZmxhZ3MpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0VmFsaWREZWx0YUZpbGUoKSB7CisgICAgTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBGaWxlS2V5VmVyc2lvbi5VU0VfQ0hFQ0tTVU1fT05MWSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlR3JvdXBJbnRlcm5hbFdpdGhEZWx0YUZpbGUoVEVTVF9HUk9VUCk7CisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLCBjb250ZXh0LCBmbGFncykpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEludmFsaWREZWx0YUZpbGVfbm9Eb3dubG9hZFVybCgpIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICAvLyBjcmVhdGUgd2l0aCBkZWx0YSBmaWxlIHdpdGggTk8gZG93bmxvYWQgdXJsCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsLkJ1aWxkZXIgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVHcm91cEludGVybmFsV2l0aERlbHRhRmlsZShURVNUX0dST1VQKS50b0J1aWxkZXIoKTsKKyAgICBEZWx0YUZpbGUgZGVsdGFGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGVsdGFGaWxlKCkudG9CdWlsZGVyKCkuY2xlYXJVcmxUb0Rvd25sb2FkKCkuYnVpbGQoKTsKKyAgICBEYXRhRmlsZSBkYXRhRmlsZSA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKS5jbGVhckRlbHRhRmlsZSgpLmFkZERlbHRhRmlsZShkZWx0YUZpbGUpLmJ1aWxkKCk7CisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAuc2V0RmlsZSgwLCBkYXRhRmlsZSk7CisKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAuYnVpbGQoKSwgY29udGV4dCwgZmxhZ3MpKQorICAgICAgICAuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEludmFsaWREZWx0YUZpbGVfbm9EaWZmRGVjb2RlcigpIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICAvLyBjcmVhdGUgd2l0aCBkZWx0YSBmaWxlIHdpdGggTk8gZGlmZiBkZWNvZGVyCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsLkJ1aWxkZXIgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVHcm91cEludGVybmFsV2l0aERlbHRhRmlsZShURVNUX0dST1VQKS50b0J1aWxkZXIoKTsKKyAgICBEZWx0YUZpbGUgZGVsdGFGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGVsdGFGaWxlKCkudG9CdWlsZGVyKCkuY2xlYXJEaWZmRGVjb2RlcigpLmJ1aWxkKCk7CisgICAgRGF0YUZpbGUgZGF0YUZpbGUgPQorICAgICAgICBkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCkudG9CdWlsZGVyKCkuY2xlYXJEZWx0YUZpbGUoKS5hZGREZWx0YUZpbGUoZGVsdGFGaWxlKS5idWlsZCgpOworICAgIGRhdGFGaWxlR3JvdXAgPSBkYXRhRmlsZUdyb3VwLnNldEZpbGUoMCwgZGF0YUZpbGUpOworCisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLmJ1aWxkKCksIGNvbnRleHQsIGZsYWdzKSkKKyAgICAgICAgLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkRGVsdGFGaWxlX3Vuc3BlY2lmaWVkRGlmZkRlY29kZXIoKSB7CisgICAgTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBGaWxlS2V5VmVyc2lvbi5VU0VfQ0hFQ0tTVU1fT05MWSk7CisgICAgLy8gY3JlYXRlIHdpdGggZGVsdGEgZmlsZSB3aXRoIFVOU1BFQ0lGSUVEIGRpZmYgZGVjb2RlcgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlR3JvdXBJbnRlcm5hbFdpdGhEZWx0YUZpbGUoVEVTVF9HUk9VUCkudG9CdWlsZGVyKCk7CisgICAgRGVsdGFGaWxlIGRlbHRhRmlsZSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURlbHRhRmlsZSgpLnRvQnVpbGRlcigpLnNldERpZmZEZWNvZGVyKERpZmZEZWNvZGVyLlVOU1BFQ0lGSUVEKS5idWlsZCgpOworICAgIERhdGFGaWxlIGRhdGFGaWxlID0KKyAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLnRvQnVpbGRlcigpLmNsZWFyRGVsdGFGaWxlKCkuYWRkRGVsdGFGaWxlKGRlbHRhRmlsZSkuYnVpbGQoKTsKKyAgICBkYXRhRmlsZUdyb3VwID0gZGF0YUZpbGVHcm91cC5zZXRGaWxlKDAsIGRhdGFGaWxlKTsKKworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cC5idWlsZCgpLCBjb250ZXh0LCBmbGFncykpCisgICAgICAgIC5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZERlbHRhRmlsZV9ub0NoZWNrc3VtKCkgeworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworICAgIC8vIGNyZWF0ZSB3aXRoIGRlbHRhIGZpbGUgd2l0aCBOTyBjaGVja3N1bQorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlR3JvdXBJbnRlcm5hbFdpdGhEZWx0YUZpbGUoVEVTVF9HUk9VUCkudG9CdWlsZGVyKCk7CisgICAgRGVsdGFGaWxlIGRlbHRhRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURlbHRhRmlsZSgpLnRvQnVpbGRlcigpLmNsZWFyQ2hlY2tzdW0oKS5idWlsZCgpOworICAgIERhdGFGaWxlIGRhdGFGaWxlID0KKyAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLnRvQnVpbGRlcigpLmNsZWFyRGVsdGFGaWxlKCkuYWRkRGVsdGFGaWxlKGRlbHRhRmlsZSkuYnVpbGQoKTsKKyAgICBkYXRhRmlsZUdyb3VwID0gZGF0YUZpbGVHcm91cC5zZXRGaWxlKDAsIGRhdGFGaWxlKTsKKworICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoZGF0YUZpbGVHcm91cC5idWlsZCgpLCBjb250ZXh0LCBmbGFncykpCisgICAgICAgIC5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZERlbHRhRmlsZV9ub0J5dGVTaXplKCkgeworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworICAgIC8vIGNyZWF0ZSB3aXRoIGRlbHRhIGZpbGUgd2l0aCBOTyBieXRlIHNpemUKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUdyb3VwSW50ZXJuYWxXaXRoRGVsdGFGaWxlKFRFU1RfR1JPVVApLnRvQnVpbGRlcigpOworICAgIERlbHRhRmlsZSBkZWx0YUZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEZWx0YUZpbGUoKS50b0J1aWxkZXIoKS5jbGVhckJ5dGVTaXplKCkuYnVpbGQoKTsKKyAgICBEYXRhRmlsZSBkYXRhRmlsZSA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKS5jbGVhckRlbHRhRmlsZSgpLmFkZERlbHRhRmlsZShkZWx0YUZpbGUpLmJ1aWxkKCk7CisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAuc2V0RmlsZSgwLCBkYXRhRmlsZSk7CisKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAuYnVpbGQoKSwgY29udGV4dCwgZmxhZ3MpKQorICAgICAgICAuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEludmFsaWREZWx0YUZpbGVfbm9CYXNlRmlsZUNoZWNrc3VtKCkgeworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlR3JvdXBJbnRlcm5hbFdpdGhEZWx0YUZpbGUoVEVTVF9HUk9VUCkudG9CdWlsZGVyKCk7CisgICAgRGVsdGFGaWxlIGRlbHRhRmlsZSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURlbHRhRmlsZSgpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0QmFzZUZpbGUoQmFzZUZpbGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBEYXRhRmlsZSBkYXRhRmlsZSA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKS5jbGVhckRlbHRhRmlsZSgpLmFkZERlbHRhRmlsZShkZWx0YUZpbGUpLmJ1aWxkKCk7CisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAuc2V0RmlsZSgwLCBkYXRhRmlsZSk7CisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLmJ1aWxkKCksIGNvbnRleHQsIGZsYWdzKSkKKyAgICAgICAgLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkRGVsdGFGaWxlX2Jhc2VGaWxlX2ludmFsaWRDaGVja3N1bSgpIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUdyb3VwSW50ZXJuYWxXaXRoRGVsdGFGaWxlKFRFU1RfR1JPVVApLnRvQnVpbGRlcigpOworICAgIERlbHRhRmlsZSBkZWx0YUZpbGUgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEZWx0YUZpbGUoKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEJhc2VGaWxlKEJhc2VGaWxlLm5ld0J1aWxkZXIoKS5zZXRDaGVja3N1bSgiYWJjIiArICJ8IiArICJkZWYiKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIERhdGFGaWxlIGRhdGFGaWxlID0KKyAgICAgICAgZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLnRvQnVpbGRlcigpLmNsZWFyRGVsdGFGaWxlKCkuYWRkRGVsdGFGaWxlKGRlbHRhRmlsZSkuYnVpbGQoKTsKKyAgICBkYXRhRmlsZUdyb3VwID0gZGF0YUZpbGVHcm91cC5zZXRGaWxlKDAsIGRhdGFGaWxlKTsKKyAgICBhc3NlcnRUaGF0KERhdGFGaWxlR3JvdXBWYWxpZGF0b3IuaXNWYWxpZEdyb3VwKGRhdGFGaWxlR3JvdXAuYnVpbGQoKSwgY29udGV4dCwgZmxhZ3MpKQorICAgICAgICAuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEludmFsaWREZWx0YUZpbGVfbm9CYXNlRmlsZSgpIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUdyb3VwSW50ZXJuYWxXaXRoRGVsdGFGaWxlKFRFU1RfR1JPVVApLnRvQnVpbGRlcigpOworICAgIERlbHRhRmlsZSBkZWx0YUZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEZWx0YUZpbGUoKS50b0J1aWxkZXIoKS5jbGVhckJhc2VGaWxlKCkuYnVpbGQoKTsKKyAgICBEYXRhRmlsZSBkYXRhRmlsZSA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKS5jbGVhckRlbHRhRmlsZSgpLmFkZERlbHRhRmlsZShkZWx0YUZpbGUpLmJ1aWxkKCk7CisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAuc2V0RmlsZSgwLCBkYXRhRmlsZSk7CisgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChkYXRhRmlsZUdyb3VwLmJ1aWxkKCksIGNvbnRleHQsIGZsYWdzKSkKKyAgICAgICAgLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RTaWRlbG9hZGVkRmlsZV92YWxpZFdoZW5TaWRlbG9hZGluZ0VuYWJsZWQoKSB7CisgICAgLy8gQ3JlYXRlIHNpZGVsb2FkZWQgZ3JvdXAKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgc2lkZWxvYWRlZEdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoInNpZGVsb2FkZWRfZmlsZSIpCisgICAgICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJmaWxlOi90ZXN0IikKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtVHlwZShEYXRhRmlsZS5DaGVja3N1bVR5cGUuTk9ORSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHsKKyAgICAgIC8vIEZvcmNlIHNpZGVsb2FkaW5nIG9mZgorICAgICAgZmxhZ3MuZW5hYmxlU2lkZWxvYWRpbmcgPSBPcHRpb25hbC5vZihmYWxzZSk7CisKKyAgICAgIGFzc2VydFRoYXQoRGF0YUZpbGVHcm91cFZhbGlkYXRvci5pc1ZhbGlkR3JvdXAoc2lkZWxvYWRlZEdyb3VwLCBjb250ZXh0LCBmbGFncykpLmlzRmFsc2UoKTsKKyAgICB9CisKKyAgICB7CisgICAgICAvLyBGb3JjZSBzaWRlbG9hZGluZyBvbgorICAgICAgZmxhZ3MuZW5hYmxlU2lkZWxvYWRpbmcgPSBPcHRpb25hbC5vZih0cnVlKTsKKworICAgICAgYXNzZXJ0VGhhdChEYXRhRmlsZUdyb3VwVmFsaWRhdG9yLmlzVmFsaWRHcm91cChzaWRlbG9hZGVkR3JvdXAsIGNvbnRleHQsIGZsYWdzKSkuaXNUcnVlKCk7CisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvRXhwaXJhdGlvbkhhbmRsZXJUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvRXhwaXJhdGlvbkhhbmRsZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODYzYzM5ZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9FeHBpcmF0aW9uSGFuZGxlclRlc3QuamF2YQpAQCAtMCwwICsxLDE3NjUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuYW55OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLmRvVGhyb3c7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ubmV2ZXI7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udGltZXM7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnZlcmlmeU5vTW9yZUludGVyYWN0aW9uczsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by53aGVuOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQudXRpbC5QYWlyOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5TaWxlbnRGZWVkYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kZWx0YS5EZWx0YURlY29kZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWlncmF0aW9ucy5GaWxlS2V5VmVyc2lvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kb3dubG9hZGVyLk1kZEZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuRXZlbnRMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5EaXJlY3RvcnlVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuRG93bmxvYWRQcm9ncmVzc01vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5GYWtlVGltZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLlRlc3RGbGFnczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsLkFsbG93ZWRSZWFkZXJzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRmlsZVN0YXR1czsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkdyb3VwS2V5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uTmV3RmlsZUtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLlNoYXJlZEZpbGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNhbGVuZGFyOworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljUmVmZXJlbmNlOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uaW52b2NhdGlvbi5JbnZvY2F0aW9uT25Nb2NrOworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9KVW5pdDsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvUnVsZTsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgRXhwaXJhdGlvbkhhbmRsZXJUZXN0IHsKKworICBATW9jayBTaGFyZWRGaWxlTWFuYWdlciBtb2NrU2hhcmVkRmlsZU1hbmFnZXI7CisgIEBNb2NrIFNoYXJlZEZpbGVzTWV0YWRhdGEgbW9ja1NoYXJlZEZpbGVzTWV0YWRhdGE7CisgIEBNb2NrIEZpbGVHcm91cHNNZXRhZGF0YSBtb2NrRmlsZUdyb3Vwc01ldGFkYXRhOworICBATW9jayBFdmVudExvZ2dlciBtb2NrRXZlbnRMb2dnZXI7CisgIEBNb2NrIFNpbGVudEZlZWRiYWNrIG1vY2tTaWxlbnRGZWVkYmFjazsKKworICBATW9jayBCYWNrZW5kIG1vY2tCYWNrZW5kOworICBATW9jayBCYWNrZW5kIG1vY2tCbG9iU3RvcmVCYWNrZW5kOworICBATW9jayBNZGRGaWxlRG93bmxvYWRlciBtb2NrRG93bmxvYWRlcjsKKyAgQE1vY2sgRG93bmxvYWRQcm9ncmVzc01vbml0b3IgbW9ja0Rvd25sb2FkTW9uaXRvcjsKKworICAvLyBBbGxvd3MgbW9ja0ZpbGVHcm91cHNNZXRhZGF0YSB0byBjb3JyZWN0bHkgcmVzcG9uZCB0byB3cml0ZVN0YWxlR3JvdXBzIGFuZCBnZXRBbGxTdGFsZUdyb3Vwcy4KKyAgQXRvbWljUmVmZXJlbmNlPEltbXV0YWJsZUxpc3Q8RGF0YUZpbGVHcm91cEludGVybmFsPj4gZmlsZUdyb3Vwc01ldGFkYXRhU3RhbGVHcm91cHMgPQorICAgICAgbmV3IEF0b21pY1JlZmVyZW5jZTw+KEltbXV0YWJsZUxpc3Qub2YoKSk7CisKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlOworICBwcml2YXRlIENvbnRleHQgY29udGV4dDsKKyAgcHJpdmF0ZSBFeHBpcmF0aW9uSGFuZGxlciBleHBpcmF0aW9uSGFuZGxlcjsKKyAgcHJpdmF0ZSBFeHBpcmF0aW9uSGFuZGxlciBleHBpcmF0aW9uSGFuZGxlck5vTW9ja3M7CisgIHByaXZhdGUgRmFrZVRpbWVTb3VyY2UgdGVzdENsb2NrOworICBwcml2YXRlIFVyaSBiYXNlRG93bmxvYWREaXJlY3RvcnlVcmk7CisgIHByaXZhdGUgVXJpIGJhc2VEb3dubG9hZFN5bWxpbmtEaXJlY3RvcnlVcmk7CisgIHByaXZhdGUgRmlsZUdyb3Vwc01ldGFkYXRhIGZpbGVHcm91cHNNZXRhZGF0YTsKKyAgcHJpdmF0ZSBTaGFyZWRGaWxlc01ldGFkYXRhIHNoYXJlZEZpbGVzTWV0YWRhdGE7CisgIHByaXZhdGUgU2hhcmVkRmlsZU1hbmFnZXIgc2hhcmVkRmlsZU1hbmFnZXI7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfR1JPVVBfMSA9ICJ0ZXN0LWdyb3VwLTEiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBHcm91cEtleSBURVNUX0tFWV8xID0gR3JvdXBLZXkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfR1JPVVBfMiA9ICJ0ZXN0LWdyb3VwLTIiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBHcm91cEtleSBURVNUX0tFWV8yID0gR3JvdXBLZXkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CisKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdGVzdFVyaTEgPQorICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICJhbmRyb2lkOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8xIik7CisKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdGVzdFVyaTIgPQorICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICJhbmRyb2lkOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8yIik7CisKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdGVtcFRlc3RVcmkyID0KKyAgICAgIFVyaS5wYXJzZSgKKyAgICAgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsL2ZpbGVzL2RhdGFkb3dubG9hZC9zaGFyZWQvcHVibGljL2ZpbGVfMl90ZW1wIik7CisKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdGVzdFVyaTMgPQorICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICJhbmRyb2lkOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8zIik7CisKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdGVzdFVyaTQgPQorICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICJhbmRyb2lkOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV80Iik7CisKKyAgLy8gTUREIGZpbGUgVVJJIGNvdWxkIGJlIGEgZm9sZGVyIHdoaWNoIGlzIHVuemlwcGVkIGZyb20gemlwIGZvbGRlciBkb3dubG9hZCB0cmFuc2Zvcm0KKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdGVzdERpclVyaTEgPQorICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICJhbmRyb2lkOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZGlyXzEiKTsKKworICBwcml2YXRlIGZpbmFsIFVyaSB0ZXN0RGlyRmlsZVVyaTEgPQorICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICJhbmRyb2lkOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZGlyXzEvZmlsZV8xIik7CisKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdGVzdERpckZpbGVVcmkyID0KKyAgICAgIFVyaS5wYXJzZSgKKyAgICAgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsL2ZpbGVzL2RhdGFkb3dubG9hZC9zaGFyZWQvcHVibGljL2Rpcl8xL2ZpbGVfMiIpOworCisgIHByaXZhdGUgZmluYWwgVXJpIGRpckZvckFsbCA9CisgICAgICBVcmkucGFyc2UoCisgICAgICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC9maWxlcy9kYXRhZG93bmxvYWQvc2hhcmVkL3B1YmxpY18zcCIpOworICBwcml2YXRlIGZpbmFsIFVyaSBkaXJGb3IxcCA9CisgICAgICBVcmkucGFyc2UoCisgICAgICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC9maWxlcy9kYXRhZG93bmxvYWQvc2hhcmVkL3B1YmxpYyIpOworICBwcml2YXRlIGZpbmFsIFVyaSBkaXJGb3IwcCA9CisgICAgICBVcmkucGFyc2UoCisgICAgICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC9maWxlcy9kYXRhZG93bmxvYWQvc2hhcmVkL3ByaXZhdGUiKTsKKworICBwcml2YXRlIGZpbmFsIFVyaSBzeW1saW5rRGlyRm9yR3JvdXAxID0KKyAgICAgIFVyaS5wYXJzZSgKKyAgICAgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsL2ZpbGVzL2RhdGFkb3dubG9hZC9zaGFyZWQvbGlua3MvcHVibGljL3Rlc3QtZ3JvdXAtMSIpOworICBwcml2YXRlIGZpbmFsIFVyaSBzeW1saW5rRm9yVXJpMSA9CisgICAgICBVcmkucGFyc2UoCisgICAgICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC9maWxlcy9kYXRhZG93bmxvYWQvc2hhcmVkL2xpbmtzL3B1YmxpYy90ZXN0LWdyb3VwLTEvdGVzdC1ncm91cC0xXzAiKTsKKworICBwcml2YXRlIGZpbmFsIFVyaSBzeW1saW5rRGlyRm9yR3JvdXAyID0KKyAgICAgIFVyaS5wYXJzZSgKKyAgICAgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsL2ZpbGVzL2RhdGFkb3dubG9hZC9zaGFyZWQvbGlua3MvcHVibGljL3Rlc3QtZ3JvdXAtMiIpOworICBwcml2YXRlIGZpbmFsIFVyaSBzeW1saW5rRm9yVXJpMiA9CisgICAgICBVcmkucGFyc2UoCisgICAgICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC9maWxlcy9kYXRhZG93bmxvYWQvc2hhcmVkL2xpbmtzL3B1YmxpYy90ZXN0LWdyb3VwLTIvdGVzdC1ncm91cC0yXzAiKTsKKworICBwcml2YXRlIGZpbmFsIFRlc3RGbGFncyBmbGFncyA9IG5ldyBUZXN0RmxhZ3MoKTsKKyAgQFJ1bGUgcHVibGljIGZpbmFsIE1vY2tpdG9SdWxlIG1vY2tzID0gTW9ja2l0b0pVbml0LnJ1bGUoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKworICAgIHRlc3RDbG9jayA9IG5ldyBGYWtlVGltZVNvdXJjZSgpOworCisgICAgYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpID0gRGlyZWN0b3J5VXRpbC5nZXRCYXNlRG93bmxvYWREaXJlY3RvcnkoY29udGV4dCwgT3B0aW9uYWwuYWJzZW50KCkpOworICAgIGJhc2VEb3dubG9hZFN5bWxpbmtEaXJlY3RvcnlVcmkgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldEJhc2VEb3dubG9hZFN5bWxpbmtEaXJlY3RvcnkoY29udGV4dCwgT3B0aW9uYWwuYWJzZW50KCkpOworICAgIHdoZW4obW9ja0JhY2tlbmQubmFtZSgpKS50aGVuUmV0dXJuKCJhbmRyb2lkIik7CisgICAgd2hlbihtb2NrQmxvYlN0b3JlQmFja2VuZC5uYW1lKCkpLnRoZW5SZXR1cm4oImJsb2JzdG9yZSIpOworICAgIHNldFVwRGlyZWN0b3J5TW9jayhiYXNlRG93bmxvYWREaXJlY3RvcnlVcmksIEFycmF5cy5hc0xpc3QoZGlyRm9yQWxsLCBkaXJGb3IxcCwgZGlyRm9yMHApKTsKKyAgICBzZXRVcERpcmVjdG9yeU1vY2soZGlyRm9yQWxsLCBJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHNldFVwRGlyZWN0b3J5TW9jayhkaXJGb3IwcCwgSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICBzZXRVcERpcmVjdG9yeU1vY2soZGlyRm9yMXAsIEltbXV0YWJsZUxpc3Qub2YoKSk7CisgICAgc2V0VXBEaXJlY3RvcnlNb2NrKHRlc3REaXJVcmkxLCBJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIGZpbGVTdG9yYWdlID0gbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoQXJyYXlzLmFzTGlzdChtb2NrQmFja2VuZCwgbW9ja0Jsb2JTdG9yZUJhY2tlbmQpKTsKKworICAgIGV4cGlyYXRpb25IYW5kbGVyID0KKyAgICAgICAgbmV3IEV4cGlyYXRpb25IYW5kbGVyKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsCisgICAgICAgICAgICBtb2NrU2hhcmVkRmlsZU1hbmFnZXIsCisgICAgICAgICAgICBtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIHRlc3RDbG9jaywKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCksCisgICAgICAgICAgICBmbGFncyk7CisKKyAgICAvLyBCeSBkZWZhdWx0LCBtb2NrcyB3aWxsIHJldHVybiBlbXB0eSBsaXN0cworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShJbW11dGFibGVMaXN0Lm9mKCkpKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlbW92ZUFsbFN0YWxlR3JvdXBzKCkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLnJlbW92ZUZpbGVFbnRyeShhbnkoKSkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKFNoYXJlZEZpbGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTsKKworICAgIC8vIENhbGxzIHRvIG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEud3JpdGVTdGFsZUdyb3VwcygpIGFyZSByZWZsZWN0ZWQgYnkgZ2V0QWxsU3RhbGVHcm91cHMoKS4KKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKSkKKyAgICAgICAgLnRoZW5BbnN3ZXIoaW52b2NhdGlvbiAtPiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmaWxlR3JvdXBzTWV0YWRhdGFTdGFsZUdyb3Vwcy5nZXQoKSkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS53cml0ZVN0YWxlR3JvdXBzKGFueSgpKSkKKyAgICAgICAgLnRoZW5BbnN3ZXIoCisgICAgICAgICAgICAoSW52b2NhdGlvbk9uTW9jayBpbnZvY2F0aW9uKSAtPiB7CisgICAgICAgICAgICAgIExpc3Q8RGF0YUZpbGVHcm91cEludGVybmFsPiByZXF1ZXN0ID0gaW52b2NhdGlvbi5nZXRBcmd1bWVudCgwKTsKKyAgICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhU3RhbGVHcm91cHMuc2V0KEltbXV0YWJsZUxpc3QuY29weU9mKHJlcXVlc3QpKTsKKyAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpOworICAgICAgICAgICAgfSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgc2V0dXBGb3JBbmRyb2lkU2hhcmVkKCkgeworICAgIC8vIENvbnN0cnVjdCBhbiBleHBpcmF0aW9uIGhhbmRsZXIgd2l0aG91dCBtb2NraW5nIHRoZSBtYWluIGNsYXNzZXMKKyAgICBmaWxlR3JvdXBzTWV0YWRhdGEgPQorICAgICAgICBuZXcgU2hhcmVkUHJlZmVyZW5jZXNGaWxlR3JvdXBzTWV0YWRhdGEoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgdGVzdENsb2NrLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCkpOworICAgIE9wdGlvbmFsPERlbHRhRGVjb2Rlcj4gZGVsdGFEZWNvZGVyID0gT3B0aW9uYWwuYWJzZW50KCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSA9CisgICAgICAgIG5ldyBTaGFyZWRQcmVmZXJlbmNlc1NoYXJlZEZpbGVzTWV0YWRhdGEoCisgICAgICAgICAgICBjb250ZXh0LCBtb2NrU2lsZW50RmVlZGJhY2ssIE9wdGlvbmFsLmFic2VudCgpLCBmbGFncyk7CisgICAgc2hhcmVkRmlsZU1hbmFnZXIgPQorICAgICAgICBuZXcgU2hhcmVkRmlsZU1hbmFnZXIoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgbW9ja0Rvd25sb2FkZXIsCisgICAgICAgICAgICBkZWx0YURlY29kZXIsCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrRG93bmxvYWRNb25pdG9yKSwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCkpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXJOb01vY2tzID0KKyAgICAgICAgbmV3IEV4cGlyYXRpb25IYW5kbGVyKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YSwKKyAgICAgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyLAorICAgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgICAgIG1vY2tFdmVudExvZ2dlciwKKyAgICAgICAgICAgIHRlc3RDbG9jaywKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCksCisgICAgICAgICAgICBmbGFncyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cGRhdGVFeHBpcmF0aW9uX25vR3JvdXBzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEltbXV0YWJsZUxpc3Qub2YoKSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoSW1tdXRhYmxlTGlzdC5vZigpKSk7CisKKyAgICBleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMykpLmdldEFsbEZyZXNoR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDIpKS5nZXRBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxHcm91cHNXaXRoS2V5cyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS53cml0ZVN0YWxlR3JvdXBzKEltbXV0YWJsZUxpc3Qub2YoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YSkuZ2V0QWxsRmlsZUtleXMoKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmV4aXN0cyhiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuY2hpbGRyZW4oYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmRlbGV0ZUZpbGUoYW55KCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdXBkYXRlRXhwaXJhdGlvbl9ub0V4cGlyZWRHcm91cHNfbm9FeHBpcmF0aW9uRGF0ZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzEsIDIpOworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXApOworCisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBncm91cHMgPQorICAgICAgICBBcnJheXMuYXNMaXN0KFBhaXIuY3JlYXRlKFRFU1RfS0VZXzEsIGRhdGFGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShncm91cHMpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTEpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXlzWzFdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzFdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTIpKTsKKworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoQXJyYXlzLmFzTGlzdChmaWxlS2V5cykpKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmNoaWxkcmVuKGRpckZvcjBwKSkudGhlblJldHVybihBcnJheXMuYXNMaXN0KHRlc3RVcmkxLCB0ZXN0VXJpMikpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMF0pOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzFdKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmV4aXN0cyhiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuY2hpbGRyZW4oYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmlzRGlyZWN0b3J5KGRpckZvckFsbCk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeShkaXJGb3IxcCk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5kZWxldGVGaWxlKGFueSgpKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVwZGF0ZUV4cGlyYXRpb25fbm9FeHBpcmVkR3JvdXBzX2V4cGlyYXRpb25EYXRlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIENhbGVuZGFyIG5vdyA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjApLmJ1aWxkKCk7CisgICAgdGVzdENsb2NrLnNldChub3cuZ2V0VGltZUluTWlsbGlzKCkpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8xLCAyKTsKKyAgICBDYWxlbmRhciBsYXRlciA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5BUFJJTCwgMjApLmJ1aWxkKCk7CisgICAgbG9uZyBsYXRlclRpbWVTZWNzID0gbGF0ZXIuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwOworICAgIGRhdGFGaWxlR3JvdXAgPSBkYXRhRmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldEV4cGlyYXRpb25EYXRlU2VjcyhsYXRlclRpbWVTZWNzKS5idWlsZCgpOworCisgICAgTmV3RmlsZUtleVtdIGZpbGVLZXlzID0gTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwoZGF0YUZpbGVHcm91cCk7CisKKyAgICBMaXN0PFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4+IGdyb3VwcyA9CisgICAgICAgIEFycmF5cy5hc0xpc3QoUGFpci5jcmVhdGUoVEVTVF9LRVlfMSwgZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGdyb3VwcykpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMV0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMV0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMikpOworCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShBcnJheXMuYXNMaXN0KGZpbGVLZXlzKSkpOworICAgIHdoZW4obW9ja0JhY2tlbmQuY2hpbGRyZW4oZGlyRm9yMHApKS50aGVuUmV0dXJuKEFycmF5cy5hc0xpc3QodGVzdFVyaTEsIHRlc3RVcmkyKSk7CisKKyAgICBleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMykpLmdldEFsbEZyZXNoR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDIpKS5nZXRBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxHcm91cHNXaXRoS2V5cyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS53cml0ZVN0YWxlR3JvdXBzKEltbXV0YWJsZUxpc3Qub2YoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YSkuZ2V0QWxsRmlsZUtleXMoKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5nZXRPbkRldmljZVVyaShmaWxlS2V5c1swXSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMV0pOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZXhpc3RzKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5jaGlsZHJlbihiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkoZGlyRm9yQWxsKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmlzRGlyZWN0b3J5KGRpckZvcjFwKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmRlbGV0ZUZpbGUoYW55KCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdXBkYXRlRXhwaXJhdGlvbl9leHBpcmVkR3JvdXBzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQ3VycmVudCB0aW1lCisgICAgQ2FsZW5kYXIgbm93ID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMjAsIENhbGVuZGFyLk1BUkNILCAyMCkuYnVpbGQoKTsKKyAgICB0ZXN0Q2xvY2suc2V0KG5vdy5nZXRUaW1lSW5NaWxsaXMoKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzEsIDUpOworICAgIC8vIFRpbWUgd2hlbiB0aGUgZ3JvdXAgZXhwaXJlcworICAgIENhbGVuZGFyIGVhcmxpZXIgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIGxvbmcgZWFybGllclRpbWVTZWNzID0gZWFybGllci5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDA7CisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKGVhcmxpZXJUaW1lU2VjcykuYnVpbGQoKTsKKworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXApOworCisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBncm91cHMgPQorICAgICAgICBBcnJheXMuYXNMaXN0KFBhaXIuY3JlYXRlKFRFU1RfS0VZXzEsIGRhdGFGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZ3JvdXBzKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobmV3IEFycmF5TGlzdDw+KCkpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTEpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXlzWzFdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRmlsZVN0YXR1cy5ET1dOTE9BRF9GQUlMRUQpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRPbkRldmljZVVyaShmaWxlS2V5c1sxXSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRlc3RVcmkyKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0RmlsZVN0YXR1cyhmaWxlS2V5c1syXSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRPbkRldmljZVVyaShmaWxlS2V5c1syXSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRlc3RVcmkzKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0RmlsZVN0YXR1cyhmaWxlS2V5c1szXSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZpbGVTdGF0dXMuU1VCU0NSSUJFRCkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzNdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTQpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXlzWzRdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRmlsZVN0YXR1cy5OT05FKSk7CisKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLmdldEFsbEZpbGVLZXlzKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEFycmF5cy5hc0xpc3QoZmlsZUtleXMpKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5jaGlsZHJlbihkaXJGb3IwcCkpCisgICAgICAgIC50aGVuUmV0dXJuKEFycmF5cy5hc0xpc3QodGVzdFVyaTEsIHRlc3RVcmkyLCB0ZXN0VXJpMywgdGVzdFVyaTQpKTsKKyAgICBleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMykpLmdldEFsbEZyZXNoR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDIpKS5nZXRBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxHcm91cHNXaXRoS2V5cyhBcnJheXMuYXNMaXN0KFRFU1RfS0VZXzEpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikucmVtb3ZlRmlsZUVudHJ5KGZpbGVLZXlzWzBdKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5yZW1vdmVGaWxlRW50cnkoZmlsZUtleXNbMV0pOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLnJlbW92ZUZpbGVFbnRyeShmaWxlS2V5c1syXSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikucmVtb3ZlRmlsZUVudHJ5KGZpbGVLZXlzWzNdKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5yZW1vdmVGaWxlRW50cnkoZmlsZUtleXNbNF0pOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZXhpc3RzKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5jaGlsZHJlbihiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdFVyaTEpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdFVyaTIpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdFVyaTMpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdFVyaTQpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZGVsZXRlRmlsZSh0ZXN0VXJpMSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5kZWxldGVGaWxlKHRlc3RVcmkyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmRlbGV0ZUZpbGUodGVzdFVyaTMpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZGVsZXRlRmlsZSh0ZXN0VXJpNCk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cGRhdGVFeHBpcmF0aW9uX25vRXhwaXJlZEdyb3Vwc19wZW5kaW5nR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMSwgMik7CisgICAgQ2FsZW5kYXIgbGF0ZXIgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuQVBSSUwsIDIwKS5idWlsZCgpOworICAgIGxvbmcgbGF0ZXJUaW1lU2VjcyA9IGxhdGVyLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMDsKKyAgICBkYXRhRmlsZUdyb3VwID0gZGF0YUZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRFeHBpcmF0aW9uRGF0ZVNlY3MobGF0ZXJUaW1lU2VjcykuYnVpbGQoKTsKKworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXApOworCisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBncm91cHMgPQorICAgICAgICBBcnJheXMuYXNMaXN0KFBhaXIuY3JlYXRlKFRFU1RfS0VZXzEsIGRhdGFGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShncm91cHMpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTEpKTsKKyAgICAvLyBUaGUgc2Vjb25kIGZpbGUgaGFzIG5vdCBiZWVuIGRvd25sb2FkZWQuCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0RmlsZVN0YXR1cyhmaWxlS2V5c1sxXSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZpbGVTdGF0dXMuTk9ORSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzFdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTIpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLmdldEFsbEZpbGVLZXlzKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEFycmF5cy5hc0xpc3QoZmlsZUtleXMpKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5jaGlsZHJlbihkaXJGb3IwcCkpLnRoZW5SZXR1cm4oQXJyYXlzLmFzTGlzdCh0ZXN0VXJpMSwgdGVzdFVyaTIpKTsKKworICAgIGV4cGlyYXRpb25IYW5kbGVyLnVwZGF0ZUV4cGlyYXRpb24oKS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygzKSkuZ2V0QWxsRnJlc2hHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMikpLmdldEFsbFN0YWxlR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKEltbXV0YWJsZUxpc3Qub2YoKSk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLnJlbW92ZUFsbFN0YWxlR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLndyaXRlU3RhbGVHcm91cHMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhKS5nZXRBbGxGaWxlS2V5cygpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzBdKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5nZXRPbkRldmljZVVyaShmaWxlS2V5c1sxXSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmNoaWxkcmVuKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeShkaXJGb3JBbGwpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkoZGlyRm9yMXApOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZGVsZXRlRmlsZShhbnkoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cGRhdGVFeHBpcmF0aW9uX25vdERlbGV0ZUludGVybmFsRmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMSwgMik7CisgICAgQ2FsZW5kYXIgbGF0ZXIgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuQVBSSUwsIDIwKS5idWlsZCgpOworICAgIGxvbmcgbGF0ZXJUaW1lU2VjcyA9IGxhdGVyLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMDsKKyAgICBkYXRhRmlsZUdyb3VwID0gZGF0YUZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRFeHBpcmF0aW9uRGF0ZVNlY3MobGF0ZXJUaW1lU2VjcykuYnVpbGQoKTsKKworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IGNyZWF0ZUZpbGVLZXlzVXNlQ2hlY2tzdW1Pbmx5KGRhdGFGaWxlR3JvdXApOworCisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBncm91cHMgPQorICAgICAgICBBcnJheXMuYXNMaXN0KFBhaXIuY3JlYXRlKFRFU1RfS0VZXzEsIGRhdGFGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShncm91cHMpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTEpKTsKKyAgICAvLyBUaGUgc2Vjb25kIGZpbGUgaGFzIG5vdCBiZWVuIGRvd25sb2FkZWQuCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0RmlsZVN0YXR1cyhmaWxlS2V5c1sxXSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZpbGVTdGF0dXMuTk9ORSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzFdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTIpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLmdldEFsbEZpbGVLZXlzKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEFycmF5cy5hc0xpc3QoZmlsZUtleXMpKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5jaGlsZHJlbihkaXJGb3IwcCkpCisgICAgICAgIC50aGVuUmV0dXJuKEFycmF5cy5hc0xpc3QodGVzdFVyaTEsIHRlc3RVcmkyLCB0ZW1wVGVzdFVyaTIpKTsKKworICAgIGV4cGlyYXRpb25IYW5kbGVyLnVwZGF0ZUV4cGlyYXRpb24oKS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygzKSkuZ2V0QWxsRnJlc2hHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMikpLmdldEFsbFN0YWxlR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKEltbXV0YWJsZUxpc3Qub2YoKSk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLnJlbW92ZUFsbFN0YWxlR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLndyaXRlU3RhbGVHcm91cHMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhKS5nZXRBbGxGaWxlS2V5cygpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzBdKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5nZXRPbkRldmljZVVyaShmaWxlS2V5c1sxXSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmNoaWxkcmVuKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeShkaXJGb3JBbGwpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkoZGlyRm9yMXApOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkoZGlyRm9yMHApOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZGVsZXRlRmlsZShhbnkoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cGRhdGVFeHBpcmF0aW9uX2RlbGV0ZUludGVybmFsRmlsZXNXaXRoRXhpcGlyZWRBY2NvdW50ZWRGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBGaWxlS2V5VmVyc2lvbi5VU0VfQ0hFQ0tTVU1fT05MWSk7CisgICAgQ2FsZW5kYXIgbm93ID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLk1BUkNILCAyMCkuYnVpbGQoKTsKKyAgICB0ZXN0Q2xvY2suc2V0KG5vdy5nZXRUaW1lSW5NaWxsaXMoKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzEsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0QnVpbGRJZCgxMCkKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoInRlc3RWYXJpYW50IikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGxvbmcgbm93VGltZVNlY3MgPSBub3cuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwOworICAgIGRhdGFGaWxlR3JvdXAgPSBkYXRhRmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldEV4cGlyYXRpb25EYXRlU2Vjcyhub3dUaW1lU2VjcykuYnVpbGQoKTsKKworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IGNyZWF0ZUZpbGVLZXlzVXNlQ2hlY2tzdW1Pbmx5KGRhdGFGaWxlR3JvdXApOworCisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBncm91cHMgPQorICAgICAgICBBcnJheXMuYXNMaXN0KFBhaXIuY3JlYXRlKFRFU1RfS0VZXzEsIGRhdGFGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZ3JvdXBzKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobmV3IEFycmF5TGlzdDw+KCkpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTIpKTsKKworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoQXJyYXlzLmFzTGlzdChmaWxlS2V5cykpKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmNoaWxkcmVuKGRpckZvcjBwKSkudGhlblJldHVybihBcnJheXMuYXNMaXN0KHRlc3RVcmkyLCB0ZW1wVGVzdFVyaTIpKTsKKyAgICBleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMykpLmdldEFsbEZyZXNoR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDIpKS5nZXRBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxHcm91cHNXaXRoS2V5cyhBcnJheXMuYXNMaXN0KFRFU1RfS0VZXzEpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikucmVtb3ZlRmlsZUVudHJ5KGZpbGVLZXlzWzBdKTsKKworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZXhpc3RzKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5jaGlsZHJlbihiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdFVyaTIpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVtcFRlc3RVcmkyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmRlbGV0ZUZpbGUodGVzdFVyaTIpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZGVsZXRlRmlsZSh0ZW1wVGVzdFVyaTIpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdXBkYXRlRXhwaXJhdGlvbl9zaGFyZWRGaWxlc19ub0V4cGlyYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlIGRhdGFGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGUiLCAwKTsKKyAgICBOZXdGaWxlS2V5IGZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIGRhdGFGaWxlLCBBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKTsKKworICAgIC8vIFRoZSBmaXJzdCBncm91cCBleHBpcmVzIDMwIGRheXMgZnJvbSBub3cuCisgICAgQ2FsZW5kYXIgbGF0ZXIgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuQVBSSUwsIDIwKS5idWlsZCgpOworICAgIGxvbmcgbGF0ZXJUaW1lU2VjcyA9IGxhdGVyLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMDsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlyc3RHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8xKQorICAgICAgICAgICAgLmFkZEZpbGUoZGF0YUZpbGUpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLk9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKGxhdGVyVGltZVNlY3MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIFRoZSBzZWNvbmQgZ3JvdXAgbmV2ZXIgZXhwaXJlcworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBzZWNvbmRHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8yKQorICAgICAgICAgICAgLmFkZEZpbGUoZGF0YUZpbGUpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLk9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIExpc3Q8UGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPj4gZ3JvdXBzID0KKyAgICAgICAgQXJyYXlzLmFzTGlzdChQYWlyLmNyZWF0ZShURVNUX0tFWV8xLCBmaXJzdEdyb3VwKSwgUGFpci5jcmVhdGUoVEVTVF9LRVlfMiwgc2Vjb25kR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShncm91cHMpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRlc3RVcmkxKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KGZpbGVLZXkpKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5jaGlsZHJlbihkaXJGb3IwcCkpLnRoZW5SZXR1cm4oQXJyYXlzLmFzTGlzdCh0ZXN0VXJpMSkpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmNoaWxkcmVuKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeShkaXJGb3JBbGwpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZGVsZXRlRmlsZShhbnkoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cGRhdGVFeHBpcmF0aW9uX3NoYXJlZEZpbGVzX2V4cGlyYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlIGRhdGFGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGUiLCAwKTsKKyAgICBOZXdGaWxlS2V5IGZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIGRhdGFGaWxlLCBBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKTsKKworICAgIC8vIFRoZSBmaXJzdCBncm91cCBleHBpcmVzIDMwIGRheXMgZnJvbSBub3cuCisgICAgQ2FsZW5kYXIgbGF0ZXIgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuQVBSSUwsIDIwKS5idWlsZCgpOworICAgIGxvbmcgbGF0ZXJUaW1lU2VjcyA9IGxhdGVyLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMDsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlyc3RHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8xKQorICAgICAgICAgICAgLmFkZEZpbGUoZGF0YUZpbGUpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLk9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKGxhdGVyVGltZVNlY3MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIFRoZSBzZWNvbmQgZ3JvdXAgZXhwaXJlcyAxNSBkYXlzCisgICAgQ2FsZW5kYXIgc29vbmVyID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLkFQUklMLCA1KS5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBzZWNvbmRHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8yKQorICAgICAgICAgICAgLmFkZEZpbGUoZGF0YUZpbGUpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLk9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKHNvb25lci5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDApCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIExpc3Q8UGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPj4gZ3JvdXBzID0KKyAgICAgICAgQXJyYXlzLmFzTGlzdChQYWlyLmNyZWF0ZShURVNUX0tFWV8xLCBmaXJzdEdyb3VwKSwgUGFpci5jcmVhdGUoVEVTVF9LRVlfMiwgc2Vjb25kR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShncm91cHMpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRlc3RVcmkxKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KGZpbGVLZXkpKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5jaGlsZHJlbihkaXJGb3IwcCkpLnRoZW5SZXR1cm4oQXJyYXlzLmFzTGlzdCh0ZXN0VXJpMSkpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmNoaWxkcmVuKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeShkaXJGb3JBbGwpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZGVsZXRlRmlsZShhbnkoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cGRhdGVFeHBpcmF0aW9uX25vRXhwaXJlZFN0YWxlR3JvdXBzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQ2FsZW5kYXIgbm93ID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLk1BUkNILCAyMCkuYnVpbGQoKTsKKyAgICB0ZXN0Q2xvY2suc2V0KG5vdy5nZXRUaW1lSW5NaWxsaXMoKSk7CisKKyAgICBDYWxlbmRhciBsYXRlciA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjIpLmJ1aWxkKCk7CisgICAgTG9uZyBsYXRlclRpbWVTZWNzID0gbGF0ZXIuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwOworICAgIDsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzEsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0U3RhbGVMaWZldGltZVNlY3MobGF0ZXJUaW1lU2VjcyAtIChub3cuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwKSkKKyAgICAgICAgICAgIC5zZXRCb29ra2VlcGluZygKKyAgICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcubmV3QnVpbGRlcigpLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUobGF0ZXJUaW1lU2VjcykuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXApOworCisgICAgZmlsZUdyb3Vwc01ldGFkYXRhU3RhbGVHcm91cHMuc2V0KEltbXV0YWJsZUxpc3Qub2YoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMV0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMV0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMikpOworCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShBcnJheXMuYXNMaXN0KGZpbGVLZXlzKSkpOworICAgIHdoZW4obW9ja0JhY2tlbmQuY2hpbGRyZW4oZGlyRm9yMHApKS50aGVuUmV0dXJuKEFycmF5cy5hc0xpc3QodGVzdFVyaTEsIHRlc3RVcmkyKSk7CisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKGRhdGFGaWxlR3JvdXApKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhKS5nZXRBbGxGaWxlS2V5cygpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzBdKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5nZXRPbkRldmljZVVyaShmaWxlS2V5c1sxXSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmNoaWxkcmVuKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeShkaXJGb3JBbGwpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkoZGlyRm9yMXApOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZGVsZXRlRmlsZShhbnkoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cGRhdGVFeHBpcmF0aW9uX25vRXhwaXJlZFN0YWxlR3JvdXBzX25vdERlbGV0ZURpcigpIHRocm93cyBFeGNlcHRpb24geworICAgIENhbGVuZGFyIG5vdyA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjApLmJ1aWxkKCk7CisgICAgdGVzdENsb2NrLnNldChub3cuZ2V0VGltZUluTWlsbGlzKCkpOworCisgICAgQ2FsZW5kYXIgbGF0ZXIgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIyKS5idWlsZCgpOworICAgIGxvbmcgbGF0ZXJUaW1lU2VjcyA9IGxhdGVyLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMDsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzEsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0U3RhbGVMaWZldGltZVNlY3MobGF0ZXJUaW1lU2VjcyAtIChub3cuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwKSkKKyAgICAgICAgICAgIC5zZXRCb29ra2VlcGluZygKKyAgICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcubmV3QnVpbGRlcigpLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUobGF0ZXJUaW1lU2VjcykuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXApOworCisgICAgZmlsZUdyb3Vwc01ldGFkYXRhU3RhbGVHcm91cHMuc2V0KEltbXV0YWJsZUxpc3Qub2YoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0RGlyVXJpMSkpOworICAgIHdoZW4obW9ja0JhY2tlbmQuY2hpbGRyZW4odGVzdERpclVyaTEpKQorICAgICAgICAudGhlblJldHVybihBcnJheXMuYXNMaXN0KHRlc3REaXJGaWxlVXJpMSwgdGVzdERpckZpbGVVcmkyKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0RmlsZVN0YXR1cyhmaWxlS2V5c1sxXSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRPbkRldmljZVVyaShmaWxlS2V5c1sxXSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRlc3RVcmkyKSk7CisKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLmdldEFsbEZpbGVLZXlzKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEFycmF5cy5hc0xpc3QoZmlsZUtleXMpKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5jaGlsZHJlbihkaXJGb3IwcCkpLnRoZW5SZXR1cm4oQXJyYXlzLmFzTGlzdCh0ZXN0RGlyVXJpMSwgdGVzdFVyaTIpKTsKKyAgICBleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMykpLmdldEFsbEZyZXNoR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDIpKS5nZXRBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxHcm91cHNXaXRoS2V5cyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS53cml0ZVN0YWxlR3JvdXBzKEltbXV0YWJsZUxpc3Qub2YoZGF0YUZpbGVHcm91cCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMF0pOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzFdKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmV4aXN0cyhiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuY2hpbGRyZW4oYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmlzRGlyZWN0b3J5KGRpckZvckFsbCk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeShkaXJGb3IxcCk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5kZWxldGVGaWxlKGFueSgpKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVwZGF0ZUV4cGlyYXRpb25fZXhwaXJlZFN0YWxlR3JvdXBzX3Nob3J0ZXJTdGFsZUV4cGlyYXRpb25EYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQ2FsZW5kYXIgbm93ID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLk1BUkNILCAyMCkuYnVpbGQoKTsKKyAgICBDYWxlbmRhciBsYXRlciA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjIpLmJ1aWxkKCk7CisgICAgdGVzdENsb2NrLnNldChub3cuZ2V0VGltZUluTWlsbGlzKCkpOworCisgICAgTG9uZyBub3dUaW1lU2VjcyA9IG5vdy5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDA7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8xLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFN0YWxlTGlmZXRpbWVTZWNzKDApCisgICAgICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICAgICAgRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nLm5ld0J1aWxkZXIoKS5zZXRTdGFsZUV4cGlyYXRpb25EYXRlKG5vd1RpbWVTZWNzKS5idWlsZCgpKQorICAgICAgICAgICAgLnNldEV4cGlyYXRpb25EYXRlU2VjcyhsYXRlci5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDApCisgICAgICAgICAgICAuc2V0QnVpbGRJZCgxMCkKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoInRlc3RWYXJpYW50IikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXApOworCisgICAgZmlsZUdyb3Vwc01ldGFkYXRhU3RhbGVHcm91cHMuc2V0KEltbXV0YWJsZUxpc3Qub2YoZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMV0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMV0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMikpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoQXJyYXlzLmFzTGlzdChmaWxlS2V5cykpKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmNoaWxkcmVuKGRpckZvcjBwKSkudGhlblJldHVybihBcnJheXMuYXNMaXN0KHRlc3RVcmkxLCB0ZXN0VXJpMikpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikucmVtb3ZlRmlsZUVudHJ5KGZpbGVLZXlzWzBdKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5yZW1vdmVGaWxlRW50cnkoZmlsZUtleXNbMV0pOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZXhpc3RzKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5jaGlsZHJlbihiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdFVyaTEpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdFVyaTIpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZGVsZXRlRmlsZSh0ZXN0VXJpMSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5kZWxldGVGaWxlKHRlc3RVcmkyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVwZGF0ZUV4cGlyYXRpb25fZXhwaXJlZFN0YWxlR3JvdXBzX3Nob3J0ZXJFeHBpcmF0aW9uRGF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIENhbGVuZGFyIG5vdyA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjApLmJ1aWxkKCk7CisgICAgQ2FsZW5kYXIgbGF0ZXIgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIyKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIExvbmcgbm93VGltZVNlY3MgPSBub3cuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMSwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRCb29ra2VlcGluZygKKyAgICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRTdGFsZUV4cGlyYXRpb25EYXRlKGxhdGVyLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMCkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKG5vd1RpbWVTZWNzKQorICAgICAgICAgICAgLnNldEJ1aWxkSWQoMTApCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJ0ZXN0VmFyaWFudCIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBOZXdGaWxlS2V5W10gZmlsZUtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChkYXRhRmlsZUdyb3VwKTsKKworICAgIGZpbGVHcm91cHNNZXRhZGF0YVN0YWxlR3JvdXBzLnNldChJbW11dGFibGVMaXN0Lm9mKGRhdGFGaWxlR3JvdXApKTsKKworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMV0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMV0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMikpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoQXJyYXlzLmFzTGlzdChmaWxlS2V5cykpKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmNoaWxkcmVuKGRpckZvcjBwKSkudGhlblJldHVybihBcnJheXMuYXNMaXN0KHRlc3RVcmkxLCB0ZXN0VXJpMikpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikucmVtb3ZlRmlsZUVudHJ5KGZpbGVLZXlzWzBdKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5yZW1vdmVGaWxlRW50cnkoZmlsZUtleXNbMV0pOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZXhpc3RzKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5jaGlsZHJlbihiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdFVyaTEpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdFVyaTIpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZGVsZXRlRmlsZSh0ZXN0VXJpMSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5kZWxldGVGaWxlKHRlc3RVcmkyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVwZGF0ZUV4cGlyYXRpb25fZXhwaXJlZFN0YWxlR3JvdXBzX2RlbGV0ZUV4cGlyZWREaXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIENhbGVuZGFyIGxhdGVyID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLk1BUkNILCAyMikuYnVpbGQoKTsKKyAgICB0ZXN0Q2xvY2suc2V0KG5vdy5nZXRUaW1lSW5NaWxsaXMoKSk7CisgICAgbG9uZyBub3dUaW1lU2VjcyA9IG5vdy5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDA7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8xLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEJvb2trZWVwaW5nKAorICAgICAgICAgICAgICAgIERhdGFGaWxlR3JvdXBCb29ra2VlcGluZy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUobGF0ZXIuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5zZXRFeHBpcmF0aW9uRGF0ZVNlY3Mobm93VGltZVNlY3MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBOZXdGaWxlS2V5W10gZmlsZUtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChkYXRhRmlsZUdyb3VwKTsKKworICAgIGZpbGVHcm91cHNNZXRhZGF0YVN0YWxlR3JvdXBzLnNldChJbW11dGFibGVMaXN0Lm9mKGRhdGFGaWxlR3JvdXApKTsKKworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0RGlyVXJpMSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMV0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMV0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMikpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoQXJyYXlzLmFzTGlzdChmaWxlS2V5cykpKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmNoaWxkcmVuKGRpckZvcjFwKSkudGhlblJldHVybihBcnJheXMuYXNMaXN0KHRlc3REaXJVcmkxLCB0ZXN0VXJpMikpOworICAgIHdoZW4obW9ja0JhY2tlbmQuY2hpbGRyZW4odGVzdERpclVyaTEpKQorICAgICAgICAudGhlblJldHVybihBcnJheXMuYXNMaXN0KHRlc3REaXJGaWxlVXJpMSwgdGVzdERpckZpbGVVcmkyKSk7CisKKyAgICBleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMykpLmdldEFsbEZyZXNoR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDIpKS5nZXRBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxHcm91cHNXaXRoS2V5cyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS53cml0ZVN0YWxlR3JvdXBzKEltbXV0YWJsZUxpc3Qub2YoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YSkuZ2V0QWxsRmlsZUtleXMoKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5yZW1vdmVGaWxlRW50cnkoZmlsZUtleXNbMF0pOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLnJlbW92ZUZpbGVFbnRyeShmaWxlS2V5c1sxXSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmNoaWxkcmVuKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeSh0ZXN0RGlyVXJpMSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeSh0ZXN0RGlyRmlsZVVyaTEpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdERpckZpbGVVcmkyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmlzRGlyZWN0b3J5KHRlc3RVcmkyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmRlbGV0ZUZpbGUodGVzdERpckZpbGVVcmkxKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmRlbGV0ZUZpbGUodGVzdERpckZpbGVVcmkyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmRlbGV0ZUZpbGUodGVzdFVyaTIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdXBkYXRlRXhwaXJhdGlvbl9zaGFyZWRGaWxlc19zdGFsZUdyb3VwU29vbmVyRXhwaXJhdGlvbl9hY3RpdmVHcm91cExhdGVyRXhwaXJhdGlvbigpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlIGRhdGFGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGUiLCAwKTsKKyAgICBOZXdGaWxlS2V5IGZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIGRhdGFGaWxlLCBBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKTsKKworICAgIC8vIFRoZSBhY3RpdmUgZ3JvdXAgZXhwaXJlcyAzMCBkYXlzIGZyb20gbm93LgorICAgIENhbGVuZGFyIGxhdGVyID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLkFQUklMLCAyMCkuYnVpbGQoKTsKKyAgICBsb25nIGxhdGVyVGltZVNlY3MgPSBsYXRlci5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDA7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGFjdGl2ZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzEpCisgICAgICAgICAgICAuYWRkRmlsZShkYXRhRmlsZSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVyc0VudW0oQWxsb3dlZFJlYWRlcnMuT05MWV9HT09HTEVfUExBWV9TRVJWSUNFUykKKyAgICAgICAgICAgIC5zZXRFeHBpcmF0aW9uRGF0ZVNlY3MobGF0ZXJUaW1lU2VjcykKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gVGhlIHN0YWxlIGdyb3VwIGV4cGlyZXMgMiBkYXlzIGZyb20gbm93LgorICAgIENhbGVuZGFyIHNvb25lciA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjIpLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHN0YWxlR3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikKKyAgICAgICAgICAgIC5hZGRGaWxlKGRhdGFGaWxlKQorICAgICAgICAgICAgLnNldEFsbG93ZWRSZWFkZXJzRW51bShBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKQorICAgICAgICAgICAgLnNldEJvb2trZWVwaW5nKAorICAgICAgICAgICAgICAgIERhdGFGaWxlR3JvdXBCb29ra2VlcGluZy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUoc29vbmVyLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMCkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuc2V0U3RhbGVMaWZldGltZVNlY3MoKHNvb25lci5nZXRUaW1lSW5NaWxsaXMoKSAtIG5vdy5nZXRUaW1lSW5NaWxsaXMoKSkgLyAxMDAwKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBMaXN0PFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4+IGdyb3VwcyA9CisgICAgICAgIEFycmF5cy5hc0xpc3QoUGFpci5jcmVhdGUoVEVTVF9LRVlfMSwgYWN0aXZlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShncm91cHMpKTsKKworICAgIGZpbGVHcm91cHNNZXRhZGF0YVN0YWxlR3JvdXBzLnNldChJbW11dGFibGVMaXN0Lm9mKHN0YWxlR3JvdXApKTsKKworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRPbkRldmljZVVyaShmaWxlS2V5KSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTEpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLmdldEFsbEZpbGVLZXlzKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKENvbGxlY3Rpb25zLnNpbmdsZXRvbkxpc3QoZmlsZUtleSkpKTsKKyAgICBzZXRVcERpcmVjdG9yeU1vY2soZGlyRm9yMXAsIEFycmF5cy5hc0xpc3QodGVzdFVyaTEpKTsKKyAgICBzZXRVcEZpbGVNb2NrKHRlc3RVcmkxLCAxMDApOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKHN0YWxlR3JvdXApKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhKS5nZXRBbGxGaWxlS2V5cygpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLmdldE9uRGV2aWNlVXJpKGZpbGVLZXkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZXhpc3RzKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5jaGlsZHJlbihiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkoZGlyRm9yQWxsKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmRlbGV0ZUZpbGUoYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdXBkYXRlRXhwaXJhdGlvbl9zaGFyZWRGaWxlc19zdGFsZUdyb3VwTGF0ZXJFeHBpcmF0aW9uX2FjdGl2ZUdyb3VwU29vbmVyRXhwaXJhdGlvbigpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlIGRhdGFGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGUiLCAwKTsKKyAgICBOZXdGaWxlS2V5IGZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIGRhdGFGaWxlLCBBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKTsKKworICAgIC8vIFRoZSBhY3RpdmUgZ3JvdXAgZXhwaXJlcyAxIGRheSBmcm9tIG5vdy4KKyAgICBDYWxlbmRhciBzb29uZXIgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIxKS5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBhY3RpdmVHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8xKQorICAgICAgICAgICAgLmFkZEZpbGUoZGF0YUZpbGUpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLk9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKHNvb25lci5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDApCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIFRoZSBzdGFsZSBncm91cCBleHBpcmVzIDIgZGF5cyBmcm9tIG5vdy4KKyAgICBDYWxlbmRhciBsYXRlciA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjIpLmJ1aWxkKCk7CisgICAgbG9uZyBsYXRlclRpbWVTZWNzID0gbGF0ZXIuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBzdGFsZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzIpCisgICAgICAgICAgICAuYWRkRmlsZShkYXRhRmlsZSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVyc0VudW0oQWxsb3dlZFJlYWRlcnMuT05MWV9HT09HTEVfUExBWV9TRVJWSUNFUykKKyAgICAgICAgICAgIC5zZXRCb29ra2VlcGluZygKKyAgICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcubmV3QnVpbGRlcigpLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUobGF0ZXJUaW1lU2VjcykuYnVpbGQoKSkKKyAgICAgICAgICAgIC5zZXRTdGFsZUxpZmV0aW1lU2VjcyhsYXRlclRpbWVTZWNzIC0gbm93LmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMCkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBncm91cHMgPQorICAgICAgICBBcnJheXMuYXNMaXN0KFBhaXIuY3JlYXRlKFRFU1RfS0VZXzEsIGFjdGl2ZUdyb3VwKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZ3JvdXBzKSk7CisKKyAgICBmaWxlR3JvdXBzTWV0YWRhdGFTdGFsZUdyb3Vwcy5zZXQoSW1tdXRhYmxlTGlzdC5vZihzdGFsZUdyb3VwKSk7CisKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRlc3RVcmkxKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KGZpbGVLZXkpKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5jaGlsZHJlbihkaXJGb3IwcCkpLnRoZW5SZXR1cm4oQXJyYXlzLmFzTGlzdCh0ZXN0VXJpMSkpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKHN0YWxlR3JvdXApKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhKS5nZXRBbGxGaWxlS2V5cygpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLmdldE9uRGV2aWNlVXJpKGZpbGVLZXkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZXhpc3RzKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5jaGlsZHJlbihiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkoZGlyRm9yQWxsKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmRlbGV0ZUZpbGUoYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdXBkYXRlRXhwaXJhdGlvbl9zaGFyZWRGaWxlc19zdGFsZUdyb3VwX2FjdGl2ZUdyb3VwTm9FeHBpcmF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQ2FsZW5kYXIgbm93ID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLk1BUkNILCAyMCkuYnVpbGQoKTsKKyAgICB0ZXN0Q2xvY2suc2V0KG5vdy5nZXRUaW1lSW5NaWxsaXMoKSk7CisKKyAgICBEYXRhRmlsZSBkYXRhRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJmaWxlIiwgMCk7CisgICAgTmV3RmlsZUtleSBmaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoCisgICAgICAgICAgICBkYXRhRmlsZSwgQWxsb3dlZFJlYWRlcnMuT05MWV9HT09HTEVfUExBWV9TRVJWSUNFUyk7CisKKyAgICAvLyBUaGUgYWN0aXZlIGdyb3VwIG5ldmVyIGV4cGlyZXMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGFjdGl2ZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzEpCisgICAgICAgICAgICAuYWRkRmlsZShkYXRhRmlsZSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVyc0VudW0oQWxsb3dlZFJlYWRlcnMuT05MWV9HT09HTEVfUExBWV9TRVJWSUNFUykKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gVGhlIHN0YWxlIGdyb3VwIGV4cGlyZXMgMiBkYXlzIGZyb20gbm93LgorICAgIENhbGVuZGFyIHNvb25lciA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjIpLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHN0YWxlR3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikKKyAgICAgICAgICAgIC5hZGRGaWxlKGRhdGFGaWxlKQorICAgICAgICAgICAgLnNldEFsbG93ZWRSZWFkZXJzRW51bShBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKQorICAgICAgICAgICAgLnNldEJvb2trZWVwaW5nKAorICAgICAgICAgICAgICAgIERhdGFGaWxlR3JvdXBCb29ra2VlcGluZy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUoc29vbmVyLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMCkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuc2V0U3RhbGVMaWZldGltZVNlY3MoKHNvb25lci5nZXRUaW1lSW5NaWxsaXMoKSAtIG5vdy5nZXRUaW1lSW5NaWxsaXMoKSkgLyAxMDAwKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBMaXN0PFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4+IGdyb3VwcyA9CisgICAgICAgIEFycmF5cy5hc0xpc3QoUGFpci5jcmVhdGUoVEVTVF9LRVlfMSwgYWN0aXZlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShncm91cHMpKTsKKworICAgIGZpbGVHcm91cHNNZXRhZGF0YVN0YWxlR3JvdXBzLnNldChJbW11dGFibGVMaXN0Lm9mKHN0YWxlR3JvdXApKTsKKworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRPbkRldmljZVVyaShmaWxlS2V5KSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTEpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLmdldEFsbEZpbGVLZXlzKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKENvbGxlY3Rpb25zLnNpbmdsZXRvbkxpc3QoZmlsZUtleSkpKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmNoaWxkcmVuKGRpckZvcjBwKSkudGhlblJldHVybihBcnJheXMuYXNMaXN0KHRlc3RVcmkxKSk7CisKKyAgICBleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMykpLmdldEFsbEZyZXNoR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDIpKS5nZXRBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxHcm91cHNXaXRoS2V5cyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS53cml0ZVN0YWxlR3JvdXBzKEltbXV0YWJsZUxpc3Qub2Yoc3RhbGVHcm91cCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmNoaWxkcmVuKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeShkaXJGb3JBbGwpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZGVsZXRlRmlsZShhbnkoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cGRhdGVFeHBpcmF0aW9uX3NoYXJlZEZpbGVzX3N0YWxlR3JvdXBOb25FeHBpcmVkX2FjdGl2ZUdyb3VwRXhwaXJlZCgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlIGRhdGFGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGUiLCAwKTsKKyAgICBOZXdGaWxlS2V5IGZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIGRhdGFGaWxlLCBBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKTsKKworICAgIC8vIFRoZSBhY3RpdmUgZ3JvdXAgaXMgZXhwaXJlZC4KKyAgICBDYWxlbmRhciBzb29uZXIgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDE5KS5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBhY3RpdmVHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8xKQorICAgICAgICAgICAgLmFkZEZpbGUoZGF0YUZpbGUpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLk9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKHNvb25lci5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDApCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIFRoZSBzdGFsZSBncm91cCBleHBpcmVzIDIgZGF5cyBmcm9tIG5vdy4KKyAgICBDYWxlbmRhciBsYXRlciA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjIpLmJ1aWxkKCk7CisgICAgbG9uZyBsYXRlclRpbWVTZWNzID0gbGF0ZXIuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBzdGFsZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzIpCisgICAgICAgICAgICAuYWRkRmlsZShkYXRhRmlsZSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVyc0VudW0oQWxsb3dlZFJlYWRlcnMuT05MWV9HT09HTEVfUExBWV9TRVJWSUNFUykKKyAgICAgICAgICAgIC5zZXRCb29ra2VlcGluZygKKyAgICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcubmV3QnVpbGRlcigpLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUobGF0ZXJUaW1lU2VjcykuYnVpbGQoKSkKKyAgICAgICAgICAgIC5zZXRTdGFsZUxpZmV0aW1lU2VjcyhsYXRlclRpbWVTZWNzIC0gbm93LmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMCkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBncm91cHMgPQorICAgICAgICBBcnJheXMuYXNMaXN0KFBhaXIuY3JlYXRlKFRFU1RfS0VZXzEsIGFjdGl2ZUdyb3VwKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZ3JvdXBzKSk7CisKKyAgICBmaWxlR3JvdXBzTWV0YWRhdGFTdGFsZUdyb3Vwcy5zZXQoSW1tdXRhYmxlTGlzdC5vZihzdGFsZUdyb3VwKSk7CisKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRlc3RVcmkxKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KGZpbGVLZXkpKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5jaGlsZHJlbihkaXJGb3IwcCkpLnRoZW5SZXR1cm4oQXJyYXlzLmFzTGlzdCh0ZXN0VXJpMSkpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoQXJyYXlzLmFzTGlzdChURVNUX0tFWV8xKSk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLnJlbW92ZUFsbFN0YWxlR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLndyaXRlU3RhbGVHcm91cHMoSW1tdXRhYmxlTGlzdC5vZihzdGFsZUdyb3VwKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YSkuZ2V0QWxsRmlsZUtleXMoKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5nZXRPbkRldmljZVVyaShmaWxlS2V5KTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmV4aXN0cyhiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuY2hpbGRyZW4oYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmlzRGlyZWN0b3J5KGRpckZvckFsbCk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5kZWxldGVGaWxlKGFueSgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVwZGF0ZUV4cGlyYXRpb25fbXVsdGlwbGVFeHBpcmVkR3JvdXBzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgQ2FsZW5kYXIgbm93ID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLk1BUkNILCAyMCkuYnVpbGQoKTsKKyAgICB0ZXN0Q2xvY2suc2V0KG5vdy5nZXRUaW1lSW5NaWxsaXMoKSk7CisKKyAgICBEYXRhRmlsZSBkYXRhRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJmaWxlIiwgMCk7CisgICAgTmV3RmlsZUtleSBmaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoCisgICAgICAgICAgICBkYXRhRmlsZSwgQWxsb3dlZFJlYWRlcnMuT05MWV9HT09HTEVfUExBWV9TRVJWSUNFUyk7CisKKyAgICAvLyBEQVkgMCA6IFRoZSBmaXJzdEdyb3VwIGlzIGFjdGl2ZSBhbmQgd2lsbCBleHBpcmUgaW4gMzAgZGF5cy4KKyAgICBDYWxlbmRhciBlYXJsaWVyID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLk1BUkNILCAxOSkuYnVpbGQoKTsKKyAgICBMb25nIGVhcmxpZXJTZWNzID0gZWFybGllci5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDA7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpcnN0R3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMSkKKyAgICAgICAgICAgIC5hZGRGaWxlKGRhdGFGaWxlKQorICAgICAgICAgICAgLnNldEFsbG93ZWRSZWFkZXJzRW51bShBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKQorICAgICAgICAgICAgLnNldEV4cGlyYXRpb25EYXRlU2VjcyhlYXJsaWVyU2VjcykKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgQ2FsZW5kYXIgZWFybGllc3QgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDE4KS5idWlsZCgpOworICAgIExvbmcgZWFybGllc3RTZWNzID0gZWFybGllc3QuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBzZWNvbmRHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8yKQorICAgICAgICAgICAgLmFkZEZpbGUoZGF0YUZpbGUpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLk9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKGVhcmxpZXN0U2VjcykKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBncm91cHMgPQorICAgICAgICBBcnJheXMuYXNMaXN0KFBhaXIuY3JlYXRlKFRFU1RfS0VZXzEsIGZpcnN0R3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZ3JvdXBzKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoSW1tdXRhYmxlTGlzdC5vZigpKSk7CisKKyAgICBmaWxlR3JvdXBzTWV0YWRhdGFTdGFsZUdyb3Vwcy5zZXQoSW1tdXRhYmxlTGlzdC5vZihzZWNvbmRHcm91cCkpOworCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0RmlsZVN0YXR1cyhmaWxlS2V5KSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdChmaWxlS2V5KSkpOworICAgIHdoZW4obW9ja0JhY2tlbmQuY2hpbGRyZW4oZGlyRm9yMHApKQorICAgICAgICAudGhlblJldHVybihBcnJheXMuYXNMaXN0KHRlc3RVcmkxLCB0ZXN0VXJpMyAvKmFuIG9sZCBmaWxlIGxlZnQgb24gZGV2aWNlIHNvbWVob3cqLykpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoQXJyYXlzLmFzTGlzdChURVNUX0tFWV8xKSk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLnJlbW92ZUFsbFN0YWxlR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLndyaXRlU3RhbGVHcm91cHMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhKS5nZXRBbGxGaWxlS2V5cygpOworICAgIC8vIHVuc3Vic2NyaWJlIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbmNlIGV2ZW4gdGhvdWdoIHR3byBncm91cHMgcmVmZXJlbmNpbmcgZmlsZUtleSBoYXZlIGJvdGgKKyAgICAvLyBleHBpcmVkLgorICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLnJlbW92ZUZpbGVFbnRyeShmaWxlS2V5KTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmV4aXN0cyhiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuY2hpbGRyZW4oYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmlzRGlyZWN0b3J5KHRlc3RVcmkxKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmRlbGV0ZUZpbGUodGVzdFVyaTEpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdFVyaTMpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZGVsZXRlRmlsZSh0ZXN0VXJpMyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cGRhdGVFeHBpcmF0aW9uX211bHRpcGxlVGltZXNfd2l0aEdyb3VwVHJhbnNpdGlvbnMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlIGRhdGFGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGUiLCAwKTsKKyAgICBOZXdGaWxlS2V5IGZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIGRhdGFGaWxlLCBBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKTsKKworICAgIC8vIERBWSAwIDogVGhlIGZpcnN0R3JvdXAgaXMgYWN0aXZlIGFuZCB3aWxsIGV4cGlyZSBpbiAzMCBkYXlzLgorICAgIENhbGVuZGFyIGZpcnN0RXhwaXJhdGlvbiA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5BUFJJTCwgMjApLmJ1aWxkKCk7CisgICAgTG9uZyBmaXJzdEV4cGlyYXRpb25TZWNzID0gZmlyc3RFeHBpcmF0aW9uLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMDsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBmaXJzdEdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzEpCisgICAgICAgICAgICAuYWRkRmlsZShkYXRhRmlsZSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVyc0VudW0oQWxsb3dlZFJlYWRlcnMuT05MWV9HT09HTEVfUExBWV9TRVJWSUNFUykKKyAgICAgICAgICAgIC5zZXRFeHBpcmF0aW9uRGF0ZVNlY3MoZmlyc3RFeHBpcmF0aW9uU2Vjcyk7CisKKyAgICBMaXN0PFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4+IGdyb3VwcyA9CisgICAgICAgIEFycmF5cy5hc0xpc3QoUGFpci5jcmVhdGUoVEVTVF9LRVlfMSwgZmlyc3RHcm91cC5idWlsZCgpKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZ3JvdXBzKSk7CisKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRlc3RVcmkxKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KGZpbGVLZXkpKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5jaGlsZHJlbihkaXJGb3IwcCkpLnRoZW5SZXR1cm4oQXJyYXlzLmFzTGlzdCh0ZXN0VXJpMSkpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmNoaWxkcmVuKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeShkaXJGb3JBbGwpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZGVsZXRlRmlsZShhbnkoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisKKyAgICAvLyBEQVkgMSA6IGZpcnN0R3JvdXAgYmVjb21lcyBzdGFsZSBhbmQgc2hvdWxkIGV4cGlyZSBpbiAyIGRheXMuCisgICAgbm93ID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLk1BUkNILCAyMSkuYnVpbGQoKTsKKyAgICB0ZXN0Q2xvY2suc2V0KG5vdy5nZXRUaW1lSW5NaWxsaXMoKSk7CisKKyAgICBDYWxlbmRhciBmaXJzdFN0YWxlRXhwaXJhdGlvbiA9CisgICAgICAgIG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjMpLmJ1aWxkKCk7CisgICAgbG9uZyBmaXJzdFN0YWxlRXhwaXJhdGlvblNlY3MgPSBmaXJzdFN0YWxlRXhwaXJhdGlvbi5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDA7CisgICAgZmlyc3RHcm91cAorICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUoZmlyc3RTdGFsZUV4cGlyYXRpb25TZWNzKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAuc2V0U3RhbGVMaWZldGltZVNlY3MoZmlyc3RTdGFsZUV4cGlyYXRpb25TZWNzIC0gKG5vdy5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDApKTsKKworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShJbW11dGFibGVMaXN0Lm9mKCkpKTsKKworICAgIGZpbGVHcm91cHNNZXRhZGF0YVN0YWxlR3JvdXBzLnNldChJbW11dGFibGVMaXN0Lm9mKGZpcnN0R3JvdXAuYnVpbGQoKSkpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDYpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcyg0KSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMikpLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKEltbXV0YWJsZUxpc3Qub2YoKSk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDIpKS5yZW1vdmVBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS53cml0ZVN0YWxlR3JvdXBzKEltbXV0YWJsZUxpc3Qub2YoZmlyc3RHcm91cC5idWlsZCgpKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIsIHRpbWVzKDIpKS5nZXRPbkRldmljZVVyaShmaWxlS2V5KTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEsIHRpbWVzKDIpKS5nZXRBbGxGaWxlS2V5cygpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgdGltZXMoMikpLmV4aXN0cyhiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgdGltZXMoMikpLmNoaWxkcmVuKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCB0aW1lcygyKSkuaXNEaXJlY3RvcnkoZGlyRm9yMXApOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZGVsZXRlRmlsZShhbnkoKSk7CisKKyAgICAvLyBEQVkgMiA6IHNlY29uZEdyb3VwIGFycml2ZXMgYW5kIHJlcXVlc3RzIHRoZSBzaGFyZWQgZmlsZS4KKyAgICBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIyKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIENhbGVuZGFyIHNlY29uZEV4cGlyYXRpb24gPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuQVBSSUwsIDIyKS5idWlsZCgpOworICAgIGxvbmcgc2Vjb25kRXhwaXJhdGlvblNlY3MgPSBzZWNvbmRFeHBpcmF0aW9uLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMDsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgc2Vjb25kR3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikKKyAgICAgICAgICAgIC5hZGRGaWxlKGRhdGFGaWxlKQorICAgICAgICAgICAgLnNldEFsbG93ZWRSZWFkZXJzRW51bShBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKQorICAgICAgICAgICAgLnNldEV4cGlyYXRpb25EYXRlU2VjcyhzZWNvbmRFeHBpcmF0aW9uU2VjcykKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgZ3JvdXBzID0gQXJyYXlzLmFzTGlzdChQYWlyLmNyZWF0ZShURVNUX0tFWV8yLCBzZWNvbmRHcm91cCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGdyb3VwcykpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDkpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcyg2KSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMykpLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKEltbXV0YWJsZUxpc3Qub2YoKSk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDMpKS5yZW1vdmVBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKGZpcnN0R3JvdXAuYnVpbGQoKSkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyLCB0aW1lcygzKSkuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLCB0aW1lcygzKSkuZ2V0QWxsRmlsZUtleXMoKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIHRpbWVzKDMpKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIHRpbWVzKDMpKS5jaGlsZHJlbihiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgdGltZXMoMykpLmlzRGlyZWN0b3J5KGRpckZvcjBwKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmRlbGV0ZUZpbGUoYW55KCkpOworCisgICAgLy8gREFZIDMgOiB0aGUgZmlyc3RHcm91cCBleHBpcmVzCisgICAgbm93ID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLk1BUkNILCAyMikuYnVpbGQoKTsKKyAgICB0ZXN0Q2xvY2suc2V0KG5vdy5nZXRUaW1lSW5NaWxsaXMoKSk7CisKKyAgICBleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMTIpKS5nZXRBbGxGcmVzaEdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcyg4KSkuZ2V0QWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoNCkpLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKEltbXV0YWJsZUxpc3Qub2YoKSk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDQpKS5yZW1vdmVBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygzKSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKGZpcnN0R3JvdXAuYnVpbGQoKSkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyLCB0aW1lcyg0KSkuZ2V0T25EZXZpY2VVcmkoZmlsZUtleSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLCB0aW1lcyg0KSkuZ2V0QWxsRmlsZUtleXMoKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIHRpbWVzKDQpKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIHRpbWVzKDQpKS5jaGlsZHJlbihiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgdGltZXMoNCkpLmlzRGlyZWN0b3J5KGRpckZvckFsbCk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5kZWxldGVGaWxlKGFueSgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVwZGF0ZUV4cGlyYXRpb25fZXhwaXJlZEdyb3Vwc193aXRoQW5kcm9pZFNoYXJlZEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzZXR1cEZvckFuZHJvaWRTaGFyZWQoKTsKKyAgICAvLyBDdXJyZW50IHRpbWUKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAyMCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMSwgMSk7CisgICAgLy8gVGltZSB3aGVuIHRoZSBncm91cCBleHBpcmVzCisgICAgQ2FsZW5kYXIgZWFybGllciA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjApLmJ1aWxkKCk7CisgICAgbG9uZyBub3dUaW1lU2VjcyA9IGVhcmxpZXIuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwOworICAgIGRhdGFGaWxlR3JvdXAgPSBkYXRhRmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldEV4cGlyYXRpb25EYXRlU2Vjcyhub3dUaW1lU2VjcykuYnVpbGQoKTsKKyAgICBOZXdGaWxlS2V5W10gZmlsZUtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChkYXRhRmlsZUdyb3VwKTsKKyAgICBTdHJpbmcgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSA9ICJzaGEyNTZfIiArIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRDaGVja3N1bSgpOworICAgIFVyaSBibG9iVXJpID0gRGlyZWN0b3J5VXRpbC5nZXRCbG9iVXJpKGNvbnRleHQsIGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0pOworCisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlTWFuYWdlci5yZXNlcnZlRmlsZUVudHJ5KGZpbGVLZXlzWzBdKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyCisgICAgICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyZWREb3dubG9hZGVkRmlsZUVudHJ5KAorICAgICAgICAgICAgICAgICAgICBmaWxlS2V5c1swXSwgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSwgbm93VGltZVNlY3MpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUoVEVTVF9LRVlfMSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXJOb01vY2tzLnVwZGF0ZUV4cGlyYXRpb24oKS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrQmxvYlN0b3JlQmFja2VuZCkuZGVsZXRlRmlsZShibG9iVXJpKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChmaWxlS2V5c1swXSkuZ2V0KCkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoVEVTVF9LRVlfMSkuZ2V0KCkpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdXBkYXRlRXhwaXJhdGlvbl9leHBpcmVkR3JvdXBzX3dpdGhBbmRyb2lkU2hhcmVkRmlsZV9yZWxlYXNlTGVhc2VGYWlscygpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzZXR1cEZvckFuZHJvaWRTaGFyZWQoKTsKKyAgICAvLyBDdXJyZW50IHRpbWUKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAyMCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMSwgMSk7CisgICAgLy8gVGltZSB3aGVuIHRoZSBncm91cCBleHBpcmVzCisgICAgQ2FsZW5kYXIgZWFybGllciA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjApLmJ1aWxkKCk7CisgICAgbG9uZyBub3dUaW1lU2VjcyA9IGVhcmxpZXIuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwOworICAgIGRhdGFGaWxlR3JvdXAgPSBkYXRhRmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldEV4cGlyYXRpb25EYXRlU2Vjcyhub3dUaW1lU2VjcykuYnVpbGQoKTsKKyAgICBOZXdGaWxlS2V5W10gZmlsZUtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChkYXRhRmlsZUdyb3VwKTsKKyAgICBTdHJpbmcgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSA9ICJzaGEyNTZfIiArIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRDaGVja3N1bSgpOworICAgIFVyaSBibG9iVXJpID0gRGlyZWN0b3J5VXRpbC5nZXRCbG9iVXJpKGNvbnRleHQsIGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0pOworCisgICAgZG9UaHJvdyhuZXcgSU9FeGNlcHRpb24oKSkud2hlbihtb2NrQmxvYlN0b3JlQmFja2VuZCkuZGVsZXRlRmlsZShibG9iVXJpKTsKKworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZU1hbmFnZXIucmVzZXJ2ZUZpbGVFbnRyeShmaWxlS2V5c1swXSkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBzaGFyZWRGaWxlTWFuYWdlcgorICAgICAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkRG93bmxvYWRlZEZpbGVFbnRyeSgKKyAgICAgICAgICAgICAgICAgICAgZmlsZUtleXNbMF0sIGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0sIG5vd1RpbWVTZWNzKQorICAgICAgICAgICAgICAgIC5nZXQoKSkKKyAgICAgICAgLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLndyaXRlKFRFU1RfS0VZXzEsIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKworICAgIGV4cGlyYXRpb25IYW5kbGVyTm9Nb2Nrcy51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0Jsb2JTdG9yZUJhY2tlbmQpLmRlbGV0ZUZpbGUoYmxvYlVyaSk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQoZmlsZUtleXNbMF0pLmdldCgpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKFRFU1RfS0VZXzEpLmdldCgpKS5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVwZGF0ZUV4cGlyYXRpb25fZXhwaXJlZEdyb3Vwc193aXRoQW5kcm9pZFNoYXJlZEFuZE5vdEFuZHJvaWRTaGFyZWRGaWxlcygpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzZXR1cEZvckFuZHJvaWRTaGFyZWQoKTsKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMSwgMik7CisgICAgbG9uZyBub3dUaW1lU2VjcyA9IG5vdy5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDA7CisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKG5vd1RpbWVTZWNzKS5idWlsZCgpOworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXApOworICAgIFN0cmluZyBhbmRyb2lkU2hhcmluZ0NoZWNrc3VtID0gInNoYTI1Nl8iICsgZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLmdldENoZWNrc3VtKCk7CisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSk7CisKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLnJlc2VydmVGaWxlRW50cnkoZmlsZUtleXNbMF0pLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLnJlc2VydmVGaWxlRW50cnkoZmlsZUtleXNbMV0pLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgc2hhcmVkRmlsZU1hbmFnZXIKKyAgICAgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJlZERvd25sb2FkZWRGaWxlRW50cnkoCisgICAgICAgICAgICAgICAgICAgIGZpbGVLZXlzWzBdLCBhbmRyb2lkU2hhcmluZ0NoZWNrc3VtLCBub3dUaW1lU2VjcykKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZShURVNUX0tFWV8xLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmNoaWxkcmVuKGRpckZvcjBwKSkudGhlblJldHVybihBcnJheXMuYXNMaXN0KHRlc3RVcmkyKSk7CisKKyAgICBleHBpcmF0aW9uSGFuZGxlck5vTW9ja3MudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5kZWxldGVGaWxlKHRlc3RVcmkyKTsKKyAgICB2ZXJpZnkobW9ja0Jsb2JTdG9yZUJhY2tlbmQpLmRlbGV0ZUZpbGUoYmxvYlVyaSk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQoZmlsZUtleXNbMF0pLmdldCgpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChmaWxlS2V5c1sxXSkuZ2V0KCkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoVEVTVF9LRVlfMSkuZ2V0KCkpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdXBkYXRlRXhwaXJhdGlvbl9ub0V4cGlyZWRBbmRyb2lkU2hhcmVkR3JvdXBfd2l0aFVuYWNjb3VudGVkRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHNldHVwRm9yQW5kcm9pZFNoYXJlZCgpOworICAgIENhbGVuZGFyIG5vdyA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjApLmJ1aWxkKCk7CisgICAgdGVzdENsb2NrLnNldChub3cuZ2V0VGltZUluTWlsbGlzKCkpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8xLCAxKTsKKyAgICAvLyBObyBjaGFuZ2VzIHRvIGRhdGFGaWxlR3JvdXAKKyAgICBOZXdGaWxlS2V5W10gZmlsZUtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChkYXRhRmlsZUdyb3VwKTsKKyAgICBTdHJpbmcgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSA9IGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCk7CisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgYW5kcm9pZFNoYXJpbmdDaGVja3N1bSk7CisKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLnJlc2VydmVGaWxlRW50cnkoZmlsZUtleXNbMF0pLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgc2hhcmVkRmlsZU1hbmFnZXIKKyAgICAgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJlZERvd25sb2FkZWRGaWxlRW50cnkoZmlsZUtleXNbMF0sIGFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0sIDApCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUoVEVTVF9LRVlfMSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgLy8gVW5hY2NvdW50ZWQgZmlsZQorICAgIHdoZW4obW9ja0JhY2tlbmQuY2hpbGRyZW4oZGlyRm9yMHApKS50aGVuUmV0dXJuKEFycmF5cy5hc0xpc3QodGVtcFRlc3RVcmkyKSk7CisKKyAgICBleHBpcmF0aW9uSGFuZGxlck5vTW9ja3MudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChURVNUX0tFWV8xKS5nZXQoKSkuaXNOb3ROdWxsKCk7CisgICAgdmVyaWZ5KG1vY2tCbG9iU3RvcmVCYWNrZW5kLCBuZXZlcigpKS5kZWxldGVGaWxlKGJsb2JVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZGVsZXRlRmlsZSh0ZW1wVGVzdFVyaTIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdXBkYXRlRXhwaXJhdGlvbl9leHBpcmVkR3JvdXBzX3dpdGhJc29sYXRlZFN0cnVjdHVyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHNldHVwSXNvbGF0ZWRTeW1saW5rU3RydWN0dXJlKCk7CisKKyAgICAvLyBDdXJyZW50IHRpbWUKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAyMCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIHRlc3RDbG9jay5zZXQobm93LmdldFRpbWVJbk1pbGxpcygpKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMSwgMSk7CisgICAgLy8gVGltZSB3aGVuIHRoZSBncm91cCBleHBpcmVzCisgICAgQ2FsZW5kYXIgZWFybGllciA9IG5ldyBDYWxlbmRhci5CdWlsZGVyKCkuc2V0RGF0ZSgyMDE4LCBDYWxlbmRhci5NQVJDSCwgMjApLmJ1aWxkKCk7CisgICAgbG9uZyBlYXJsaWVyVGltZVNlY3MgPSBlYXJsaWVyLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMDsKKyAgICBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgZGF0YUZpbGVHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEV4cGlyYXRpb25EYXRlU2VjcyhlYXJsaWVyVGltZVNlY3MpCisgICAgICAgICAgICAuc2V0UHJlc2VydmVGaWxlbmFtZXNBbmRJc29sYXRlRmlsZXModHJ1ZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgTmV3RmlsZUtleVtdIGZpbGVLZXlzID0gTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwoZGF0YUZpbGVHcm91cCk7CisKKyAgICBMaXN0PFBhaXI8R3JvdXBLZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbD4+IGdyb3VwcyA9CisgICAgICAgIEFycmF5cy5hc0xpc3QoUGFpci5jcmVhdGUoVEVTVF9LRVlfMSwgZGF0YUZpbGVHcm91cCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShncm91cHMpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShuZXcgQXJyYXlMaXN0PD4oKSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMSkpOworCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShBcnJheXMuYXNMaXN0KGZpbGVLZXlzKSkpOworICAgIHdoZW4obW9ja0JhY2tlbmQuY2hpbGRyZW4oZGlyRm9yMHApKS50aGVuUmV0dXJuKEFycmF5cy5hc0xpc3QodGVzdFVyaTEpKTsKKyAgICBleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMykpLmdldEFsbEZyZXNoR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDIpKS5nZXRBbGxTdGFsZUdyb3VwcygpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmVBbGxHcm91cHNXaXRoS2V5cyhBcnJheXMuYXNMaXN0KFRFU1RfS0VZXzEpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlQWxsU3RhbGVHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkud3JpdGVTdGFsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKCkpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEpLmdldEFsbEZpbGVLZXlzKCk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikucmVtb3ZlRmlsZUVudHJ5KGZpbGVLZXlzWzBdKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmV4aXN0cyhiYXNlRG93bmxvYWREaXJlY3RvcnlVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuY2hpbGRyZW4oYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmlzRGlyZWN0b3J5KHRlc3RVcmkxKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmRlbGV0ZUZpbGUodGVzdFVyaTEpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgdGltZXMoMikpLmV4aXN0cyhzeW1saW5rRGlyRm9yR3JvdXAxKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIHRpbWVzKDIpKS5pc0RpcmVjdG9yeShzeW1saW5rRGlyRm9yR3JvdXAxKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmRlbGV0ZURpcmVjdG9yeShzeW1saW5rRGlyRm9yR3JvdXAxKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHVwZGF0ZUV4cGlyYXRpb25fbm9FeHBpcmVkR3JvdXBzX2RvZXNOb3RSZW1vdmVJc29sYXRlZFN0cnVjdHVyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENyZWF0ZSBncm91cCB0aGF0IGhhcyBpc29sYXRlZCBzdHJ1Y3R1cmUKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzEsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0UHJlc2VydmVGaWxlbmFtZXNBbmRJc29sYXRlRmlsZXModHJ1ZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgTmV3RmlsZUtleVtdIGZpbGVLZXlzID0gTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwoZGF0YUZpbGVHcm91cCk7CisKKyAgICAvLyBTZXR1cCBtb2NrcyB0byByZXR1cm4gb3VyIGZyZXNoIGdyb3VwCisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBncm91cHMgPQorICAgICAgICBBcnJheXMuYXNMaXN0KFBhaXIuY3JlYXRlKFRFU1RfS0VZXzEsIGRhdGFGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShncm91cHMpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodGVzdFVyaTEpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLmdldEFsbEZpbGVLZXlzKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEFycmF5cy5hc0xpc3QoZmlsZUtleXMpKSk7CisKKyAgICBleHBpcmF0aW9uSGFuZGxlci51cGRhdGVFeHBpcmF0aW9uKCkuZ2V0KCk7CisKKyAgICAvLyBWZXJpZnkgZmlsZSBpcyBub3QgZGVsZXRlZAorICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZGVsZXRlRmlsZSh0ZXN0VXJpMSk7CisKKyAgICAvLyBWZXJpZnkgc3ltbGlua3MgYXJlIG5vdCBjb25zaWRlcmVkIGZvciBkZWxldGlvbjoKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmV4aXN0cyhzeW1saW5rRGlyRm9yR3JvdXAxKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmlzRGlyZWN0b3J5KHN5bWxpbmtEaXJGb3JHcm91cDEpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZGVsZXRlRGlyZWN0b3J5KHN5bWxpbmtEaXJGb3JHcm91cDEpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZXhpc3RzKHN5bWxpbmtGb3JVcmkxKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmlzRGlyZWN0b3J5KHN5bWxpbmtGb3JVcmkxKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmRlbGV0ZUZpbGUoc3ltbGlua0ZvclVyaTEpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdXBkYXRlRXhwaXJhdGlvbl9leHBpcmVkU3RhbGVHcm91cF93aXRoSXNvbGF0ZWRTdHJ1Y3R1cmVfZGVsZXRlc0ZpbGVzKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIHNldHVwSXNvbGF0ZWRTeW1saW5rU3RydWN0dXJlKCk7CisKKyAgICBDYWxlbmRhciBub3cgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMjAxOCwgQ2FsZW5kYXIuTUFSQ0gsIDIwKS5idWlsZCgpOworICAgIENhbGVuZGFyIGxhdGVyID0gbmV3IENhbGVuZGFyLkJ1aWxkZXIoKS5zZXREYXRlKDIwMTgsIENhbGVuZGFyLk1BUkNILCAyMikuYnVpbGQoKTsKKyAgICB0ZXN0Q2xvY2suc2V0KG5vdy5nZXRUaW1lSW5NaWxsaXMoKSk7CisgICAgbG9uZyBub3dUaW1lU2VjcyA9IG5vdy5nZXRUaW1lSW5NaWxsaXMoKSAvIDEwMDA7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8xLCAxKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEJvb2trZWVwaW5nKAorICAgICAgICAgICAgICAgIERhdGFGaWxlR3JvdXBCb29ra2VlcGluZy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUobGF0ZXIuZ2V0VGltZUluTWlsbGlzKCkgLyAxMDAwKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5zZXRFeHBpcmF0aW9uRGF0ZVNlY3Mobm93VGltZVNlY3MpCisgICAgICAgICAgICAuc2V0UHJlc2VydmVGaWxlbmFtZXNBbmRJc29sYXRlRmlsZXModHJ1ZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXApOworCisgICAgZmlsZUdyb3Vwc01ldGFkYXRhU3RhbGVHcm91cHMuc2V0KEltbXV0YWJsZUxpc3Qub2YoZGF0YUZpbGVHcm91cCkpOworCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0RmlsZVN0YXR1cyhmaWxlS2V5c1swXSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRPbkRldmljZVVyaShmaWxlS2V5c1swXSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRlc3REaXJVcmkxKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShBcnJheXMuYXNMaXN0KGZpbGVLZXlzKSkpOworICAgIHdoZW4obW9ja0JhY2tlbmQuY2hpbGRyZW4oZGlyRm9yMXApKS50aGVuUmV0dXJuKEFycmF5cy5hc0xpc3QodGVzdERpclVyaTEsIHRlc3RVcmkyKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5jaGlsZHJlbih0ZXN0RGlyVXJpMSkpCisgICAgICAgIC50aGVuUmV0dXJuKEFycmF5cy5hc0xpc3QodGVzdERpckZpbGVVcmkxLCB0ZXN0RGlyRmlsZVVyaTIpKTsKKworICAgIGV4cGlyYXRpb25IYW5kbGVyLnVwZGF0ZUV4cGlyYXRpb24oKS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygzKSkuZ2V0QWxsRnJlc2hHcm91cHMoKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMikpLmdldEFsbFN0YWxlR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKEltbXV0YWJsZUxpc3Qub2YoKSk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLnJlbW92ZUFsbFN0YWxlR3JvdXBzKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEpLndyaXRlU3RhbGVHcm91cHMoSW1tdXRhYmxlTGlzdC5vZigpKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhKS5nZXRBbGxGaWxlS2V5cygpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLnJlbW92ZUZpbGVFbnRyeShmaWxlS2V5c1swXSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmFzZURvd25sb2FkRGlyZWN0b3J5VXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmNoaWxkcmVuKGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeSh0ZXN0RGlyVXJpMSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5pc0RpcmVjdG9yeSh0ZXN0RGlyRmlsZVVyaTEpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuaXNEaXJlY3RvcnkodGVzdERpckZpbGVVcmkyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIHRpbWVzKDIpKS5leGlzdHMoc3ltbGlua0RpckZvckdyb3VwMSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCB0aW1lcygyKSkuaXNEaXJlY3Rvcnkoc3ltbGlua0RpckZvckdyb3VwMSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5kZWxldGVEaXJlY3Rvcnkoc3ltbGlua0RpckZvckdyb3VwMSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB1cGRhdGVFeHBpcmF0aW9uX25vRXhwaXJlZEdyb3Vwc19yZW1vdmVzVW5hY2NvdW50ZWRJc29sYXRlZEZpbGVVcmkoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc2V0dXBJc29sYXRlZFN5bWxpbmtTdHJ1Y3R1cmUoKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBpc29sYXRlZEdyb3VwMSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzEsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0UHJlc2VydmVGaWxlbmFtZXNBbmRJc29sYXRlRmlsZXModHJ1ZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXlbXSBmaWxlS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGlzb2xhdGVkR3JvdXAxKTsKKworICAgIExpc3Q8UGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPj4gZ3JvdXBzID0KKyAgICAgICAgQXJyYXlzLmFzTGlzdChQYWlyLmNyZWF0ZShURVNUX0tFWV8xLCBpc29sYXRlZEdyb3VwMSkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGdyb3VwcykpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZUtleXNbMF0pKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0ZXN0VXJpMSkpOworCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShBcnJheXMuYXNMaXN0KGZpbGVLZXlzKSkpOworCisgICAgZXhwaXJhdGlvbkhhbmRsZXIudXBkYXRlRXhwaXJhdGlvbigpLmdldCgpOworCisgICAgLy8gVmVyaWZ5IG9ubHkgdGhlIHVuYWNjb3VudGVkIGlzb2xhdGVkIGZpbGUgdXJpIGlzIGRlbGV0ZWQuCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5kZWxldGVGaWxlKHN5bWxpbmtGb3JVcmkyKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmRlbGV0ZUZpbGUoc3ltbGlua0ZvclVyaTEpOworICB9CisKKyAgLy8gVE9ETyhiLzExNTY1OTk4MCk6IGNvbnNpZGVyIG1vdmluZyB0aGlzIHRvIGEgcHVibGljIHV0aWxpdHkgY2xhc3MgaW4gdGhlIEZpbGUgTGlicmFyeQorICBwcml2YXRlIHZvaWQgc2V0VXBGaWxlTW9jayhVcmkgdXJpLCBsb25nIHNpemUpIHRocm93cyBFeGNlcHRpb24geworICAgIHdoZW4obW9ja0JhY2tlbmQuZXhpc3RzKHVyaSkpLnRoZW5SZXR1cm4odHJ1ZSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5pc0RpcmVjdG9yeSh1cmkpKS50aGVuUmV0dXJuKGZhbHNlKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmZpbGVTaXplKHVyaSkpLnRoZW5SZXR1cm4oc2l6ZSk7CisgIH0KKworICAvLyBUT0RPKGIvMTE1NjU5OTgwKTogY29uc2lkZXIgbW92aW5nIHRoaXMgdG8gYSBwdWJsaWMgdXRpbGl0eSBjbGFzcyBpbiB0aGUgRmlsZSBMaWJyYXJ5CisgIHByaXZhdGUgdm9pZCBzZXRVcERpcmVjdG9yeU1vY2soVXJpIHVyaSwgTGlzdDxVcmk+IGNoaWxkcmVuKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmV4aXN0cyh1cmkpKS50aGVuUmV0dXJuKHRydWUpOworICAgIHdoZW4obW9ja0JhY2tlbmQuaXNEaXJlY3RvcnkodXJpKSkudGhlblJldHVybih0cnVlKTsKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmNoaWxkcmVuKHVyaSkpLnRoZW5SZXR1cm4oY2hpbGRyZW4pOworICB9CisKKyAgcHJpdmF0ZSBOZXdGaWxlS2V5W10gY3JlYXRlRmlsZUtleXNVc2VDaGVja3N1bU9ubHkoRGF0YUZpbGVHcm91cEludGVybmFsIGdyb3VwKSB7CisgICAgTmV3RmlsZUtleVtdIG5ld0ZpbGVLZXlzID0gbmV3IE5ld0ZpbGVLZXlbZ3JvdXAuZ2V0RmlsZUNvdW50KCldOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ3JvdXAuZ2V0RmlsZUNvdW50KCk7ICsraSkgeworICAgICAgbmV3RmlsZUtleXNbaV0gPQorICAgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlRm9yQ3VycmVudFZlcnNpb24oCisgICAgICAgICAgICAgIGNvbnRleHQsIGdyb3VwLmdldEZpbGUoaSksIGdyb3VwLmdldEFsbG93ZWRSZWFkZXJzRW51bSgpLCBtb2NrU2lsZW50RmVlZGJhY2spOworICAgIH0KKyAgICByZXR1cm4gbmV3RmlsZUtleXM7CisgIH0KKworICBwcml2YXRlIHZvaWQgc2V0dXBJc29sYXRlZFN5bWxpbmtTdHJ1Y3R1cmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzZXRVcERpcmVjdG9yeU1vY2soCisgICAgICAgIGJhc2VEb3dubG9hZERpcmVjdG9yeVVyaSwKKyAgICAgICAgQXJyYXlzLmFzTGlzdChkaXJGb3JBbGwsIGRpckZvcjFwLCBkaXJGb3IwcCwgYmFzZURvd25sb2FkU3ltbGlua0RpcmVjdG9yeVVyaSkpOworICAgIHNldFVwRGlyZWN0b3J5TW9jaygKKyAgICAgICAgYmFzZURvd25sb2FkU3ltbGlua0RpcmVjdG9yeVVyaSwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihzeW1saW5rRGlyRm9yR3JvdXAxLCBzeW1saW5rRGlyRm9yR3JvdXAyKSk7CisgICAgc2V0VXBEaXJlY3RvcnlNb2NrKHN5bWxpbmtEaXJGb3JHcm91cDEsIEltbXV0YWJsZUxpc3Qub2Yoc3ltbGlua0ZvclVyaTEpKTsKKyAgICBzZXRVcERpcmVjdG9yeU1vY2soc3ltbGlua0RpckZvckdyb3VwMiwgSW1tdXRhYmxlTGlzdC5vZihzeW1saW5rRm9yVXJpMikpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvRmlsZUdyb3VwTWFuYWdlclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9GaWxlR3JvdXBNYW5hZ2VyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2N2JjODEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvRmlsZUdyb3VwTWFuYWdlclRlc3QuamF2YQpAQCAtMCwwICsxLDYyNzQgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1kZFRlc3RVdGlsLndyaXRlU2hhcmVkRmlsZXM7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFdpdGhNZXNzYWdlOworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuYW55SW50OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueUxpc3Q7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuYW55TG9uZzsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5lcTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5pc0E7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ubmV2ZXI7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udGltZXM7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnZlcmlmeU5vTW9yZUludGVyYWN0aW9uczsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by53aGVuOworCitpbXBvcnQgYW5kcm9pZC5hY2NvdW50cy5BY2NvdW50OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5wbS5QYWNrYWdlSW5mbzsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQucG0uUGFja2FnZU1hbmFnZXI7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQ7CitpbXBvcnQgYW5kcm9pZC51dGlsLlBhaXI7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkFjY291bnRTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuQWdncmVnYXRlRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uLkRvd25sb2FkUmVzdWx0Q29kZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GaWxlU291cmNlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlNpbGVudEZlZWRiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmFjY291bnQuQWNjb3VudFV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuQW5kcm9pZEZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLkxpbWl0RXhjZWVkZWRFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5zcGkuQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5GaWxlR3JvdXBNYW5hZ2VyLkdyb3VwRG93bmxvYWRTdGF0dXM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZG93bmxvYWRlci5Eb3dubG9hZGVyQ2FsbGJhY2tJbXBsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmRvd25sb2FkZXIuTWRkRmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZXhwZXJpbWVudGF0aW9uLkRvd25sb2FkU3RhZ2VNYW5hZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmV4cGVyaW1lbnRhdGlvbi5Ob09wRG93bmxvYWRTdGFnZU1hbmFnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5FdmVudExvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLkRpcmVjdG9yeVV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5GaWxlR3JvdXBVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuRG93bmxvYWRQcm9ncmVzc01vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5GYWtlVGltZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLlRlc3RGbGFnczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZU1hcDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0Lkxpc3RzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmxhYnMuY29uY3VycmVudC5MYWJzRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5Db3JyZXNwb25kZW5jZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQXN5bmNGdW5jdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsLkFsbG93ZWRSZWFkZXJzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRG93bmxvYWRDb25kaXRpb25zOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRG93bmxvYWRDb25kaXRpb25zLkFjdGl2YXRpbmdDb25kaXRpb247CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Eb3dubG9hZENvbmRpdGlvbnMuRGV2aWNlTmV0d29ya1BvbGljeTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VTdG9yYWdlUG9saWN5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRXh0cmFIdHRwSGVhZGVyOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRmlsZVN0YXR1czsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkdyb3VwS2V5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uTmV3RmlsZUtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLlNoYXJlZEZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5Bbnk7CitpbXBvcnQgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU7CitpbXBvcnQgamF2YS5pby5DbG9zZWFibGU7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEuaW8uRmlsZU91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ2FsZW5kYXI7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0aW9uRXhjZXB0aW9uOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydWxlcy5UZW1wb3JhcnlGb2xkZXI7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLkFyZ3VtZW50Q2FwdG9yOworaW1wb3J0IG9yZy5tb2NraXRvLkNhcHRvcjsKK2ltcG9ydCBvcmcubW9ja2l0by5Nb2NrOworaW1wb3J0IG9yZy5tb2NraXRvLmludm9jYXRpb24uSW52b2NhdGlvbk9uTW9jazsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvSlVuaXQ7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b1J1bGU7CitpbXBvcnQgb3JnLm1vY2tpdG8uc3R1YmJpbmcuQW5zd2VyOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlNoYWRvd3M7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLnV0aWwuUmVmbGVjdGlvbkhlbHBlcnM7CisKK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBGaWxlR3JvdXBNYW5hZ2VyVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBDVVJSRU5UX1RJTUVTVEFNUCA9IDEwMDA7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFRSQUZGSUNfVEFHID0gMTAwMDsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFeGVjdXRvciBTRVFVRU5USUFMX0NPTlRST0xfRVhFQ1VUT1IgPQorICAgICAgRXhlY3V0b3JzLm5ld1NpbmdsZVRocmVhZFNjaGVkdWxlZEV4ZWN1dG9yKCk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfR1JPVVAgPSAidGVzdC1ncm91cCI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBURVNUX0dST1VQXzIgPSAidGVzdC1ncm91cC0yIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfR1JPVVBfMyA9ICJ0ZXN0LWdyb3VwLTMiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVTVF9HUk9VUF80ID0gInRlc3QtZ3JvdXAtNCI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyA9IDEwOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSE9TVF9BUFBfTE9HX1NPVVJDRSA9ICJIT1NUX0FQUF9MT0dfU09VUkNFIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEhPU1RfQVBQX1BSSU1FU19MT0dfU09VUkNFID0gIkhPU1RfQVBQX1BSSU1FU19MT0dfU09VUkNFIjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBDb3JyZXNwb25kZW5jZTxHcm91cEtleSwgU3RyaW5nPiBHUk9VUF9LRVlfVE9fVkFSSUFOVCA9CisgICAgICBDb3JyZXNwb25kZW5jZS50cmFuc2Zvcm1pbmcoR3JvdXBLZXk6OmdldFZhcmlhbnRJZCwgInVzaW5nIHZhcmlhbnQiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29ycmVzcG9uZGVuY2U8UGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPiwgUGFpcjxTdHJpbmcsIFN0cmluZz4+CisgICAgICBLRVlfR1JPVVBfUEFJUl9UT19WQVJJQU5UX1BBSVIgPQorICAgICAgICAgIENvcnJlc3BvbmRlbmNlLnRyYW5zZm9ybWluZygKKyAgICAgICAgICAgICAga2V5R3JvdXBQYWlyIC0+CisgICAgICAgICAgICAgICAgICBQYWlyLmNyZWF0ZSgKKyAgICAgICAgICAgICAgICAgICAgICBrZXlHcm91cFBhaXIuZmlyc3QuZ2V0VmFyaWFudElkKCksIGtleUdyb3VwUGFpci5zZWNvbmQuZ2V0VmFyaWFudElkKCkpLAorICAgICAgICAgICAgICAidXNpbmcgdmFyaWFudHMgZnJvbSBncm91cCBrZXkgYW5kIGZpbGUgZ3JvdXAiKTsKKworICBwcml2YXRlIHN0YXRpYyBHcm91cEtleSB0ZXN0S2V5OworICBwcml2YXRlIHN0YXRpYyBHcm91cEtleSB0ZXN0S2V5MjsKKyAgcHJpdmF0ZSBzdGF0aWMgR3JvdXBLZXkgdGVzdEtleTM7CisgIHByaXZhdGUgc3RhdGljIEdyb3VwS2V5IHRlc3RLZXk0OworCisgIHByaXZhdGUgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIEZpbGVHcm91cE1hbmFnZXIgZmlsZUdyb3VwTWFuYWdlcjsKKyAgcHJpdmF0ZSBGaWxlR3JvdXBzTWV0YWRhdGEgZmlsZUdyb3Vwc01ldGFkYXRhOworICBwcml2YXRlIFNoYXJlZEZpbGVNYW5hZ2VyIHNoYXJlZEZpbGVNYW5hZ2VyOworICBwcml2YXRlIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YTsKKyAgcHJpdmF0ZSBGYWtlVGltZVNvdXJjZSB0ZXN0Q2xvY2s7CisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHVibGljIEZpbGUgcHVibGljRGlyZWN0b3J5OworICBwcml2YXRlIGZpbmFsIFRlc3RGbGFncyBmbGFncyA9IG5ldyBUZXN0RmxhZ3MoKTsKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeUZvbGRlciBmb2xkZXIgPSBuZXcgVGVtcG9yYXJ5Rm9sZGVyKCk7CisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgQE1vY2sgRXZlbnRMb2dnZXIgbW9ja0xvZ2dlcjsKKyAgQE1vY2sgU2lsZW50RmVlZGJhY2sgbW9ja1NpbGVudEZlZWRiYWNrOworICBATW9jayBNZGRGaWxlRG93bmxvYWRlciBtb2NrRG93bmxvYWRlcjsKKyAgQE1vY2sgU2hhcmVkRmlsZU1hbmFnZXIgbW9ja1NoYXJlZEZpbGVNYW5hZ2VyOworICBATW9jayBGaWxlR3JvdXBzTWV0YWRhdGEgbW9ja0ZpbGVHcm91cHNNZXRhZGF0YTsKKyAgQE1vY2sgRG93bmxvYWRQcm9ncmVzc01vbml0b3IgbW9ja0Rvd25sb2FkTW9uaXRvcjsKKyAgQE1vY2sgQWNjb3VudFNvdXJjZSBtb2NrQWNjb3VudFNvdXJjZTsKKyAgQE1vY2sgQmFja2VuZCBtb2NrQmFja2VuZDsKKyAgQE1vY2sgQ2xvc2VhYmxlIGNsb3NlYWJsZTsKKworICBAQ2FwdG9yIEFyZ3VtZW50Q2FwdG9yPEZpbGVTb3VyY2U+IGZpbGVTb3VyY2VDYXB0b3I7CisgIEBDYXB0b3IgQXJndW1lbnRDYXB0b3I8R3JvdXBLZXk+IGdyb3VwS2V5Q2FwdG9yOworICBAQ2FwdG9yIEFyZ3VtZW50Q2FwdG9yPExpc3Q8R3JvdXBLZXk+PiBncm91cEtleXNDYXB0b3I7CisKKyAgcHJpdmF0ZSBEb3dubG9hZFN0YWdlTWFuYWdlciBkb3dubG9hZFN0YWdlTWFuYWdlcjsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisKKyAgICB3aGVuKG1vY2tCYWNrZW5kLm5hbWUoKSkudGhlblJldHVybigiYmxvYnN0b3JlIik7CisgICAgZmlsZVN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEFycmF5cy5hc0xpc3QoQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuYnVpbGQoKSwgbW9ja0JhY2tlbmQpKTsKKworICAgIHRlc3RDbG9jayA9IG5ldyBGYWtlVGltZVNvdXJjZSgpLnNldChDVVJSRU5UX1RJTUVTVEFNUCk7CisKKyAgICB0ZXN0S2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHRlc3RLZXkyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgdGVzdEtleTMgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8zKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB0ZXN0S2V5NCA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzQpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgZmlsZUdyb3Vwc01ldGFkYXRhID0KKyAgICAgICAgbmV3IFNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIHRlc3RDbG9jaywKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgTW9yZUV4ZWN1dG9ycy5kaXJlY3RFeGVjdXRvcigpKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhID0KKyAgICAgICAgbmV3IFNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YSgKKyAgICAgICAgICAgIGNvbnRleHQsIG1vY2tTaWxlbnRGZWVkYmFjaywgT3B0aW9uYWwuYWJzZW50KCksIGZsYWdzKTsKKyAgICBzaGFyZWRGaWxlTWFuYWdlciA9CisgICAgICAgIG5ldyBTaGFyZWRGaWxlTWFuYWdlcigKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBtb2NrRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICBtb2NrTG9nZ2VyLAorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3IoKSk7CisKKyAgICBkb3dubG9hZFN0YWdlTWFuYWdlciA9IG5ldyBOb09wRG93bmxvYWRTdGFnZU1hbmFnZXIoKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIgPQorICAgICAgICBuZXcgRmlsZUdyb3VwTWFuYWdlcigKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrTG9nZ2VyLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLAorICAgICAgICAgICAgc2hhcmVkRmlsZU1hbmFnZXIsCisgICAgICAgICAgICB0ZXN0Q2xvY2ssCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrQWNjb3VudFNvdXJjZSksCisgICAgICAgICAgICBTRVFVRU5USUFMX0NPTlRST0xfRVhFQ1VUT1IsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgZG93bmxvYWRTdGFnZU1hbmFnZXIsCisgICAgICAgICAgICBmbGFncyk7CisgICAgLy8gVE9ETyhiLzExNzU3MTA4Myk6IFJlcGxhY2Ugd2l0aCBmaWxlU3RvcmFnZSBBUEkuCisgICAgRmlsZSBkb3dubG9hZERpcmVjdG9yeSA9CisgICAgICAgIG5ldyBGaWxlKGNvbnRleHQuZ2V0RmlsZXNEaXIoKSwgRGlyZWN0b3J5VXRpbC5NRERfU1RPUkFHRV9NT0RVTEUgKyAiLyIgKyAic2hhcmVkIik7CisgICAgcHVibGljRGlyZWN0b3J5ID0gbmV3IEZpbGUoZG93bmxvYWREaXJlY3RvcnksIERpcmVjdG9yeVV0aWwuTUREX1NUT1JBR0VfQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBwdWJsaWNEaXJlY3RvcnkubWtkaXJzKCk7CisKKyAgICAvLyBmaWxlIHNoYXJpbmcgaXMgYXZhaWxhYmxlIGZvciBTREsgUisKKyAgICBSZWZsZWN0aW9uSGVscGVycy5zZXRTdGF0aWNGaWVsZChCdWlsZC5WRVJTSU9OLmNsYXNzLCAiU0RLX0lOVCIsIEJ1aWxkLlZFUlNJT05fQ09ERVMuUik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIE5ld0ZpbGVLZXlbXSBncm91cEtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChkYXRhRmlsZUdyb3VwKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICB2ZXJpZnlBZGRHcm91cEZvckRvd25sb2FkV3JpdGVzTWV0YWRhdGEodGVzdEtleSwgZGF0YUZpbGVHcm91cCwgQ1VSUkVOVF9USU1FU1RBTVApOworCisgICAgLy8gQ2hlY2sgdGhhdCBkb3dubG9hZGVkIGZpbGUgZ3JvdXBzIGRvZXNuJ3QgY29udGFpbiB0aGlzIGZpbGUgZ3JvdXAuCisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOdWxsKCk7CisKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoZ3JvdXBLZXlzWzBdKS5nZXQoKSkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKGdyb3VwS2V5c1sxXSkuZ2V0KCkpLmlzTm90TnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfY29ycmVjdGx5UG9wdWxhdGVzQnVpbGRJZEFuZFZhcmlhbnRJZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0QnVpbGRJZCgxMCkKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoInRlc3RWYXJpYW50IikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXlbXSBncm91cEtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChkYXRhRmlsZUdyb3VwKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICB2ZXJpZnlBZGRHcm91cEZvckRvd25sb2FkV3JpdGVzTWV0YWRhdGEodGVzdEtleSwgZGF0YUZpbGVHcm91cCwgQ1VSUkVOVF9USU1FU1RBTVApOworCisgICAgLy8gQ2hlY2sgdGhhdCBkb3dubG9hZGVkIGZpbGUgZ3JvdXBzIGRvZXNuJ3QgY29udGFpbiB0aGlzIGZpbGUgZ3JvdXAuCisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOdWxsKCk7CisKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoZ3JvdXBLZXlzWzBdKS5nZXQoKSkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKGdyb3VwS2V5c1sxXSkuZ2V0KCkpLmlzTm90TnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfZ3JvdXBVcGRhdGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLCBDVVJSRU5UX1RJTUVTVEFNUCk7CisKKyAgICAvLyBVcGRhdGUgdGhlIGZpbGUgaWQgYW5kIHNlZSB0aGF0IHRoZSBncm91cCBnZXRzIHVwZGF0ZWQgaW4gdGhlIHBlbmRpbmcgZ3JvdXBzIGxpc3QuCisgICAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlKDAsIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKS5zZXRGaWxlSWQoImZpbGUyIikpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICB2ZXJpZnlBZGRHcm91cEZvckRvd25sb2FkV3JpdGVzTWV0YWRhdGEodGVzdEtleSwgZGF0YUZpbGVHcm91cCwgQ1VSUkVOVF9USU1FU1RBTVApOworCisgICAgLy8gVXBkYXRlIG90aGVyIHBhcmFtZXRlcnMgYW5kIGNoZWNrIHRoYXQgd2Ugc3VjY2Vzc2Z1bGx5IGFkZCB0aGUgZ3JvdXAuCisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0RmlsZUdyb3VwVmVyc2lvbk51bWJlcigyKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICB2ZXJpZnlBZGRHcm91cEZvckRvd25sb2FkV3JpdGVzTWV0YWRhdGEodGVzdEtleSwgZGF0YUZpbGVHcm91cCwgQ1VSUkVOVF9USU1FU1RBTVApOworCisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0U3RhbGVMaWZldGltZVNlY3MoNTApLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLCBDVVJSRU5UX1RJTUVTVEFNUCk7CisKKyAgICBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgZGF0YUZpbGVHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucygKKyAgICAgICAgICAgICAgICBEb3dubG9hZENvbmRpdGlvbnMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXREZXZpY2VOZXR3b3JrUG9saWN5KAorICAgICAgICAgICAgICAgICAgICAgICAgRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9GSVJTVF9PTl9XSUZJX1RIRU5fT05fQU5ZX05FVFdPUkspKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLCBDVVJSRU5UX1RJTUVTVEFNUCk7CisKKyAgICBEb3dubG9hZENvbmRpdGlvbnMgZG93bmxvYWRDb25kaXRpb25zID0KKyAgICAgICAgRG93bmxvYWRDb25kaXRpb25zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERldmljZVN0b3JhZ2VQb2xpY3koRGV2aWNlU3RvcmFnZVBvbGljeS5CTE9DS19ET1dOTE9BRF9MT1dFUl9USFJFU0hPTEQpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBkYXRhRmlsZUdyb3VwID0gZGF0YUZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXREb3dubG9hZENvbmRpdGlvbnMoZG93bmxvYWRDb25kaXRpb25zKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICB2ZXJpZnlBZGRHcm91cEZvckRvd25sb2FkV3JpdGVzTWV0YWRhdGEodGVzdEtleSwgZGF0YUZpbGVHcm91cCwgQ1VSUkVOVF9USU1FU1RBTVApOworCisgICAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVyc0VudW0oQWxsb3dlZFJlYWRlcnMuT05MWV9HT09HTEVfUExBWV9TRVJWSUNFUykKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICB2ZXJpZnlBZGRHcm91cEZvckRvd25sb2FkV3JpdGVzTWV0YWRhdGEodGVzdEtleSwgZGF0YUZpbGVHcm91cCwgQ1VSUkVOVF9USU1FU1RBTVApOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfZ3JvdXBVcGRhdGVkX3doZW5CdWlsZENoYW5nZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZCh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAsIENVUlJFTlRfVElNRVNUQU1QKTsKKworICAgIC8vIFVwZGF0ZSB0aGUgZmlsZSBpZCBhbmQgc2VlIHRoYXQgdGhlIGdyb3VwIGdldHMgdXBkYXRlZCBpbiB0aGUgcGVuZGluZyBncm91cHMgbGlzdC4KKyAgICBkYXRhRmlsZUdyb3VwID0gZGF0YUZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRCdWlsZElkKDEyMzQ1Njc4OUwpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLCBDVVJSRU5UX1RJTUVTVEFNUCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9ncm91cFVwZGF0ZWRfd2hlblZhcmlhbnRDaGFuZ2VzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLCBDVVJSRU5UX1RJTUVTVEFNUCk7CisKKyAgICAvLyBVcGRhdGUgdGhlIGZpbGUgaWQgYW5kIHNlZSB0aGF0IHRoZSBncm91cCBnZXRzIHVwZGF0ZWQgaW4gdGhlIHBlbmRpbmcgZ3JvdXBzIGxpc3QuCisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0VmFyaWFudElkKCJzb21lLWRpZmZlcmVudC12YXJpYW50IikuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZCh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAsIENVUlJFTlRfVElNRVNUQU1QKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkV2l0aFN5bmNJZF9mYWlsZWRUb1VwZGF0ZU1ldGFkYXRhTm9TY2hlZHVsZVZpYVNwZSgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNb2NrIEZpbGVHcm91cHNNZXRhZGF0YSBhbmQgU2hhcmVkRmlsZU1hbmFnZXIgdG8gdGVzdCBmYWlsdXJlIHNjZW5hcmlvLgorICAgIHJlc2V0RmlsZUdyb3VwTWFuYWdlcihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCBtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsV2l0aERvd25sb2FkSWQoVEVTVF9HUk9VUCwgMik7CisgICAgTmV3RmlsZUtleVtdIGdyb3VwS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXApOworCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIucmVzZXJ2ZUZpbGVFbnRyeShhbnkoTmV3RmlsZUtleS5jbGFzcykpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisKKyAgICAvLyBGYWlsZWQgdG8gd3JpdGUgdG8gTWV0YWRhdGEsIG5vIHRhc2sgd2lsbCBiZSBzY2hlZHVsZWQgdmlhIFNQRS4KKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUoYW55KEdyb3VwS2V5LmNsYXNzKSwgYW55KERhdGFGaWxlR3JvdXBJbnRlcm5hbC5jbGFzcykpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmYWxzZSkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGFueShHcm91cEtleS5jbGFzcykpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPEJvb2xlYW4+IGFkZEdyb3VwRnV0dXJlID0KKyAgICAgICAgZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApOworICAgIGFzc2VydFRocm93cyhFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsIGFkZEdyb3VwRnV0dXJlOjpnZXQpOworICAgIElPRXhjZXB0aW9uIGUgPSBMYWJzRnV0dXJlcy5nZXRGYWlsdXJlQ2F1c2VBcyhhZGRHcm91cEZ1dHVyZSwgSU9FeGNlcHRpb24uY2xhc3MpOworICAgIGFzc2VydFRoYXQoZSkuaGFzTWVzc2FnZVRoYXQoKS5jb250YWlucygiRmFpbGVkIHRvIGNvbW1pdCBuZXcgZ3JvdXAgbWV0YWRhdGEgdG8gZGlzay4iKTsKKworICAgIC8vIENoZWNrIHRoYXQgZG93bmxvYWRlZCBmaWxlIGdyb3VwcyBkb2Vzbid0IGNvbnRhaW4gdGhpcyBmaWxlIGdyb3VwLgorICAgIEdyb3VwS2V5IGRvd25sb2FkZWRrZXkgPSB0ZXN0S2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKyAgICBhc3NlcnRXaXRoTWVzc2FnZShTdHJpbmcuZm9ybWF0KCJFeHBlY3RlZCB0aGF0IGtleSAlcyBzaG91bGQgbm90IGV4aXN0LiIsIGRvd25sb2FkZWRrZXkpKQorICAgICAgICAudGhhdChtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZG93bmxvYWRlZGtleSkuZ2V0KCkpCisgICAgICAgIC5pc051bGwoKTsKKyAgICAvLyBDaGVjayB0aGF0IHRoZSBnZXQgbWV0aG9kIGRvZXNuJ3QgcmV0dXJuIHRoaXMgZmlsZSBncm91cC4KKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuZ2V0RmlsZUdyb3VwKHRlc3RLZXksIHRydWUpLmdldCgpKS5pc051bGwoKTsKKworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLnJlc2VydmVGaWxlRW50cnkoZ3JvdXBLZXlzWzBdKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5yZXNlcnZlRmlsZUVudHJ5KGdyb3VwS2V5c1sxXSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9kdXBsaWNhdGVQZW5kaW5nR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICB2ZXJpZnlBZGRHcm91cEZvckRvd25sb2FkV3JpdGVzTWV0YWRhdGEodGVzdEtleSwgZGF0YUZpbGVHcm91cCwgQ1VSUkVOVF9USU1FU1RBTVApOworCisgICAgLy8gU2VuZCB0aGUgZXhhY3Qgc2FtZSBncm91cCBhZ2FpbiwgYW5kIGNoZWNrIHRoYXQgaXQgaXMgY29uc2lkZXJlZCBkdXBsaWNhdGUuCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX2R1cGxpY2F0ZURvd25sb2FkZWRHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwKTsKKworICAgIC8vIFNlbmQgdGhlIGV4YWN0IHNhbWUgZ3JvdXAgYXMgdGhlIGRvd25sb2FkZWQgZ3JvdXAsIGFuZCBjaGVjayB0aGF0IGl0IGlzIGNvbnNpZGVyZWQgZHVwbGljYXRlLgorICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9maWxlUHJvcGVydGllc1VwZGF0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZGF0YUZpbGVHcm91cCk7CisKKyAgICBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgZGF0YUZpbGVHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGUoMCwgZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLnRvQnVpbGRlcigpLnNldFVybFRvRG93bmxvYWQoImh0dHBzOi8vZmlsZTIiKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIC8vIFNlbmQgdGhlIHNhbWUgZ3JvdXAgd2l0aCBkaWZmZXJlbnQgcHJvcGVydHksIGFuZCBjaGVjayB0aGF0IGl0IGlzIE5PVCBkdXBsaWNhdGUuCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlKDAsIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKS5zZXRVcmxUb0Rvd25sb2FkKCJodHRwczovL2ZpbGUzIikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZCh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9kaWZmZXJlbnRQZW5kaW5nR3JvdXBfZHVwbGljYXRlRG93bmxvYWRlZEdyb3VwKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpcnN0R3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZmlyc3RHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCBmaXJzdEdyb3VwLCBDVVJSRU5UX1RJTUVTVEFNUCk7CisKKyAgICAvLyBDcmVhdGUgYSBzZWNvbmQgZ3JvdXAgdGhhdCBpcyBpZGVudGljYWwgZXhjZXB0IGZvciBvbmUgZGlmZmVyZW50IGZpbGUgaWQuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsLkJ1aWxkZXIgc2Vjb25kR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCk7CisgICAgc2Vjb25kR3JvdXAuc2V0RmlsZSgwLCBzZWNvbmRHcm91cC5nZXRGaWxlKDApLnRvQnVpbGRlcigpLnNldEZpbGVJZCgiZmlsZTIiKSk7CisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXksIHNlY29uZEdyb3VwLmJ1aWxkKCkpOworCisgICAgLy8gU2VuZCB0aGUgc2FtZSBncm91cCBhcyBkb3dubG9hZGVkIGdyb3VwLCBhbmQgY2hlY2sgdGhhdCBpdCBpcyBub3QgY29uc2lkZXJlZCBkdXBsaWNhdGUuCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgc2Vjb25kR3JvdXAuYnVpbGQoKSkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCBzZWNvbmRHcm91cC5idWlsZCgpLCBDVVJSRU5UX1RJTUVTVEFNUCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9zdWJzY3JpYmVGYWlsZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNb2NrIFNoYXJlZEZpbGVNYW5hZ2VyIHRvIHRlc3QgZmFpbHVyZSBzY2VuYXJpby4KKyAgICByZXNldEZpbGVHcm91cE1hbmFnZXIoZmlsZUdyb3Vwc01ldGFkYXRhLCBtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDMpOworICAgIE5ld0ZpbGVLZXlbXSBncm91cEtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChkYXRhRmlsZUdyb3VwKTsKKworICAgIEFyZ3VtZW50Q2FwdG9yPE5ld0ZpbGVLZXk+IGZpbGVDYXB0b3IgPSBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhOZXdGaWxlS2V5LmNsYXNzKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5yZXNlcnZlRmlsZUVudHJ5KGZpbGVDYXB0b3IuY2FwdHVyZSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oCisgICAgICAgICAgICBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSwKKyAgICAgICAgICAgIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKSwKKyAgICAgICAgICAgIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICBmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCk6OmdldCk7CisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKElPRXhjZXB0aW9uLmNsYXNzKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHdlIHRyaWVkIHRvIHN1YnNjcmliZSB0byBvbmx5IHRoZSBmaXJzdCAyIGZpbGVzLgorICAgIGFzc2VydFRoYXQoZmlsZUNhcHRvci5nZXRBbGxWYWx1ZXMoKSkuY29udGFpbnNFeGFjdGx5KGdyb3VwS2V5c1swXSwgZ3JvdXBLZXlzWzFdKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX3N1YnNjcmliZUZhaWxlZF9maXJzdEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNb2NrIFNoYXJlZEZpbGVNYW5hZ2VyIHRvIHRlc3QgZmFpbHVyZSBzY2VuYXJpby4KKyAgICByZXNldEZpbGVHcm91cE1hbmFnZXIoZmlsZUdyb3Vwc01ldGFkYXRhLCBtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDMpOworICAgIE5ld0ZpbGVLZXlbXSBncm91cEtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChkYXRhRmlsZUdyb3VwKTsKKworICAgIEFyZ3VtZW50Q2FwdG9yPE5ld0ZpbGVLZXk+IGZpbGVDYXB0b3IgPSBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhOZXdGaWxlS2V5LmNsYXNzKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5yZXNlcnZlRmlsZUVudHJ5KGZpbGVDYXB0b3IuY2FwdHVyZSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oCisgICAgICAgICAgICBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmYWxzZSksCisgICAgICAgICAgICBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSwKKyAgICAgICAgICAgIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICBmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCk6OmdldCk7CisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKElPRXhjZXB0aW9uLmNsYXNzKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHdlIHRyaWVkIHRvIHN1YnNjcmliZSB0byBvbmx5IHRoZSBmaXJzdCBmaWxlLgorICAgIGFzc2VydFRoYXQoZmlsZUNhcHRvci5nZXRBbGxWYWx1ZXMoKSkuY29udGFpbnNFeGFjdGx5KGdyb3VwS2V5c1swXSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9hbHJlYWR5RG93bmxvYWRlZEdyb3VwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV3JpdGUgYSBncm91cCB0byB0aGUgcGVuZGluZyBzaGFyZWQgcHJlZnMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgcGVuZGluZ0dyb3VwKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBvbGREb3dubG9hZGVkR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXksIG9sZERvd25sb2FkZWRHcm91cCk7CisKKyAgICAvLyBBZGQgYSBuZXdlciB2ZXJzaW9uIG9mIHRoYXQgZ3JvdXAKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcmVjZWl2ZWRHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAzKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIHJlY2VpdmVkR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKworICAgIC8vIFRoZSBuZXcgYWRkZWQgZ3JvdXAgc2hvdWxkIGJlIHRoZSBwZW5kaW5nIGdyb3VwLgorICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCByZWNlaXZlZEdyb3VwLCBDVVJSRU5UX1RJTUVTVEFNUCk7CisgICAgYXNzZXJ0VGhhdChvbGREb3dubG9hZGVkR3JvdXApLmlzRXF1YWxUbyhyZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5KSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9hZGRFbXB0eUdyb3VwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV3JpdGUgYSBncm91cCB0byB0aGUgcGVuZGluZyBzaGFyZWQgcHJlZnMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgcGVuZGluZ0dyb3VwKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBlbXB0eUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZCh0ZXN0S2V5LCBlbXB0eUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKHRlc3RLZXksIGVtcHR5R3JvdXAsIENVUlJFTlRfVElNRVNUQU1QKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX2FkZEdyb3VwRm9yVW5pbnN0YWxsZWRBcHAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICBHcm91cEtleSB1bmluc3RhbGxlZEFwcEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkuc2V0T3duZXJQYWNrYWdlKCJub3QuaW5zdGFsbGVkLmFwcCIpLmJ1aWxkKCk7CisKKyAgICAvLyBTZW5kIGEgZ3JvdXAgd2l0aCBhbiBvd25lciBwYWNrYWdlIHRoYXQgaXMgbm90IGluc3RhbGxlZC4gRW5zdXJlIHRoYXQgdGhpcyBncm91cCBpcyByZWplY3RlZC4KKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIFVuaW5zdGFsbGVkQXBwRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAoKSAtPiBmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodW5pbnN0YWxsZWRBcHBLZXksIGRhdGFGaWxlR3JvdXApKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX2V4cGlyZWRHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIENhbGVuZGFyIGRhdGUgPSBuZXcgQ2FsZW5kYXIuQnVpbGRlcigpLnNldERhdGUoMTk3MCwgQ2FsZW5kYXIuSkFOVUFSWSwgMikuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEV4cGlyYXRpb25EYXRlU2VjcyhkYXRlLmdldFRpbWVJbk1pbGxpcygpIC8gMTAwMCkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgdGVzdENsb2NrLnNldChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisKKyAgICAvLyBTZW5kIGEgZ3JvdXAgd2l0aCBhbiBleHBpcmF0aW9uIGRhdGUgdGhhdCBoYXMgYWxyZWFkeSBwYXNzZWQuCisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBFeHBpcmVkRmlsZUdyb3VwRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAoKSAtPiBmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfanVzdEV4cGlyZWRHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGxvbmcgb25lSG91ckFnbyA9IChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIFRpbWVVbml0LkhPVVJTLnRvTWlsbGlzKDEpKSAvIDEwMDA7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRFeHBpcmF0aW9uRGF0ZVNlY3Mob25lSG91ckFnbykKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgdGVzdENsb2NrLnNldChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisKKyAgICAvLyBTZW5kIGEgZ3JvdXAgd2l0aCBhbiBleHBpcmF0aW9uIGRhdGUgdGhhdCBoYXMgYWxyZWFkeSBwYXNzZWQuCisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBFeHBpcmVkRmlsZUdyb3VwRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAoKSAtPiBmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfbm9uZXhwaXJlZEdyb3VwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgTmV3RmlsZUtleVtdIGdyb3VwS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXApOworCisgICAgbG9uZyB0ZW5EYXlzRnJvbU5vdyA9IChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIFRpbWVVbml0LkRBWVMudG9NaWxsaXMoMTApKSAvIDEwMDA7CisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKHRlbkRheXNGcm9tTm93KS5idWlsZCgpOworCisgICAgdGVzdENsb2NrLnNldChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZCh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAsIHRlc3RDbG9jay5jdXJyZW50VGltZU1pbGxpcygpKTsKKworICAgIC8vIENoZWNrIHRoYXQgZG93bmxvYWRlZCBmaWxlIGdyb3VwcyBkb2Vzbid0IGNvbnRhaW4gdGhpcyBmaWxlIGdyb3VwLgorICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleSkpLmlzTnVsbCgpOworICAgIC8vIENoZWNrIHRoYXQgdGhlIGdldCBtZXRob2QgZG9lc24ndCByZXR1cm4gdGhpcyBmaWxlIGdyb3VwLgorICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5nZXRGaWxlR3JvdXAodGVzdEtleSwgdHJ1ZSkuZ2V0KCkpLmlzTnVsbCgpOworCisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKGdyb3VwS2V5c1swXSkuZ2V0KCkpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShncm91cEtleXNbMV0pLmdldCgpKS5pc05vdE51bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX25vbmV4cGlyZWRHcm91cE5vRXhwaXJhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCk7CisgICAgTmV3RmlsZUtleVtdIGdyb3VwS2V5cyA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGRhdGFGaWxlR3JvdXAuYnVpbGQoKSk7CisKKyAgICBkYXRhRmlsZUdyb3VwLnNldEV4cGlyYXRpb25EYXRlU2VjcygwKTsgLy8gMCBtZWFucyBkb24ndCBleHBpcmUKKworICAgIHRlc3RDbG9jay5zZXQoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cC5idWlsZCgpKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKAorICAgICAgICB0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLmJ1aWxkKCksIHRlc3RDbG9jay5jdXJyZW50VGltZU1pbGxpcygpKTsKKworICAgIC8vIENoZWNrIHRoYXQgZG93bmxvYWRlZCBmaWxlIGdyb3VwcyBkb2Vzbid0IGNvbnRhaW4gdGhpcyBmaWxlIGdyb3VwLgorICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleSkpLmlzTnVsbCgpOworICAgIC8vIENoZWNrIHRoYXQgdGhlIGdldCBtZXRob2QgZG9lc24ndCByZXR1cm4gdGhpcyBmaWxlIGdyb3VwLgorICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5nZXRGaWxlR3JvdXAodGVzdEtleSwgdHJ1ZSkuZ2V0KCkpLmlzTnVsbCgpOworCisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKGdyb3VwS2V5c1swXSkuZ2V0KCkpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShncm91cEtleXNbMV0pLmdldCgpKS5pc05vdE51bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX2V4dGVuZEV4cGlyYXRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpOworICAgIGxvbmcgdGVuRGF5c0Zyb21Ob3cgPSAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKyBUaW1lVW5pdC5EQVlTLnRvTWlsbGlzKDEwKSkgLyAxMDAwOworICAgIGRhdGFGaWxlR3JvdXAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKHRlbkRheXNGcm9tTm93KTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAuYnVpbGQoKSkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLmJ1aWxkKCksIENVUlJFTlRfVElNRVNUQU1QKTsKKworICAgIC8vIE5vdyBzZW5kIHRoZSBncm91cCBhZ2FpbiB3aXRoIGEgbG9uZ2VyIGV4cGlyYXRpb24uCisgICAgbG9uZyB0d2VudHlEYXlzRnJvbU5vdyA9IHRlbkRheXNGcm9tTm93ICsgVGltZVVuaXQuREFZUy50b1NlY29uZHMoMTApOworICAgIGRhdGFGaWxlR3JvdXAgPSBkYXRhRmlsZUdyb3VwLnNldEV4cGlyYXRpb25EYXRlU2Vjcyh0d2VudHlEYXlzRnJvbU5vdyk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZCh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLmJ1aWxkKCkpLmdldCgpKS5pc1RydWUoKTsKKyAgICB2ZXJpZnlBZGRHcm91cEZvckRvd25sb2FkV3JpdGVzTWV0YWRhdGEodGVzdEtleSwgZGF0YUZpbGVHcm91cC5idWlsZCgpLCBDVVJSRU5UX1RJTUVTVEFNUCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9yZWR1Y2VFeHBpcmF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgbG9uZyB0ZW5EYXlzRnJvbU5vdyA9IChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSArIFRpbWVVbml0LkRBWVMudG9NaWxsaXMoMTApKSAvIDEwMDA7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRFeHBpcmF0aW9uRGF0ZVNlY3ModGVuRGF5c0Zyb21Ob3cpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICB2ZXJpZnlBZGRHcm91cEZvckRvd25sb2FkV3JpdGVzTWV0YWRhdGEodGVzdEtleSwgZGF0YUZpbGVHcm91cCwgQ1VSUkVOVF9USU1FU1RBTVApOworCisgICAgLy8gTm93IHNlbmQgdGhlIGdyb3VwIGFnYWluIHdpdGggYSBsb25nZXIgZXhwaXJhdGlvbi4KKyAgICBsb25nIGZpdmVEYXlzRnJvbU5vdyA9IHRlbkRheXNGcm9tTm93IC0gVGltZVVuaXQuREFZUy50b1NlY29uZHMoNSk7CisgICAgZGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKGZpdmVEYXlzRnJvbU5vdykuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICB2ZXJpZnlBZGRHcm91cEZvckRvd25sb2FkV3JpdGVzTWV0YWRhdGEodGVzdEtleSwgZGF0YUZpbGVHcm91cCwgQ1VSUkVOVF9USU1FU1RBTVApOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfZGVsYXllZERvd25sb2FkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZmxhZ3MuZW5hYmxlRGVsYXllZERvd25sb2FkID0gT3B0aW9uYWwub2YodHJ1ZSk7CisgICAgLy8gQ3JlYXRlIDIgZ3JvdXBzLCBvbmUgb2Ygd2hpY2ggcmVxdWlyZXMgZGV2aWNlIHNpZGUgYWN0aXZhdGlvbi4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucygKKyAgICAgICAgICAgICAgICBEb3dubG9hZENvbmRpdGlvbnMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRBY3RpdmF0aW5nQ29uZGl0aW9uKEFjdGl2YXRpbmdDb25kaXRpb24uREVWSUNFX0FDVElWQVRFRCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAyID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMyk7CisKKyAgICAvLyBBc3NlcnQgdGhhdCBhZGRpbmcgdGhlIGZpcnN0IGdyb3VwIHRocm93cyBhbiBleGNlcHRpb24uCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4ID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGZpbGVHcm91cDEpOjpnZXQpOworICAgIGFzc2VydFRoYXQoZXgpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihBY3RpdmF0aW9uUmVxdWlyZWRGb3JHcm91cEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleTIsIGZpbGVHcm91cDIpLmdldCgpKS5pc1RydWUoKTsKKworICAgIC8vIE5vdyBhY3RpdmF0ZSB0aGUgZ3JvdXAgYW5kIHZlcmlmeSB0aGF0IHdlIGFyZSBhYmxlIHRvIGFkZCB0aGUgZmlyc3QgZ3JvdXAuCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLnNldEdyb3VwQWN0aXZhdGlvbih0ZXN0S2V5LCB0cnVlKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZmlsZUdyb3VwMSkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgLy8gRGVhY3RpdmF0ZSB0aGUgZ3JvdXAgYWdhaW4gYW5kIHZlcmlmeSB0aGF0IHdlIHNob3VsZCBubyBsb25nZXIgYmUgYWJsZSB0byBhZGQgaXQuCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLnNldEdyb3VwQWN0aXZhdGlvbih0ZXN0S2V5LCBmYWxzZSkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIGV4ID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGZpbGVHcm91cDEpOjpnZXQpOworICAgIGFzc2VydFRoYXQoZXgpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihBY3RpdmF0aW9uUmVxdWlyZWRGb3JHcm91cEV4Y2VwdGlvbi5jbGFzcyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9vbldpZmlGaXJzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGludCBlbGFwc2VkVGltZSA9IDEwMDA7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsLkJ1aWxkZXIgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKTsKKworICAgIHsKKyAgICAgIHRlc3RDbG9jay5zZXQoZWxhcHNlZFRpbWUpOworICAgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cC5idWlsZCgpKS5nZXQoKSkKKyAgICAgICAgICAuaXNUcnVlKCk7CisgICAgICAvLyBUaGUgd2lmaSBvbmx5IGRvd25sb2FkIHRpbWVzdGFtcCBpcyBzZXQgY29ycmVjdGx5LgorICAgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAuYnVpbGQoKSwgZWxhcHNlZFRpbWUpOworICAgIH0KKworICAgIHsKKyAgICAgIC8vIFVwZGF0ZSBtZXRhZGF0YSBkb2VzIG5vdCBjaGFuZ2UgdGhlIHdpZmkgb25seSBkb3dubG9hZCB0aW1lc3RhbXAuCisgICAgICBsb25nIHRlbkRheXNGcm9tTm93ID0gKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpICsgVGltZVVuaXQuREFZUy50b01pbGxpcygxMCkpIC8gMTAwMDsKKyAgICAgIGRhdGFGaWxlR3JvdXAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKHRlbkRheXNGcm9tTm93KTsKKyAgICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAuYnVpbGQoKSkuZ2V0KCkpCisgICAgICAgICAgLmlzVHJ1ZSgpOworICAgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAuYnVpbGQoKSwgZWxhcHNlZFRpbWUpOworICAgIH0KKworICAgIHsKKyAgICAgIC8vIENoYW5nZSBhbm90aGVyIG1ldGFkYXRhIGZpZWxkIGRvZXMgbm90IGNoYW5nZSB0aGUgd2lmaSBvbmx5IGRvd25sb2FkIHRpbWVzdGFtcC4KKyAgICAgIGRhdGFGaWxlR3JvdXAuc2V0RmlsZUdyb3VwVmVyc2lvbk51bWJlcigyKTsKKyAgICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAuYnVpbGQoKSkuZ2V0KCkpCisgICAgICAgICAgLmlzVHJ1ZSgpOworICAgICAgLy8gVGhlIHdpZmkgb25seSBkb3dubG9hZCB0aW1lc3RhbXAgZG9lcyBub3QgY2hhbmdlLgorICAgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAuYnVpbGQoKSwgZWxhcHNlZFRpbWUpOworICAgIH0KKworICAgIHsKKyAgICAgIC8vIFVwZGF0ZSB0aGUgZmlsZSdzIHVybFRvRG93bmxvYWQgd2lsbCByZXNldCB0aGUgd2lmaSBvbmx5IGRvd25sb2FkIHRpbWVzdGFtcC4KKyAgICAgIGVsYXBzZWRUaW1lID0gMjAwMDsKKyAgICAgIHRlc3RDbG9jay5zZXQoZWxhcHNlZFRpbWUpOworICAgICAgZGF0YUZpbGVHcm91cC5zZXRGaWxlKAorICAgICAgICAgIDAsIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKS5zZXRVcmxUb0Rvd25sb2FkKCJodHRwczovL25ld191cmwiKSk7CisgICAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZCh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLmJ1aWxkKCkpLmdldCgpKQorICAgICAgICAgIC5pc1RydWUoKTsKKyAgICAgIC8vIFRoZSB3aWZpIG9ubHkgZG93bmxvYWQgdGltZXN0YW1wIGNoYW5nZSBzaW5jZSB3ZSBjaGFuZ2UgdGhlIHVybFRvRG93bmxvYWQKKyAgICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLmJ1aWxkKCksIGVsYXBzZWRUaW1lKTsKKyAgICB9CisKKyAgICB7CisgICAgICAvLyBVcGRhdGUgdGhlIGZpbGUncyBieXRlU2l6ZSB3aWxsIHJlc2V0IHRoZSB3aWZpIG9ubHkgZG93bmxvYWQgdGltZXN0YW1wLgorICAgICAgZWxhcHNlZFRpbWUgPSAzMDAwOworICAgICAgdGVzdENsb2NrLnNldChlbGFwc2VkVGltZSk7CisgICAgICBkYXRhRmlsZUdyb3VwLnNldEZpbGUoMSwgZGF0YUZpbGVHcm91cC5nZXRGaWxlKDEpLnRvQnVpbGRlcigpLnNldEJ5dGVTaXplKDUwMDEpKTsKKyAgICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAuYnVpbGQoKSkuZ2V0KCkpCisgICAgICAgICAgLmlzVHJ1ZSgpOworICAgICAgLy8gVGhlIHdpZmkgb25seSBkb3dubG9hZCB0aW1lc3RhbXAgY2hhbmdlIHNpbmNlIHdlIGNoYW5nZSB0aGUgdXJsVG9Eb3dubG9hZAorICAgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAuYnVpbGQoKSwgZWxhcHNlZFRpbWUpOworICAgIH0KKworICAgIHsKKyAgICAgIC8vIFVwZGF0ZSB0aGUgZmlsZSdzIGNoZWNrc3VtIHdpbGwgcmVzZXQgdGhlIHdpZmkgb25seSBkb3dubG9hZCB0aW1lc3RhbXAuCisgICAgICBlbGFwc2VkVGltZSA9IDQwMDA7CisgICAgICB0ZXN0Q2xvY2suc2V0KGVsYXBzZWRUaW1lKTsKKyAgICAgIGRhdGFGaWxlR3JvdXAuc2V0RmlsZSgxLCBkYXRhRmlsZUdyb3VwLmdldEZpbGUoMSkudG9CdWlsZGVyKCkuc2V0Q2hlY2tzdW0oIm5ldyBjaGVjayBzdW0iKSk7CisgICAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZCh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLmJ1aWxkKCkpLmdldCgpKQorICAgICAgICAgIC5pc1RydWUoKTsKKyAgICAgIC8vIFRoZSB3aWZpIG9ubHkgZG93bmxvYWQgdGltZXN0YW1wIGNoYW5nZSBzaW5jZSB3ZSBjaGFuZ2UgdGhlIHVybFRvRG93bmxvYWQKKyAgICAgIHZlcmlmeUFkZEdyb3VwRm9yRG93bmxvYWRXcml0ZXNNZXRhZGF0YSh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwLmJ1aWxkKCksIGVsYXBzZWRUaW1lKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9hZGRzU2lkZWxvYWRlZEdyb3VwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQ3JlYXRlIHNpZGVsb2FkZWQgZ3JvdXAKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgc2lkZWxvYWRlZEdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoInNpZGVsb2FkZWRfZmlsZSIpCisgICAgICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJmaWxlOi90ZXN0IikKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtVHlwZShEYXRhRmlsZS5DaGVja3N1bVR5cGUuTk9ORSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKHRlc3RLZXksIHNpZGVsb2FkZWRHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKHRlc3RLZXksIHNpZGVsb2FkZWRHcm91cCwgMTAwMEwpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfbXVsdGlwbGVWYXJpYW50cygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENyZWF0ZSAzIGdyb3VwIGtleXMgb2YgdGhlIHNhbWUgZ3JvdXAsIGJ1dCB3aXRoIGRpZmZlcmVudCB2YXJpYW50cworICAgIEdyb3VwS2V5IGRlZmF1bHRHcm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBHcm91cEtleSBlbkdyb3VwS2V5ID0gZGVmYXVsdEdyb3VwS2V5LnRvQnVpbGRlcigpLnNldFZhcmlhbnRJZCgiZW4iKS5idWlsZCgpOworICAgIEdyb3VwS2V5IGZyR3JvdXBLZXkgPSBkZWZhdWx0R3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0VmFyaWFudElkKCJmciIpLmJ1aWxkKCk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGVmYXVsdEZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZW5GaWxlR3JvdXAgPSBkZWZhdWx0RmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldFZhcmlhbnRJZCgiZW4iKS5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmckZpbGVHcm91cCA9IGRlZmF1bHRGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0VmFyaWFudElkKCJmciIpLmJ1aWxkKCk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChkZWZhdWx0R3JvdXBLZXksIGRlZmF1bHRGaWxlR3JvdXApLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQoZW5Hcm91cEtleSwgZW5GaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChmckdyb3VwS2V5LCBmckZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsR3JvdXBLZXlzKCkuZ2V0KCkpCisgICAgICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKEdST1VQX0tFWV9UT19WQVJJQU5UKQorICAgICAgICAuY29udGFpbnNFeGFjdGx5KCIiLCAiZW4iLCAiZnIiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlbW92ZUZpbGVHcm91cF9ub1ZlcnNpb25FeGlzdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBObyByZWNvcmQgZm9yIGJvdGggcGVuZGluZyBrZXkgYW5kIGRvd25sb2FkZWQga2V5LgorICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci5yZW1vdmVGaWxlR3JvdXAoZ3JvdXBLZXksIC8qIHBlbmRpbmdPbmx5PSAqLyBmYWxzZSkuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxTdGFsZUdyb3VwcygpLmdldCgpKS5pc0VtcHR5KCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsR3JvdXBLZXlzKCkuZ2V0KCkpLmlzRW1wdHkoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlbW92ZUZpbGVHcm91cF9wZW5kaW5nVmVyc2lvbkV4aXN0cygpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIGRhdGFGaWxlMSA9IERhdGFGaWxlLm5ld0J1aWxkZXIoKS5zZXRGaWxlSWQoImZpbGUxIikuc2V0Q2hlY2tzdW0oImNoZWNrc3VtMSIpLmJ1aWxkKCk7CisgICAgRGF0YUZpbGUgZGF0YUZpbGUyID0gRGF0YUZpbGUubmV3QnVpbGRlcigpLnNldEZpbGVJZCgiZmlsZTIiKS5zZXRDaGVja3N1bSgiY2hlY2tzdW0yIikuYnVpbGQoKTsKKworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleTEgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShkYXRhRmlsZTEsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5MiA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGRhdGFGaWxlMiwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nRmlsZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldEZpbGVHcm91cFZlcnNpb25OdW1iZXIoMSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVyc0VudW0oQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKQorICAgICAgICAgICAgLmFkZEFsbEZpbGUoTGlzdHMubmV3QXJyYXlMaXN0KGRhdGFGaWxlMSwgZGF0YUZpbGUyKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgcGVuZGluZ0dyb3VwS2V5ID0gZ3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKyAgICBHcm91cEtleSBkb3dubG9hZGVkR3JvdXBLZXkgPSBncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKHRydWUpLmJ1aWxkKCk7CisKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAocGVuZGluZ0dyb3VwS2V5LCBwZW5kaW5nRmlsZUdyb3VwKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBwZW5kaW5nRmlsZUdyb3VwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MsIEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIucmVtb3ZlRmlsZUdyb3VwKGdyb3VwS2V5LCAvKiBwZW5kaW5nT25seT0gKi8gZmFsc2UpLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXkpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKGRvd25sb2FkZWRHcm91cEtleSkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEdyb3VwS2V5cygpLmdldCgpKS5pc0VtcHR5KCk7CisKKyAgICBVcmkgcGVuZGluZ0ZpbGVVcmkxID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBuZXdGaWxlS2V5MS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgZGF0YUZpbGUxLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgbmV3RmlsZUtleTEuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKyAgICBVcmkgcGVuZGluZ0ZpbGVVcmkyID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBuZXdGaWxlS2V5Mi5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgZGF0YUZpbGUyLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgbmV3RmlsZUtleTIuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRlcikuc3RvcERvd25sb2FkaW5nKHBlbmRpbmdGaWxlVXJpMSk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyKS5zdG9wRG93bmxvYWRpbmcocGVuZGluZ0ZpbGVVcmkyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlbW92ZUZpbGVHcm91cF9kb3dubG9hZGVkVmVyc2lvbkV4aXN0cygpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIGRhdGFGaWxlMSA9IERhdGFGaWxlLm5ld0J1aWxkZXIoKS5zZXRGaWxlSWQoImZpbGUxIikuc2V0Q2hlY2tzdW0oImNoZWNrc3VtMSIpLmJ1aWxkKCk7CisgICAgRGF0YUZpbGUgZGF0YUZpbGUyID0gRGF0YUZpbGUubmV3QnVpbGRlcigpLnNldEZpbGVJZCgiZmlsZTIiKS5zZXRDaGVja3N1bSgiY2hlY2tzdW0yIikuYnVpbGQoKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkRmlsZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldEZpbGVHcm91cFZlcnNpb25OdW1iZXIoMCkKKyAgICAgICAgICAgIC5zZXRCdWlsZElkKDApCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCIiKQorICAgICAgICAgICAgLnNldEFsbG93ZWRSZWFkZXJzRW51bShBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpCisgICAgICAgICAgICAuYWRkQWxsRmlsZShMaXN0cy5uZXdBcnJheUxpc3QoZGF0YUZpbGUxLCBkYXRhRmlsZTIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBHcm91cEtleSBncm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXkgPSBncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworICAgIEdyb3VwS2V5IGRvd25sb2FkZWRHcm91cEtleSA9IGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChkb3dubG9hZGVkR3JvdXBLZXksIGRvd25sb2FkZWRGaWxlR3JvdXApOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGRvd25sb2FkZWRGaWxlR3JvdXAsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci5yZW1vdmVGaWxlR3JvdXAoZ3JvdXBLZXksIC8qIHBlbmRpbmdPbmx5PSAqLyBmYWxzZSkuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleSkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAoZG93bmxvYWRlZEdyb3VwS2V5KSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKS5nZXQoKSkKKyAgICAgICAgLmNvbnRhaW5zRXhhY3RseSgKKyAgICAgICAgICAgIGRvd25sb2FkZWRGaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkZWRGaWxlR3JvdXAuZ2V0Qm9va2tlZXBpbmcoKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUoMSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRlciwgbmV2ZXIoKSkuc3RvcERvd25sb2FkaW5nKGFueShVcmkuY2xhc3MpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlbW92ZUZpbGVHcm91cF9ib3RoVmVyc2lvbnNFeGlzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIHJlZ2lzdGVyZWRGaWxlID0KKyAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpLnNldEZpbGVJZCgiZmlsZSIpLnNldENoZWNrc3VtKCJyZWdpc3RlcmVkIikuYnVpbGQoKTsKKyAgICBEYXRhRmlsZSBkb3dubG9hZGVkRmlsZSA9CisgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKS5zZXRGaWxlSWQoImZpbGUiKS5zZXRDaGVja3N1bSgiZG93bmxvYWRlZCIpLmJ1aWxkKCk7CisKKyAgICBOZXdGaWxlS2V5IHJlZ2lzdGVyZWRGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUocmVnaXN0ZXJlZEZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcGVuZGluZ0ZpbGVHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRGaWxlR3JvdXBWZXJzaW9uTnVtYmVyKDEpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUykKKyAgICAgICAgICAgIC5hZGRGaWxlKHJlZ2lzdGVyZWRGaWxlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRGaWxlR3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0RmlsZUdyb3VwVmVyc2lvbk51bWJlcigwKQorICAgICAgICAgICAgLnNldEJ1aWxkSWQoMCkKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoIiIpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUykKKyAgICAgICAgICAgIC5hZGRGaWxlKGRvd25sb2FkZWRGaWxlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBHcm91cEtleSBncm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXkgPSBncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworICAgIEdyb3VwS2V5IGRvd25sb2FkZWRHcm91cEtleSA9IGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXksIHBlbmRpbmdGaWxlR3JvdXApOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChkb3dubG9hZGVkR3JvdXBLZXksIGRvd25sb2FkZWRGaWxlR3JvdXApOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIHBlbmRpbmdGaWxlR3JvdXAsIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIGRvd25sb2FkZWRGaWxlR3JvdXAsIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci5yZW1vdmVGaWxlR3JvdXAoZ3JvdXBLZXksIC8qIHBlbmRpbmdPbmx5PSAqLyBmYWxzZSkuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleSkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAoZG93bmxvYWRlZEdyb3VwS2V5KSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKS5nZXQoKSkKKyAgICAgICAgLmNvbnRhaW5zRXhhY3RseSgKKyAgICAgICAgICAgIGRvd25sb2FkZWRGaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkZWRGaWxlR3JvdXAuZ2V0Qm9va2tlZXBpbmcoKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUoMSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKworICAgIFVyaSBwZW5kaW5nRmlsZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgcmVnaXN0ZXJlZEZpbGVLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgIHJlZ2lzdGVyZWRGaWxlLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgcmVnaXN0ZXJlZEZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKworICAgIC8vIE9ubHkgY2FsbGVkIG9uY2UgdG8gc3RvcCBkb3dubG9hZCBvZiBwZW5kaW5nIGZpbGUuCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyKS5zdG9wRG93bmxvYWRpbmcocGVuZGluZ0ZpbGVVcmkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlRmlsZUdyb3VwX2JvdGhWZXJzaW9uc0V4aXN0X29ubHlSZW1vdmVQZW5kaW5nKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgcmVnaXN0ZXJlZEZpbGUgPQorICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkuc2V0RmlsZUlkKCJmaWxlIikuc2V0Q2hlY2tzdW0oInJlZ2lzdGVyZWQiKS5idWlsZCgpOworICAgIERhdGFGaWxlIGRvd25sb2FkZWRGaWxlID0KKyAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpLnNldEZpbGVJZCgiZmlsZSIpLnNldENoZWNrc3VtKCJkb3dubG9hZGVkIikuYnVpbGQoKTsKKworICAgIE5ld0ZpbGVLZXkgcmVnaXN0ZXJlZEZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShyZWdpc3RlcmVkRmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nRmlsZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldEZpbGVHcm91cFZlcnNpb25OdW1iZXIoMSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVyc0VudW0oQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKQorICAgICAgICAgICAgLmFkZEZpbGUocmVnaXN0ZXJlZEZpbGUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZEZpbGVHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRGaWxlR3JvdXBWZXJzaW9uTnVtYmVyKDApCisgICAgICAgICAgICAuc2V0QnVpbGRJZCgwKQorICAgICAgICAgICAgLnNldFZhcmlhbnRJZCgiIikKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVyc0VudW0oQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKQorICAgICAgICAgICAgLmFkZEZpbGUoZG93bmxvYWRlZEZpbGUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleSA9IGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5ID0gZ3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZCh0cnVlKS5idWlsZCgpOworCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleSwgcGVuZGluZ0ZpbGVHcm91cCk7CisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGRvd25sb2FkZWRHcm91cEtleSwgZG93bmxvYWRlZEZpbGVHcm91cCk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgcGVuZGluZ0ZpbGVHcm91cCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgZG93bmxvYWRlZEZpbGVHcm91cCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyLnJlbW92ZUZpbGVHcm91cChncm91cEtleSwgLyogcGVuZGluZ09ubHk9ICovIHRydWUpLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXkpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKGRvd25sb2FkZWRHcm91cEtleSkpLmlzTnVsbCgpOworCisgICAgLy8gUGVuZGluZyBncm91cCB3YXMganVzdCByZW1vdmVkLCBhbmQgZG93bmxvYWRlZCB3YXMgbm90IGFkZGVkIHRvIHN0YWxlIGdyb3Vwcy4KKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxTdGFsZUdyb3VwcygpLmdldCgpKS5pc0VtcHR5KCk7CisgICAgLy8gRG93bmxvYWRlZCBncm91cCBpcyBzdGlsbCBhdmFpbGFibGUuCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKS5nZXQoKSkKKyAgICAgICAgLmNvbnRhaW5zRXhhY3RseShQYWlyLmNyZWF0ZShkb3dubG9hZGVkR3JvdXBLZXksIGRvd25sb2FkZWRGaWxlR3JvdXApKTsKKworICAgIFVyaSBwZW5kaW5nRmlsZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgcmVnaXN0ZXJlZEZpbGVLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgIHJlZ2lzdGVyZWRGaWxlLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgcmVnaXN0ZXJlZEZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKworICAgIC8vIE9ubHkgY2FsbGVkIG9uY2UgdG8gc3RvcCBkb3dubG9hZCBvZiBwZW5kaW5nIGZpbGUuCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyKS5zdG9wRG93bmxvYWRpbmcocGVuZGluZ0ZpbGVVcmkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlRmlsZUdyb3VwX2ZpbGVSZWZlcmVuY2VkQnlPdGhlckZpbGVHcm91cF93aWxsTm90Q2FuY2VsRG93bmxvYWQoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZGF0YUZpbGUxID0gRGF0YUZpbGUubmV3QnVpbGRlcigpLnNldEZpbGVJZCgiZmlsZTEiKS5zZXRDaGVja3N1bSgiY2hlY2tzdW0xIikuYnVpbGQoKTsKKyAgICBEYXRhRmlsZSBkYXRhRmlsZTIgPSBEYXRhRmlsZS5uZXdCdWlsZGVyKCkuc2V0RmlsZUlkKCJmaWxlMiIpLnNldENoZWNrc3VtKCJjaGVja3N1bTIiKS5idWlsZCgpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdGaWxlR3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0RmlsZUdyb3VwVmVyc2lvbk51bWJlcigxKQorICAgICAgICAgICAgLnNldEFsbG93ZWRSZWFkZXJzRW51bShBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpCisgICAgICAgICAgICAuYWRkQWxsRmlsZShMaXN0cy5uZXdBcnJheUxpc3QoZGF0YUZpbGUxLCBkYXRhRmlsZTIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcGVuZGluZ0ZpbGVHcm91cDIgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikKKyAgICAgICAgICAgIC5zZXRGaWxlR3JvdXBWZXJzaW9uTnVtYmVyKDEpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUykKKyAgICAgICAgICAgIC5hZGRBbGxGaWxlKExpc3RzLm5ld0FycmF5TGlzdChkYXRhRmlsZTEsIGRhdGFGaWxlMikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleSA9IGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5ID0gZ3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZCh0cnVlKS5idWlsZCgpOworCisgICAgR3JvdXBLZXkgZ3JvdXBLZXkyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgcGVuZGluZ0dyb3VwS2V5MiA9IGdyb3VwS2V5Mi50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleSwgcGVuZGluZ0ZpbGVHcm91cCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleTIsIHBlbmRpbmdGaWxlR3JvdXAyKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBwZW5kaW5nRmlsZUdyb3VwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MsIEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBwZW5kaW5nRmlsZUdyb3VwMiwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTLCBGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKS5nZXQoKSkKKyAgICAgICAgLmNvbnRhaW5zRXhhY3RseSgKKyAgICAgICAgICAgIG5ldyBQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+KHBlbmRpbmdHcm91cEtleSwgcGVuZGluZ0ZpbGVHcm91cCksCisgICAgICAgICAgICBuZXcgUGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPihwZW5kaW5nR3JvdXBLZXkyLCBwZW5kaW5nRmlsZUdyb3VwMikpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci5yZW1vdmVGaWxlR3JvdXAoZ3JvdXBLZXksIC8qIHBlbmRpbmdPbmx5PSAqLyBmYWxzZSkuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleSkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAocGVuZGluZ0dyb3VwS2V5MikpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAoZG93bmxvYWRlZEdyb3VwS2V5KSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKS5nZXQoKSkuaXNFbXB0eSgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCkuZ2V0KCkpCisgICAgICAgIC5jb250YWluc0V4YWN0bHkoCisgICAgICAgICAgICBuZXcgUGFpcjxHcm91cEtleSwgRGF0YUZpbGVHcm91cEludGVybmFsPihwZW5kaW5nR3JvdXBLZXkyLCBwZW5kaW5nRmlsZUdyb3VwMikpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyLCBuZXZlcigpKS5zdG9wRG93bmxvYWRpbmcoYW55KFVyaS5jbGFzcykpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlRmlsZUdyb3VwX29uRmFpbHVyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIE1vY2sgRmlsZUdyb3Vwc01ldGFkYXRhIHRvIHRlc3QgZmFpbHVyZSBzY2VuYXJpby4KKyAgICByZXNldEZpbGVHcm91cE1hbmFnZXIobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgc2hhcmVkRmlsZU1hbmFnZXIpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nRmlsZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldEZpbGVHcm91cFZlcnNpb25OdW1iZXIoMSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkRmlsZUdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldEZpbGVHcm91cFZlcnNpb25OdW1iZXIoMCkKKyAgICAgICAgICAgIC5zZXRCdWlsZElkKDApCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCIiKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBHcm91cEtleSBncm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXkgPSBncm91cEtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworICAgIEdyb3VwS2V5IGRvd25sb2FkZWRHcm91cEtleSA9IGdyb3VwS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKHBlbmRpbmdHcm91cEtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHBlbmRpbmdGaWxlR3JvdXApKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEucmVhZChkb3dubG9hZGVkR3JvdXBLZXkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShkb3dubG9hZGVkRmlsZUdyb3VwKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlbW92ZShwZW5kaW5nR3JvdXBLZXkpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlKGRvd25sb2FkZWRHcm91cEtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKSk7CisKKyAgICAvLyBFeGNlcHRpb24gc2hvdWxkIGJlIHRocm93biB3aGVuIGZpbGVHcm91cE1hbmFnZXIgYXR0ZW1wdHMgdG8gcmVtb3ZlIGRvd25sb2FkZWRHcm91cEtleS4KKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXhwZWN0ZWQgPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPiBmaWxlR3JvdXBNYW5hZ2VyLnJlbW92ZUZpbGVHcm91cChncm91cEtleSwgLyogcGVuZGluZ09ubHk9ICovIGZhbHNlKS5nZXQoKSk7CisgICAgYXNzZXJ0VGhhdChleHBlY3RlZCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKElPRXhjZXB0aW9uLmNsYXNzKTsKKworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhKS5yZW1vdmUocGVuZGluZ0dyb3VwS2V5KTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSkucmVtb3ZlKGRvd25sb2FkZWRHcm91cEtleSk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIG5ldmVyKCkpLmFkZFN0YWxlR3JvdXAoYW55KERhdGFGaWxlR3JvdXBJbnRlcm5hbC5jbGFzcykpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlRmlsZUdyb3VwX3JlbW92ZXNTaWRlbG9hZGVkR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgc2lkZWxvYWRlZCBncm91cAorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBzaWRlbG9hZGVkR3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuYWRkRmlsZSgKKyAgICAgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEZpbGVJZCgic2lkZWxvYWRlZF9maWxlIikKKyAgICAgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImZpbGU6L3Rlc3QiKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW1UeXBlKERhdGFGaWxlLkNoZWNrc3VtVHlwZS5OT05FKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIHNpZGVsb2FkZWRHcm91cCk7CisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXksIHNpZGVsb2FkZWRHcm91cCk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyLnJlbW92ZUZpbGVHcm91cCh0ZXN0S2V5LCAvKiBwZW5kaW5nT25seSA9ICovIGZhbHNlKS5nZXQoKTsKKworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleSkpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQKKyAgICAgIHJlbW92ZUZpbGVHcm91cF93aGVuTXVsdGlwbGVWYXJpYW50c0V4aXN0X3doZW5Ob1ZhcmlhbnRTcGVjaWZpZWRfcmVtb3Zlc0VtcHR5VmFyaWFudEdyb3VwKCkKKyAgICAgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgMyB2YXJpYW50cyBvZiBhIGdyb3VwIChkZWZhdWx0IChubyB2YXJpYW50KSwgZW4sIGZyKSBhbmQgaGF2ZSB0aGVtIGFsbCBhZGRlZC4gV2hlbgorICAgIC8vIHJlbW92ZUZpbGVHcm91cHMgaXMgY2FsbGVkIGFuZCB0aGUgZ3JvdXAga2V5IGdpdmVuIGRvZXMgbm90IGluY2x1ZGUgYSB2YXJpYW50LCBlbnN1cmUgdGhhdAorICAgIC8vIHRoZSBkZWZhdWx0IGdyb3VwIGlzIHJlbW92ZWQuCisKKyAgICBHcm91cEtleSBkZWZhdWx0R3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZW5Hcm91cEtleSA9IGRlZmF1bHRHcm91cEtleS50b0J1aWxkZXIoKS5zZXRWYXJpYW50SWQoImVuIikuYnVpbGQoKTsKKyAgICBHcm91cEtleSBmckdyb3VwS2V5ID0gZGVmYXVsdEdyb3VwS2V5LnRvQnVpbGRlcigpLnNldFZhcmlhbnRJZCgiZnIiKS5idWlsZCgpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRlZmF1bHRGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGVuRmlsZUdyb3VwID0gZGVmYXVsdEZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRWYXJpYW50SWQoImVuIikuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZnJGaWxlR3JvdXAgPSBkZWZhdWx0RmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldFZhcmlhbnRJZCgiZnIiKS5idWlsZCgpOworCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKGdldFBlbmRpbmdLZXkoZGVmYXVsdEdyb3VwS2V5KSwgZGVmYXVsdEZpbGVHcm91cCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKGdldFBlbmRpbmdLZXkoZW5Hcm91cEtleSksIGVuRmlsZUdyb3VwKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAoZ2V0UGVuZGluZ0tleShmckdyb3VwS2V5KSwgZnJGaWxlR3JvdXApOworCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgZGVmYXVsdEZpbGVHcm91cCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgZW5GaWxlR3JvdXAsIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIGZyRmlsZUdyb3VwLCBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKworICAgIC8vIEFzc2VydCB0aGF0IGFsbCBmaWxlIGdyb3VwcyBzaGFyZSB0aGUgc2FtZSBmaWxlIGV2ZW4gdGhyb3VnaCB0aGUgdmFyaWFudHMgYXJlIGRpZmZlcmVudAorICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpLmdldCgpKS5oYXNTaXplKDEpOworCisgICAgeworICAgICAgLy8gUGVyZnJvbSByZW1vdmFsIG9uY2UgYW5kIGNoZWNrIHRoYXQgdGhlIGRlZmF1bHQgZ3JvdXAgZ2V0cyByZW1vdmVkCisgICAgICBmaWxlR3JvdXBNYW5hZ2VyLnJlbW92ZUZpbGVHcm91cChkZWZhdWx0R3JvdXBLZXksIC8qIHBlbmRpbmdPbmx5ID0gKi8gZmFsc2UpLmdldCgpOworCisgICAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxHcm91cEtleXMoKS5nZXQoKSkKKyAgICAgICAgICAuY29tcGFyaW5nRWxlbWVudHNVc2luZyhHUk9VUF9LRVlfVE9fVkFSSUFOVCkKKyAgICAgICAgICAuY29udGFpbnNFeGFjdGx5KCJlbiIsICJmciIpOworICAgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKS5nZXQoKSkKKyAgICAgICAgICAuY29tcGFyaW5nRWxlbWVudHNVc2luZyhLRVlfR1JPVVBfUEFJUl9UT19WQVJJQU5UX1BBSVIpCisgICAgICAgICAgLmNvbnRhaW5zRXhhY3RseShQYWlyLmNyZWF0ZSgiZW4iLCAiZW4iKSwgUGFpci5jcmVhdGUoImZyIiwgImZyIikpOworCisgICAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKS5nZXQoKSkuaGFzU2l6ZSgxKTsKKyAgICB9CisKKyAgICB7CisgICAgICAvLyBQZXJmb3JtIHJlbW92ZSBhZ2FpbiBhbmQgdmVyaWZ5IHRoYXQgdGhlcmUgaXMgbm8gY2hhbmdlIGluIHN0YXRlCisgICAgICBmaWxlR3JvdXBNYW5hZ2VyLnJlbW92ZUZpbGVHcm91cChkZWZhdWx0R3JvdXBLZXksIC8qIHBlbmRpbmdPbmx5ID0gKi8gZmFsc2UpLmdldCgpOworCisgICAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxHcm91cEtleXMoKS5nZXQoKSkKKyAgICAgICAgICAuY29tcGFyaW5nRWxlbWVudHNVc2luZyhHUk9VUF9LRVlfVE9fVkFSSUFOVCkKKyAgICAgICAgICAuY29udGFpbnNFeGFjdGx5KCJlbiIsICJmciIpOworICAgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKS5nZXQoKSkKKyAgICAgICAgICAuY29tcGFyaW5nRWxlbWVudHNVc2luZyhLRVlfR1JPVVBfUEFJUl9UT19WQVJJQU5UX1BBSVIpCisgICAgICAgICAgLmNvbnRhaW5zRXhhY3RseShQYWlyLmNyZWF0ZSgiZW4iLCAiZW4iKSwgUGFpci5jcmVhdGUoImZyIiwgImZyIikpOworCisgICAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKS5nZXQoKSkuaGFzU2l6ZSgxKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZW1vdmVGaWxlR3JvdXBfd2hlbk11bHRpcGxlVmFyaWFudHNFeGlzdF93aGVuVmFyaWFudFNwZWNpZmllZF9yZW1vdmVzVmFyaWFudEdyb3VwKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENyZWF0ZSAzIHZhcmlhbnRzIG9mIGEgZ3JvdXAgKGRlZmF1bHQgKG5vIHZhcmlhbnQpLCBlbiwgZnIpIGFuZCBoYXZlIHRoZW0gYWxsIGFkZGVkLiBXaGVuCisgICAgLy8gcmVtb3ZlRmlsZUdyb3VwcyBpcyBjYWxsZWQgYW5kIHRoZSBncm91cCBrZXkgZ2l2ZW4gaW5jbHVkZXMgYSB2YXJpYW50LCBlbnN1cmUgdGhhdCBvbmx5CisgICAgLy8gdGhlIGdyb3VwIHdpdGggdGhhdCB2YXJpYW50IGlzIHJlbW92ZWQuCisKKyAgICBHcm91cEtleSBkZWZhdWx0R3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZW5Hcm91cEtleSA9IGRlZmF1bHRHcm91cEtleS50b0J1aWxkZXIoKS5zZXRWYXJpYW50SWQoImVuIikuYnVpbGQoKTsKKyAgICBHcm91cEtleSBmckdyb3VwS2V5ID0gZGVmYXVsdEdyb3VwS2V5LnRvQnVpbGRlcigpLnNldFZhcmlhbnRJZCgiZnIiKS5idWlsZCgpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRlZmF1bHRGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGVuRmlsZUdyb3VwID0gZGVmYXVsdEZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRWYXJpYW50SWQoImVuIikuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZnJGaWxlR3JvdXAgPSBkZWZhdWx0RmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldFZhcmlhbnRJZCgiZnIiKS5idWlsZCgpOworCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKGdldFBlbmRpbmdLZXkoZGVmYXVsdEdyb3VwS2V5KSwgZGVmYXVsdEZpbGVHcm91cCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKGdldFBlbmRpbmdLZXkoZW5Hcm91cEtleSksIGVuRmlsZUdyb3VwKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAoZ2V0UGVuZGluZ0tleShmckdyb3VwS2V5KSwgZnJGaWxlR3JvdXApOworCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgZGVmYXVsdEZpbGVHcm91cCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgZW5GaWxlR3JvdXAsIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIGZyRmlsZUdyb3VwLCBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKworICAgIC8vIEFzc2VydCB0aGF0IGFsbCBmaWxlIGdyb3VwcyBzaGFyZSB0aGUgc2FtZSBmaWxlIGV2ZW4gdGhyb3VnaCB0aGUgdmFyaWFudHMgYXJlIGRpZmZlcmVudAorICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpLmdldCgpKS5oYXNTaXplKDEpOworCisgICAgeworICAgICAgLy8gUGVyZnJvbSByZW1vdmFsIG9uY2UgYW5kIGNoZWNrIHRoYXQgdGhlIGVuIGdyb3VwIGdldHMgcmVtb3ZlZAorICAgICAgZmlsZUdyb3VwTWFuYWdlci5yZW1vdmVGaWxlR3JvdXAoZW5Hcm91cEtleSwgLyogcGVuZGluZ09ubHkgPSAqLyBmYWxzZSkuZ2V0KCk7CisKKyAgICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEdyb3VwS2V5cygpLmdldCgpKQorICAgICAgICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKEdST1VQX0tFWV9UT19WQVJJQU5UKQorICAgICAgICAgIC5jb250YWluc0V4YWN0bHkoIiIsICJmciIpOworICAgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKS5nZXQoKSkKKyAgICAgICAgICAuY29tcGFyaW5nRWxlbWVudHNVc2luZyhLRVlfR1JPVVBfUEFJUl9UT19WQVJJQU5UX1BBSVIpCisgICAgICAgICAgLmNvbnRhaW5zRXhhY3RseShQYWlyLmNyZWF0ZSgiIiwgIiIpLCBQYWlyLmNyZWF0ZSgiZnIiLCAiZnIiKSk7CisKKyAgICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpLmdldCgpKS5oYXNTaXplKDEpOworICAgIH0KKworICAgIHsKKyAgICAgIC8vIFBlcmZvcm0gcmVtb3ZlIGFnYWluIGFuZCB2ZXJpZnkgdGhhdCB0aGVyZSBpcyBubyBjaGFuZ2UgaW4gc3RhdGUKKyAgICAgIGZpbGVHcm91cE1hbmFnZXIucmVtb3ZlRmlsZUdyb3VwKGVuR3JvdXBLZXksIC8qIHBlbmRpbmdPbmx5ID0gKi8gZmFsc2UpLmdldCgpOworCisgICAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxHcm91cEtleXMoKS5nZXQoKSkKKyAgICAgICAgICAuY29tcGFyaW5nRWxlbWVudHNVc2luZyhHUk9VUF9LRVlfVE9fVkFSSUFOVCkKKyAgICAgICAgICAuY29udGFpbnNFeGFjdGx5KCIiLCAiZnIiKTsKKyAgICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCkuZ2V0KCkpCisgICAgICAgICAgLmNvbXBhcmluZ0VsZW1lbnRzVXNpbmcoS0VZX0dST1VQX1BBSVJfVE9fVkFSSUFOVF9QQUlSKQorICAgICAgICAgIC5jb250YWluc0V4YWN0bHkoUGFpci5jcmVhdGUoIiIsICIiKSwgUGFpci5jcmVhdGUoImZyIiwgImZyIikpOworCisgICAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKS5nZXQoKSkuaGFzU2l6ZSgxKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRmlsZUdyb3Vwc193aGVuTm9Hcm91cHNFeGlzdF9wZXJmb3Jtc05vUmVtb3ZhbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBHcm91cEtleSBncm91cEtleTEgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZ3JvdXBLZXkyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyLnJlbW92ZUZpbGVHcm91cHMoSW1tdXRhYmxlTGlzdC5vZihncm91cEtleTEsIGdyb3VwS2V5MikpLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKS5nZXQoKSkuaXNFbXB0eSgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEdyb3VwS2V5cygpLmdldCgpKS5pc0VtcHR5KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRmlsZUdyb3Vwc193aGVuTm9NYXRjaGluZ0tleXNFeGlzdF9wZXJmb3Jtc05vUmVtb3ZhbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgYSBwZW5kaW5nIGFuZCBkb3dubG9hZGVkIHZlcnNpb24gb2YgYSBmaWxlIGdyb3VwCisgICAgLy8gUGVuZGluZyBncm91cCBpbmNsdWRlcyAyIGZpbGVzOiAxIHRoYXQgaXMgc2hhcmVkIHdpdGggZG93bmxvYWRlZCBncm91cCBhbmQgb25lIHRoYXQgd2lsbCBiZQorICAgIC8vIG1hcmtlZCBwZW5kaW5nCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisKKyAgICBHcm91cEtleS5CdWlsZGVyIGdyb3VwS2V5QnVpbGRlciA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgR3JvdXBLZXkgcGVuZGluZ0dyb3VwS2V5ID0gZ3JvdXBLZXlCdWlsZGVyLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5ID0gZ3JvdXBLZXlCdWlsZGVyLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKyAgICBHcm91cEtleSBub25NYXRjaGluZ0dyb3VwS2V5MSA9IGdyb3VwS2V5QnVpbGRlci5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8yKS5idWlsZCgpOworICAgIEdyb3VwS2V5IG5vbk1hdGNoaW5nR3JvdXBLZXkyID0gZ3JvdXBLZXlCdWlsZGVyLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzMpLmJ1aWxkKCk7CisKKyAgICAvLyBXcml0ZSBmaWxlIGdyb3VwIGFuZCBzaGFyZWQgZmlsZSBtZXRhZGF0YQorICAgIC8vIE5PVEU6IHBlbmRpbmcgZ3JvdXAgY29udGFpbnMgYWxsIGZpbGVzIGluIGRvd25sb2FkZWQgZ3JvdXAsIHNvIHdlIG9ubHkgbmVlZCB0byB3cml0ZSBzaGFyZWQKKyAgICAvLyBmaWxlIHN0YXRlIG9uY2UuCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleSwgcGVuZGluZ0ZpbGVHcm91cCk7CisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGRvd25sb2FkZWRHcm91cEtleSwgZG93bmxvYWRlZEZpbGVHcm91cCk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgcGVuZGluZ0ZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgIC5yZW1vdmVGaWxlR3JvdXBzKEltbXV0YWJsZUxpc3Qub2Yobm9uTWF0Y2hpbmdHcm91cEtleTEsIG5vbk1hdGNoaW5nR3JvdXBLZXkyKSkKKyAgICAgICAgLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXkpKS5pc05vdE51bGwoKTsKKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKGRvd25sb2FkZWRHcm91cEtleSkpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCkuZ2V0KCkpLmhhc1NpemUoMik7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKS5nZXQoKSkuaXNFbXB0eSgpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyLCB0aW1lcygwKSkuc3RvcERvd25sb2FkaW5nKGFueSgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVGaWxlR3JvdXBzX3doZW5NYXRjaGluZ1BlbmRpbmdHcm91cHNfcGVyZm9ybXNSZW1vdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgMiBwZW5kaW5nIGdyb3VwcyB0aGF0IHdpbGwgYmUgcmVtb3ZlZCwgMSBwZW5kaW5nIGdyb3VwIHRoYXQgc2hvdWxkbid0IGJlIHJlbW92ZWQsIGFuZAorICAgIC8vIDEgZG93bmxvYWRlZCBncm91cCB0aGF0IHNob3VsZG4ndCBiZSByZW1vdmVkCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdHcm91cFRvUmVtb3ZlMSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKS5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXBUb1JlbW92ZTIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAxKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcGVuZGluZ0dyb3VwVG9LZWVwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMywgMSkudG9CdWlsZGVyKCkuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZEdyb3VwVG9LZWVwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfNCwgMSk7CisKKyAgICBHcm91cEtleS5CdWlsZGVyIGdyb3VwS2V5QnVpbGRlciA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKS5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKS5zZXREb3dubG9hZGVkKGZhbHNlKTsKKyAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXlUb1JlbW92ZTEgPSBncm91cEtleUJ1aWxkZXIuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgcGVuZGluZ0dyb3VwS2V5VG9SZW1vdmUyID0gZ3JvdXBLZXlCdWlsZGVyLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzIpLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgcGVuZGluZ0dyb3VwS2V5VG9LZWVwID0gZ3JvdXBLZXlCdWlsZGVyLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzMpLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5VG9LZWVwID0KKyAgICAgICAgZ3JvdXBLZXlCdWlsZGVyLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzQpLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXlUb1JlbW92ZTEsIHBlbmRpbmdHcm91cFRvUmVtb3ZlMSk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleVRvUmVtb3ZlMiwgcGVuZGluZ0dyb3VwVG9SZW1vdmUyKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAocGVuZGluZ0dyb3VwS2V5VG9LZWVwLCBwZW5kaW5nR3JvdXBUb0tlZXApOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChkb3dubG9hZGVkR3JvdXBLZXlUb0tlZXAsIGRvd25sb2FkZWRHcm91cFRvS2VlcCk7CisKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBwZW5kaW5nR3JvdXBUb1JlbW92ZTEsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIHBlbmRpbmdHcm91cFRvUmVtb3ZlMiwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgcGVuZGluZ0dyb3VwVG9LZWVwLCBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLCBkb3dubG9hZGVkR3JvdXBUb0tlZXAsIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworCisgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAucmVtb3ZlRmlsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKHBlbmRpbmdHcm91cEtleVRvUmVtb3ZlMSwgcGVuZGluZ0dyb3VwS2V5VG9SZW1vdmUyKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gQ29uc3RydWN0IFBlbmRpbmcgRmlsZSBVcmlzIHRvIGNoZWNrIHdoaWNoIGRvd25sb2FkcyB3ZXJlIHN0b3BwZWQKKyAgICBOZXdGaWxlS2V5IHBlbmRpbmdGaWxlS2V5MSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKHBlbmRpbmdHcm91cFRvUmVtb3ZlMSlbMF07CisgICAgTmV3RmlsZUtleSBwZW5kaW5nRmlsZUtleTIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChwZW5kaW5nR3JvdXBUb1JlbW92ZTIpWzBdOworICAgIE5ld0ZpbGVLZXkgcGVuZGluZ0ZpbGVLZXkzID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwocGVuZGluZ0dyb3VwVG9LZWVwKVswXTsKKyAgICBVcmkgcGVuZGluZ0ZpbGVVcmkxID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBwZW5kaW5nRmlsZUtleTEuZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgIHBlbmRpbmdHcm91cFRvUmVtb3ZlMS5nZXRGaWxlKDApLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgcGVuZGluZ0ZpbGVLZXkxLmdldENoZWNrc3VtKCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAvKiBpbnN0YW5jZUlkID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAvKiBhbmRyb2lkU2hhcmVkID0gKi8gZmFsc2UpOworICAgIFVyaSBwZW5kaW5nRmlsZVVyaTIgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE9uRGV2aWNlVXJpKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIHBlbmRpbmdGaWxlS2V5Mi5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgcGVuZGluZ0dyb3VwVG9SZW1vdmUyLmdldEZpbGUoMCkuZ2V0RmlsZUlkKCksCisgICAgICAgICAgICBwZW5kaW5nRmlsZUtleTIuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIC8qIGFuZHJvaWRTaGFyZWQgPSAqLyBmYWxzZSk7CisgICAgVXJpIHBlbmRpbmdGaWxlVXJpMyA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgcGVuZGluZ0ZpbGVLZXkzLmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBwZW5kaW5nR3JvdXBUb0tlZXAuZ2V0RmlsZSgwKS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgIHBlbmRpbmdGaWxlS2V5My5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgLyogaW5zdGFuY2VJZCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKworICAgIC8vIEFzc2VydCB0aGF0IG1hdGNoaW5nIHBlbmRpbmcgZ3JvdXBzIGFyZSByZW1vdmVkCisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXlUb1JlbW92ZTEpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleVRvUmVtb3ZlMikpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAocGVuZGluZ0dyb3VwS2V5VG9LZWVwKSkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cChkb3dubG9hZGVkR3JvdXBLZXlUb0tlZXApKS5pc05vdE51bGwoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpLmdldCgpKS5oYXNTaXplKDIpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbFN0YWxlR3JvdXBzKCkuZ2V0KCkpLmlzRW1wdHkoKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRlcikuc3RvcERvd25sb2FkaW5nKHBlbmRpbmdGaWxlVXJpMSk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyKS5zdG9wRG93bmxvYWRpbmcocGVuZGluZ0ZpbGVVcmkyKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkZXIsIHRpbWVzKDApKS5zdG9wRG93bmxvYWRpbmcocGVuZGluZ0ZpbGVVcmkzKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVGaWxlR3JvdXBzX3doZW5NYXRjaGluZ0Rvd25sb2FkZWRHcm91cHNfcGVyZm9ybXNSZW1vdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgMiBkb3dubG9hZGVkIGdyb3VwcyB0aGF0IHdpbGwgYmUgcmVtb3ZlZCwgMSBkb3dubG9hZGVkIGdyb3VwIHRoYXQgc2hvdWxkbid0IGJlCisgICAgLy8gcmVtb3ZlZCwgYW5kIDEgcGVuZGluZyBncm91cCB0aGF0IHNob3VsZG4ndCBiZSByZW1vdmVkCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRHcm91cFRvUmVtb3ZlMSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZEdyb3VwVG9SZW1vdmUyID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRHcm91cFRvS2VlcCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzMsIDEpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXBUb0tlZXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF80LCAxKS50b0J1aWxkZXIoKS5idWlsZCgpOworCisgICAgR3JvdXBLZXkuQnVpbGRlciBncm91cEtleUJ1aWxkZXIgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkuc2V0RG93bmxvYWRlZCh0cnVlKTsKKyAgICBHcm91cEtleSBkb3dubG9hZGVkR3JvdXBLZXlUb1JlbW92ZTEgPSBncm91cEtleUJ1aWxkZXIuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5VG9SZW1vdmUyID0gZ3JvdXBLZXlCdWlsZGVyLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzIpLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5VG9LZWVwID0gZ3JvdXBLZXlCdWlsZGVyLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzMpLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgcGVuZGluZ0dyb3VwS2V5VG9LZWVwID0KKyAgICAgICAgZ3JvdXBLZXlCdWlsZGVyLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzQpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAoZG93bmxvYWRlZEdyb3VwS2V5VG9SZW1vdmUxLCBkb3dubG9hZGVkR3JvdXBUb1JlbW92ZTEpOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChkb3dubG9hZGVkR3JvdXBLZXlUb1JlbW92ZTIsIGRvd25sb2FkZWRHcm91cFRvUmVtb3ZlMik7CisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGRvd25sb2FkZWRHcm91cEtleVRvS2VlcCwgZG93bmxvYWRlZEdyb3VwVG9LZWVwKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAocGVuZGluZ0dyb3VwS2V5VG9LZWVwLCBwZW5kaW5nR3JvdXBUb0tlZXApOworCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZG93bmxvYWRlZEdyb3VwVG9SZW1vdmUxLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBkb3dubG9hZGVkR3JvdXBUb1JlbW92ZTIsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIGRvd25sb2FkZWRHcm91cFRvS2VlcCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgcGVuZGluZ0dyb3VwVG9LZWVwLCBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLnJlbW92ZUZpbGVHcm91cHMoCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKGRvd25sb2FkZWRHcm91cEtleVRvUmVtb3ZlMSwgZG93bmxvYWRlZEdyb3VwS2V5VG9SZW1vdmUyKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gQ29uc3RydWN0IFBlbmRpbmcgRmlsZSBVcmkgdG8gY2hlY2sgdGhhdCBpdCBpc24ndCBjYW5jZWxsZWQKKyAgICBOZXdGaWxlS2V5IHBlbmRpbmdGaWxlS2V5MSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKHBlbmRpbmdHcm91cFRvS2VlcClbMF07CisgICAgVXJpIHBlbmRpbmdGaWxlVXJpMSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgcGVuZGluZ0ZpbGVLZXkxLmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBwZW5kaW5nR3JvdXBUb0tlZXAuZ2V0RmlsZSgwKS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgIHBlbmRpbmdGaWxlS2V5MS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgLyogaW5zdGFuY2VJZCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKworICAgIC8vIEFzc2VydCB0aGF0IG1hdGNoaW5nIHBlbmRpbmcgZ3JvdXBzIGFyZSByZW1vdmVkCisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cChkb3dubG9hZGVkR3JvdXBLZXlUb1JlbW92ZTEpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKGRvd25sb2FkZWRHcm91cEtleVRvUmVtb3ZlMikpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAoZG93bmxvYWRlZEdyb3VwS2V5VG9LZWVwKSkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXlUb0tlZXApKS5pc05vdE51bGwoKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEZyZXNoR3JvdXBzKCkuZ2V0KCkpCisgICAgICAgIC5jb250YWluc0V4YWN0bHkoCisgICAgICAgICAgICBQYWlyLmNyZWF0ZShkb3dubG9hZGVkR3JvdXBLZXlUb0tlZXAsIGRvd25sb2FkZWRHcm91cFRvS2VlcCksCisgICAgICAgICAgICBQYWlyLmNyZWF0ZShwZW5kaW5nR3JvdXBLZXlUb0tlZXAsIHBlbmRpbmdHcm91cFRvS2VlcCkpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbFN0YWxlR3JvdXBzKCkuZ2V0KCkpCisgICAgICAgIC5jb250YWluc0V4YWN0bHkoCisgICAgICAgICAgICBkb3dubG9hZGVkR3JvdXBUb1JlbW92ZTEudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkZWRHcm91cFRvUmVtb3ZlMS5nZXRCb29ra2VlcGluZygpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0U3RhbGVFeHBpcmF0aW9uRGF0ZSgxKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCksCisgICAgICAgICAgICBkb3dubG9hZGVkR3JvdXBUb1JlbW92ZTIudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkZWRHcm91cFRvUmVtb3ZlMi5nZXRCb29ra2VlcGluZygpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0U3RhbGVFeHBpcmF0aW9uRGF0ZSgxKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyLCB0aW1lcygwKSkuc3RvcERvd25sb2FkaW5nKHBlbmRpbmdGaWxlVXJpMSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRmlsZUdyb3Vwc193aGVuTWF0Y2hpbmdCb3RoVmVyc2lvbnNfcGVyZm9ybXNSZW1vdmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgMiBmaWxlIGdyb3VwcywgZWFjaCB3aXRoIDIgdmVyc2lvbnMgKGRvd25sb2FkZWQgYW5kIHBlbmRpbmcpCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRHcm91cFRvUmVtb3ZlMSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZEdyb3VwVG9SZW1vdmUyID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdHcm91cFRvUmVtb3ZlMSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKS5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXBUb1JlbW92ZTIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAxKTsKKworICAgIEdyb3VwS2V5LkJ1aWxkZXIgZ3JvdXBLZXlCdWlsZGVyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpLnNldERvd25sb2FkZWQodHJ1ZSk7CisgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5VG9SZW1vdmUxID0gZ3JvdXBLZXlCdWlsZGVyLnNldEdyb3VwTmFtZShURVNUX0dST1VQKS5idWlsZCgpOworICAgIEdyb3VwS2V5IGRvd25sb2FkZWRHcm91cEtleVRvUmVtb3ZlMiA9IGdyb3VwS2V5QnVpbGRlci5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8yKS5idWlsZCgpOworICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleVRvUmVtb3ZlMSA9CisgICAgICAgIGdyb3VwS2V5QnVpbGRlci5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKyAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXlUb1JlbW92ZTIgPQorICAgICAgICBncm91cEtleUJ1aWxkZXIuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChkb3dubG9hZGVkR3JvdXBLZXlUb1JlbW92ZTEsIGRvd25sb2FkZWRHcm91cFRvUmVtb3ZlMSk7CisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGRvd25sb2FkZWRHcm91cEtleVRvUmVtb3ZlMiwgZG93bmxvYWRlZEdyb3VwVG9SZW1vdmUyKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAocGVuZGluZ0dyb3VwS2V5VG9SZW1vdmUxLCBwZW5kaW5nR3JvdXBUb1JlbW92ZTEpOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXlUb1JlbW92ZTIsIHBlbmRpbmdHcm91cFRvUmVtb3ZlMik7CisKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBkb3dubG9hZGVkR3JvdXBUb1JlbW92ZTEsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGRvd25sb2FkZWRHcm91cFRvUmVtb3ZlMiwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgcGVuZGluZ0dyb3VwVG9SZW1vdmUxLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBwZW5kaW5nR3JvdXBUb1JlbW92ZTIsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworCisgICAgLy8gTk9URTogdGhlIGRvd25sb2FkZWQgdmVyc2lvbiBvZiBrZXlzIGFyZSB1c2VkIGluIHRoaXMgY2FsbCwgYnV0IHRoaXMgc2hvdWxkbid0IGJlIHJlbGV2YW50OworICAgIC8vIGJvdGggZG93bmxvYWRlZCBhbmQgcGVuZGluZyB2ZXJzaW9ucyBvZiBncm91cCBrZXlzIHNob3VsZCBiZSBjaGVja2VkIGZvciByZW1vdmFsLgorICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLnJlbW92ZUZpbGVHcm91cHMoCisgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKGRvd25sb2FkZWRHcm91cEtleVRvUmVtb3ZlMSwgZG93bmxvYWRlZEdyb3VwS2V5VG9SZW1vdmUyKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gQ29uc3RydWN0IFBlbmRpbmcgRmlsZSBVcmkgdG8gY2hlY2sgdGhhdCBpdHMgZG93bmxvYWQgd2FzIGNhbmNlbGxlZAorICAgIE5ld0ZpbGVLZXkgcGVuZGluZ0ZpbGVLZXkxID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwocGVuZGluZ0dyb3VwVG9SZW1vdmUxKVswXTsKKyAgICBOZXdGaWxlS2V5IHBlbmRpbmdGaWxlS2V5MiA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKHBlbmRpbmdHcm91cFRvUmVtb3ZlMilbMF07CisgICAgVXJpIHBlbmRpbmdGaWxlVXJpMSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgcGVuZGluZ0ZpbGVLZXkxLmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBwZW5kaW5nR3JvdXBUb1JlbW92ZTEuZ2V0RmlsZSgwKS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgIHBlbmRpbmdGaWxlS2V5MS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgLyogaW5zdGFuY2VJZCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKyAgICBVcmkgcGVuZGluZ0ZpbGVVcmkyID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBwZW5kaW5nRmlsZUtleTIuZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgIHBlbmRpbmdHcm91cFRvUmVtb3ZlMi5nZXRGaWxlKDApLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgcGVuZGluZ0ZpbGVLZXkyLmdldENoZWNrc3VtKCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAvKiBpbnN0YW5jZUlkID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAvKiBhbmRyb2lkU2hhcmVkID0gKi8gZmFsc2UpOworCisgICAgLy8gQXNzZXJ0IHRoYXQgbWF0Y2hpbmcgcGVuZGluZyBncm91cHMgYXJlIHJlbW92ZWQKKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKGRvd25sb2FkZWRHcm91cEtleVRvUmVtb3ZlMSkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAoZG93bmxvYWRlZEdyb3VwS2V5VG9SZW1vdmUyKSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXlUb1JlbW92ZTEpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleVRvUmVtb3ZlMikpLmlzTnVsbCgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKS5nZXQoKSkuaXNFbXB0eSgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbFN0YWxlR3JvdXBzKCkuZ2V0KCkpCisgICAgICAgIC5jb250YWluc0V4YWN0bHkoCisgICAgICAgICAgICBkb3dubG9hZGVkR3JvdXBUb1JlbW92ZTEudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkZWRHcm91cFRvUmVtb3ZlMS5nZXRCb29ra2VlcGluZygpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0U3RhbGVFeHBpcmF0aW9uRGF0ZSgxKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCksCisgICAgICAgICAgICBkb3dubG9hZGVkR3JvdXBUb1JlbW92ZTIudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkZWRHcm91cFRvUmVtb3ZlMi5nZXRCb29ra2VlcGluZygpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0U3RhbGVFeHBpcmF0aW9uRGF0ZSgxKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyLCB0aW1lcygxKSkuc3RvcERvd25sb2FkaW5nKHBlbmRpbmdGaWxlVXJpMSk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyLCB0aW1lcygxKSkuc3RvcERvd25sb2FkaW5nKHBlbmRpbmdGaWxlVXJpMik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRmlsZUdyb3Vwc193aGVuRmlsZXNBcmVSZWZlcmVuY2VkQnlPdGhlckdyb3Vwc19kb2VzTm90Q2FuY2VsRG93bmxvYWRzKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFNldHVwIDIgcGVuZGluZyBncm91cHMgdG8gcmVtb3ZlIHRoYXQgZWFjaCBjb250YWluIGEgZmlsZSByZWZlcmVuY2VkIGJ5IGEgM3JkIHBlbmRpbmcgZ3JvdXAKKyAgICAvLyB0aGF0IGRvZXNuJ3QgZ2V0IHJlbW92ZWQuIFRoZSBwZW5kaW5nIGZpbGUgZG93bmxvYWRzIHJlZmVyZW5jZWQgYnkgdGhlIDNyZCBncm91cCBzaG91bGQgbm90CisgICAgLy8gYmUgY2FuY2VsbGVkLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXBUb0tlZXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdHcm91cFRvUmVtb3ZlMSA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzIsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuYWRkRmlsZShwZW5kaW5nR3JvdXBUb0tlZXAuZ2V0RmlsZSgwKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXBUb1JlbW92ZTIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8zLCAxKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEZpbGUocGVuZGluZ0dyb3VwVG9LZWVwLmdldEZpbGUoMSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIEdyb3VwS2V5LkJ1aWxkZXIgZ3JvdXBLZXlCdWlsZGVyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpLnNldERvd25sb2FkZWQoZmFsc2UpOworICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleVRvS2VlcCA9IGdyb3VwS2V5QnVpbGRlci5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkuYnVpbGQoKTsKKyAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXlUb1JlbW92ZTEgPSBncm91cEtleUJ1aWxkZXIuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikuYnVpbGQoKTsKKyAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXlUb1JlbW92ZTIgPSBncm91cEtleUJ1aWxkZXIuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMykuYnVpbGQoKTsKKworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXlUb0tlZXAsIHBlbmRpbmdHcm91cFRvS2VlcCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleVRvUmVtb3ZlMSwgcGVuZGluZ0dyb3VwVG9SZW1vdmUxKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAocGVuZGluZ0dyb3VwS2V5VG9SZW1vdmUyLCBwZW5kaW5nR3JvdXBUb1JlbW92ZTIpOworCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgcGVuZGluZ0dyb3VwVG9LZWVwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MsIEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBwZW5kaW5nR3JvdXBUb1JlbW92ZTEsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUywgRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIHBlbmRpbmdHcm91cFRvUmVtb3ZlMiwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTLCBGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgIC5yZW1vdmVGaWxlR3JvdXBzKEltbXV0YWJsZUxpc3Qub2YocGVuZGluZ0dyb3VwS2V5VG9SZW1vdmUxLCBwZW5kaW5nR3JvdXBLZXlUb1JlbW92ZTIpKQorICAgICAgICAuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleVRvUmVtb3ZlMSkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAocGVuZGluZ0dyb3VwS2V5VG9SZW1vdmUyKSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXlUb0tlZXApKS5pc05vdE51bGwoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpLmdldCgpKQorICAgICAgICAuY29udGFpbnNFeGFjdGx5KFBhaXIuY3JlYXRlKHBlbmRpbmdHcm91cEtleVRvS2VlcCwgcGVuZGluZ0dyb3VwVG9LZWVwKSk7CisKKyAgICAvLyBHZXQgT24gRGV2aWNlIFVyaXMgdG8gY2hlY2sgaWYgZmlsZSBkb3dubG9hZHMgd2VyZSBjYW5jZWxsZWQKKyAgICBMaXN0PFVyaT4gdW5jYW5jZWxsZWRGaWxlVXJpcyA9IGdldE9uRGV2aWNlVXJpc0ZvckZpbGVHcm91cChwZW5kaW5nR3JvdXBUb0tlZXApOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRlciwgdGltZXMoMCkpLnN0b3BEb3dubG9hZGluZyh1bmNhbmNlbGxlZEZpbGVVcmlzLmdldCgwKSk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyLCB0aW1lcygwKSkuc3RvcERvd25sb2FkaW5nKHVuY2FuY2VsbGVkRmlsZVVyaXMuZ2V0KDEpKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRlciwgdGltZXMoMSkpCisgICAgICAgIC5zdG9wRG93bmxvYWRpbmcoZ2V0T25EZXZpY2VVcmlzRm9yRmlsZUdyb3VwKHBlbmRpbmdHcm91cFRvUmVtb3ZlMSkuZ2V0KDApKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkZXIsIHRpbWVzKDEpKQorICAgICAgICAuc3RvcERvd25sb2FkaW5nKGdldE9uRGV2aWNlVXJpc0ZvckZpbGVHcm91cChwZW5kaW5nR3JvdXBUb1JlbW92ZTIpLmdldCgwKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRmlsZUdyb3Vwc193aGVuUmVtb3ZlUGVuZGluZ0dyb3VwRmFpbHNfZG9lc05vdENvbnRpbnVlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVXNlIE1vY2tzIHRvIHNpbXVsYXRlIGZhaWx1cmUgc2NlbmFyaW8KKyAgICByZXNldEZpbGVHcm91cE1hbmFnZXIobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgbW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisKKyAgICBHcm91cEtleS5CdWlsZGVyIGdyb3VwS2V5QnVpbGRlciA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKS5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBHcm91cEtleSBwZW5kaW5nR3JvdXBLZXkgPQorICAgICAgICBncm91cEtleUJ1aWxkZXIuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZG93bmxvYWRlZEdyb3VwS2V5ID0KKyAgICAgICAgZ3JvdXBLZXlCdWlsZGVyLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzIpLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKHBlbmRpbmdHcm91cEtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHBlbmRpbmdHcm91cCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGdldFBlbmRpbmdLZXkoZG93bmxvYWRlZEdyb3VwS2V5KSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoZ3JvdXBLZXlzQ2FwdG9yLmNhcHR1cmUoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKSk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUZpbGVHcm91cHMoSW1tdXRhYmxlTGlzdC5vZihwZW5kaW5nR3JvdXBLZXksIGRvd25sb2FkZWRHcm91cEtleSkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoKSk7CisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKElPRXhjZXB0aW9uLmNsYXNzKTsKKworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygwKSkuYWRkU3RhbGVHcm91cChhbnkoKSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlciwgdGltZXMoMCkpLmNhbmNlbERvd25sb2FkKGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMSkpLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKGFueSgpKTsKKyAgICBMaXN0PEdyb3VwS2V5PiBhdHRlbXB0ZWRSZW1vdmVLZXlzID0gZ3JvdXBLZXlzQ2FwdG9yLmdldFZhbHVlKCk7CisgICAgYXNzZXJ0VGhhdChhdHRlbXB0ZWRSZW1vdmVLZXlzKS5jb250YWluc0V4YWN0bHkocGVuZGluZ0dyb3VwS2V5KTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVGaWxlR3JvdXBzX3doZW5SZW1vdmVEb3dubG9hZGVkR3JvdXBGYWlsc19kb2VzTm90Q29udGludWUoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVXNlIE1vY2sgRmlsZUdyb3Vwc01ldGFkYXRhIHRvIHNpbXVsYXRlIGZhaWx1cmUgc2NlbmFyaW8KKyAgICByZXNldEZpbGVHcm91cE1hbmFnZXIobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgbW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzIsIDEpOworCisgICAgR3JvdXBLZXkuQnVpbGRlciBncm91cEtleUJ1aWxkZXIgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSk7CisgICAgR3JvdXBLZXkgcGVuZGluZ0dyb3VwS2V5ID0KKyAgICAgICAgZ3JvdXBLZXlCdWlsZGVyLnNldEdyb3VwTmFtZShURVNUX0dST1VQKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworICAgIEdyb3VwS2V5IGRvd25sb2FkZWRHcm91cEtleSA9CisgICAgICAgIGdyb3VwS2V5QnVpbGRlci5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8yKS5zZXREb3dubG9hZGVkKHRydWUpLmJ1aWxkKCk7CisKKyAgICAvLyBNb2NrIHZhcmlhdGlvbnMgb2YgZ3JvdXAga2V5IHJlYWRzCisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQocGVuZGluZ0dyb3VwS2V5KSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUocGVuZGluZ0dyb3VwKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZ2V0UGVuZGluZ0tleShkb3dubG9hZGVkR3JvdXBLZXkpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGRvd25sb2FkZWRHcm91cEtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGRvd25sb2FkZWRHcm91cCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGdldERvd25sb2FkZWRLZXkocGVuZGluZ0dyb3VwS2V5KSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKworICAgIC8vIFJldHVybiB0cnVlIGZvciBwZW5kaW5nIGdyb3VwcyByZW1vdmVkLCBidXQgZmFsc2UgZm9yIGRvd25sb2FkZWQgZ3JvdXBzCisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKGdyb3VwS2V5c0NhcHRvci5jYXB0dXJlKCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmFsc2UpKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAucmVtb3ZlRmlsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKHBlbmRpbmdHcm91cEtleSwgZG93bmxvYWRlZEdyb3VwS2V5KSkKKyAgICAgICAgICAgICAgICAgICAgLmdldCgpKTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoSU9FeGNlcHRpb24uY2xhc3MpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHRpbWVzKDApKS5hZGRTdGFsZUdyb3VwKGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyLCB0aW1lcygwKSkuY2FuY2VsRG93bmxvYWQoYW55KCkpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoYW55KCkpOworICAgIExpc3Q8TGlzdDxHcm91cEtleT4+IHJlbW92ZUNhbGxJbnZvY2F0aW9ucyA9IGdyb3VwS2V5c0NhcHRvci5nZXRBbGxWYWx1ZXMoKTsKKyAgICBhc3NlcnRUaGF0KHJlbW92ZUNhbGxJbnZvY2F0aW9ucy5nZXQoMCkpLmNvbnRhaW5zRXhhY3RseShwZW5kaW5nR3JvdXBLZXkpOworICAgIGFzc2VydFRoYXQocmVtb3ZlQ2FsbEludm9jYXRpb25zLmdldCgxKSkuY29udGFpbnNFeGFjdGx5KGRvd25sb2FkZWRHcm91cEtleSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRmlsZUdyb3Vwc193aGVuQWRkaW5nU3RhbGVHcm91cEZhaWxzX2RvZXNOb3RDb250aW51ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFVzZSBNb2NrIEZpbGVHcm91cHNNZXRhZGF0YSB0byBzaW11bGF0ZSBmYWlsdXJlIHNjZW5hcmlvCisgICAgcmVzZXRGaWxlR3JvdXBNYW5hZ2VyKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcGVuZGluZ0dyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAxKTsKKworICAgIEdyb3VwS2V5LkJ1aWxkZXIgZ3JvdXBLZXlCdWlsZGVyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleSA9CisgICAgICAgIGdyb3VwS2V5QnVpbGRlci5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKyAgICBHcm91cEtleSBkb3dubG9hZGVkR3JvdXBLZXkgPQorICAgICAgICBncm91cEtleUJ1aWxkZXIuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikuc2V0RG93bmxvYWRlZCh0cnVlKS5idWlsZCgpOworCisgICAgLy8gTW9jayByZWFkIGdyb3VwIGtleSB2YXJpYXRpb25zCisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQocGVuZGluZ0dyb3VwS2V5KSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUocGVuZGluZ0dyb3VwKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZ2V0UGVuZGluZ0tleShkb3dubG9hZGVkR3JvdXBLZXkpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGRvd25sb2FkZWRHcm91cEtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGRvd25sb2FkZWRHcm91cCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGdldERvd25sb2FkZWRLZXkocGVuZGluZ0dyb3VwS2V5KSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKworICAgIC8vIEFsd2F5cyByZXR1cm4gdHJ1ZSBmb3IgcmVtb3ZlIGNhbGxzCisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKGdyb3VwS2V5c0NhcHRvci5jYXB0dXJlKCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisKKyAgICAvLyBGYWlsIHdoZW4gYXR0ZW1wdGluZyB0byBhZGQgYSBzdGFsZSBncm91cAorICAgIHdoZW4obW9ja0ZpbGVHcm91cHNNZXRhZGF0YS5hZGRTdGFsZUdyb3VwKGRvd25sb2FkZWRHcm91cCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKSk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUZpbGVHcm91cHMoSW1tdXRhYmxlTGlzdC5vZihwZW5kaW5nR3JvdXBLZXksIGRvd25sb2FkZWRHcm91cEtleSkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoKSk7CisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKEFnZ3JlZ2F0ZUV4Y2VwdGlvbi5jbGFzcyk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cHNNZXRhZGF0YSwgdGltZXMoMSkpLmFkZFN0YWxlR3JvdXAoZG93bmxvYWRlZEdyb3VwKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyLCB0aW1lcygwKSkuY2FuY2VsRG93bmxvYWQoYW55KCkpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCB0aW1lcygyKSkucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoYW55KCkpOworICAgIExpc3Q8TGlzdDxHcm91cEtleT4+IHJlbW92ZUNhbGxJbnZvY2F0aW9ucyA9IGdyb3VwS2V5c0NhcHRvci5nZXRBbGxWYWx1ZXMoKTsKKyAgICBhc3NlcnRUaGF0KHJlbW92ZUNhbGxJbnZvY2F0aW9ucy5nZXQoMCkpLmNvbnRhaW5zRXhhY3RseShwZW5kaW5nR3JvdXBLZXkpOworICAgIGFzc2VydFRoYXQocmVtb3ZlQ2FsbEludm9jYXRpb25zLmdldCgxKSkuY29udGFpbnNFeGFjdGx5KGRvd25sb2FkZWRHcm91cEtleSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRmlsZUdyb3Vwc193aGVuQ2FuY2VsbGluZ1BlbmRpbmdEb3dubG9hZEZhaWxzX2RvZXNOb3RDb250aW51ZSgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBVc2UgTW9jayBGaWxlR3JvdXBzTWV0YWRhdGEgdG8gc2ltdWxhdGUgZmFpbHVyZSBzY2VuYXJpbworICAgIHJlc2V0RmlsZUdyb3VwTWFuYWdlcihmaWxlR3JvdXBzTWV0YWRhdGEsIG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcGVuZGluZ0dyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAxKTsKKworICAgIEdyb3VwS2V5LkJ1aWxkZXIgZ3JvdXBLZXlCdWlsZGVyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpOworICAgIEdyb3VwS2V5IHBlbmRpbmdHcm91cEtleSA9CisgICAgICAgIGdyb3VwS2V5QnVpbGRlci5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKyAgICBHcm91cEtleSBkb3dubG9hZGVkR3JvdXBLZXkgPQorICAgICAgICBncm91cEtleUJ1aWxkZXIuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikuc2V0RG93bmxvYWRlZCh0cnVlKS5idWlsZCgpOworCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHBlbmRpbmdHcm91cEtleSwgcGVuZGluZ0dyb3VwKTsKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAoZG93bmxvYWRlZEdyb3VwS2V5LCBkb3dubG9hZGVkR3JvdXApOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIHBlbmRpbmdHcm91cCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgZG93bmxvYWRlZEdyb3VwLCBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIC8vIEZhaWwgd2hlbiBjYW5jZWxsaW5nIGRvd25sb2FkCisgICAgTmV3RmlsZUtleVtdIHBlbmRpbmdGaWxlS2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKHBlbmRpbmdHcm91cCk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuY2FuY2VsRG93bmxvYWQocGVuZGluZ0ZpbGVLZXlzWzBdKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUobmV3IEV4Y2VwdGlvbigiVGVzdCBmYWlsdXJlIikpKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAucmVtb3ZlRmlsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKHBlbmRpbmdHcm91cEtleSwgZG93bmxvYWRlZEdyb3VwS2V5KSkKKyAgICAgICAgICAgICAgICAgICAgLmdldCgpKTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoQWdncmVnYXRlRXhjZXB0aW9uLmNsYXNzKTsKKworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAocGVuZGluZ0dyb3VwS2V5KSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cChkb3dubG9hZGVkR3JvdXBLZXkpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpLmdldCgpKS5pc0VtcHR5KCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKS5nZXQoKSkKKyAgICAgICAgLmNvbnRhaW5zRXhhY3RseSgKKyAgICAgICAgICAgIGRvd25sb2FkZWRHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRCb29ra2VlcGluZygKKyAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRlZEdyb3VwLmdldEJvb2trZWVwaW5nKCkudG9CdWlsZGVyKCkuc2V0U3RhbGVFeHBpcmF0aW9uRGF0ZSgxKS5idWlsZCgpKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVGaWxlR3JvdXBzX3doZW5NdWx0aXBsZVZhcmlhbnRzRXhpc3RzX3JlbW92ZXNWYXJpYW50c1NwZWNpZmllZCgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgbXVsdGlwbGUgdmFyaWFudHMgb2YgYSBncm91cCAoZGVmYXVsdCAoZW1wdHkpLCBlbiwgZnIpIGFuZCByZW1vdmUgdGhlIGRlZmF1bHQgKGVtcHR5KQorICAgIC8vIHZhcmlhbnQgYW5kIGVuIGtleXMuIEVuc3VyZSB0aGF0IG9ubHkgdGhlIGZyIGdyb3VwIHJlbWFpbnMuCisgICAgR3JvdXBLZXkgZGVmYXVsdEdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEdyb3VwS2V5IGVuR3JvdXBLZXkgPSBkZWZhdWx0R3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0VmFyaWFudElkKCJlbiIpLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZnJHcm91cEtleSA9IGRlZmF1bHRHcm91cEtleS50b0J1aWxkZXIoKS5zZXRWYXJpYW50SWQoImZyIikuYnVpbGQoKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkZWZhdWx0RmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBlbkZpbGVHcm91cCA9IGRlZmF1bHRGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0VmFyaWFudElkKCJlbiIpLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZyRmlsZUdyb3VwID0gZGVmYXVsdEZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRWYXJpYW50SWQoImZyIikuYnVpbGQoKTsKKworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChnZXRQZW5kaW5nS2V5KGRlZmF1bHRHcm91cEtleSksIGRlZmF1bHRGaWxlR3JvdXApOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChnZXRQZW5kaW5nS2V5KGVuR3JvdXBLZXkpLCBlbkZpbGVHcm91cCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKGdldFBlbmRpbmdLZXkoZnJHcm91cEtleSksIGZyRmlsZUdyb3VwKTsKKworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIGRlZmF1bHRGaWxlR3JvdXAsIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIGVuRmlsZUdyb3VwLCBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLCBmckZpbGVHcm91cCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisKKyAgICAvLyBBc3NlcnQgdGhhdCBhbGwgZmlsZSBncm91cHMgc2hhcmUgdGhlIHNhbWUgZmlsZSBldmVuIHRocm91Z2ggdGhlIHZhcmlhbnRzIGFyZSBkaWZmZXJlbnQKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKS5nZXQoKSkuaGFzU2l6ZSgxKTsKKworICAgIHsKKyAgICAgIC8vIFBlcmZyb20gcmVtb3ZhbCBvbmNlIGFuZCBjaGVjayB0aGF0IHRoZSBjb3JyZWN0IGdyb3VwcyBnZXQgcmVtb3ZlZAorICAgICAgZmlsZUdyb3VwTWFuYWdlci5yZW1vdmVGaWxlR3JvdXBzKEltbXV0YWJsZUxpc3Qub2YoZGVmYXVsdEdyb3VwS2V5LCBlbkdyb3VwS2V5KSkuZ2V0KCk7CisKKyAgICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEdyb3VwS2V5cygpLmdldCgpKQorICAgICAgICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKEdST1VQX0tFWV9UT19WQVJJQU5UKQorICAgICAgICAgIC5jb250YWluc0V4YWN0bHkoImZyIik7CisgICAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpLmdldCgpKQorICAgICAgICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKEtFWV9HUk9VUF9QQUlSX1RPX1ZBUklBTlRfUEFJUikKKyAgICAgICAgICAuY29udGFpbnNFeGFjdGx5KFBhaXIuY3JlYXRlKCJmciIsICJmciIpKTsKKworICAgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLmdldEFsbEZpbGVLZXlzKCkuZ2V0KCkpLmhhc1NpemUoMSk7CisgICAgfQorCisgICAgeworICAgICAgLy8gUGVyZm9ybSByZW1vdmUgYWdhaW4gYW5kIHZlcmlmeSB0aGF0IHRoZXJlIGlzIG5vIGNoYW5nZSBpbiBzdGF0ZQorICAgICAgZmlsZUdyb3VwTWFuYWdlci5yZW1vdmVGaWxlR3JvdXBzKEltbXV0YWJsZUxpc3Qub2YoZGVmYXVsdEdyb3VwS2V5LCBlbkdyb3VwS2V5KSkuZ2V0KCk7CisKKyAgICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEdyb3VwS2V5cygpLmdldCgpKQorICAgICAgICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKEdST1VQX0tFWV9UT19WQVJJQU5UKQorICAgICAgICAgIC5jb250YWluc0V4YWN0bHkoImZyIik7CisgICAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxGcmVzaEdyb3VwcygpLmdldCgpKQorICAgICAgICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKEtFWV9HUk9VUF9QQUlSX1RPX1ZBUklBTlRfUEFJUikKKyAgICAgICAgICAuY29udGFpbnNFeGFjdGx5KFBhaXIuY3JlYXRlKCJmciIsICJmciIpKTsKKworICAgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLmdldEFsbEZpbGVLZXlzKCkuZ2V0KCkpLmhhc1NpemUoMSk7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEdldERvd25sb2FkZWRHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5nZXRGaWxlR3JvdXAodGVzdEtleSwgdHJ1ZSkuZ2V0KCkpLmlzTnVsbCgpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEb3dubG9hZGVkRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5LCBkYXRhRmlsZUdyb3VwKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkR3JvdXAgPSBmaWxlR3JvdXBNYW5hZ2VyLmdldEZpbGVHcm91cCh0ZXN0S2V5LCB0cnVlKS5nZXQoKTsKKyAgICBNZGRUZXN0VXRpbC5hc3NlcnRNZXNzYWdlRXF1YWxzKGRhdGFGaWxlR3JvdXAsIGRvd25sb2FkZWRHcm91cCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0R2V0RG93bmxvYWRlZEdyb3VwX3doZW5NdWx0aXBsZVZhcmlhbnRzRXhpc3RzX2dldHNDb3JyZWN0R3JvdXAoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgR3JvdXBLZXkgZGVmYXVsdEdyb3VwS2V5ID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEdyb3VwS2V5IGVuR3JvdXBLZXkgPSBkZWZhdWx0R3JvdXBLZXkudG9CdWlsZGVyKCkuc2V0VmFyaWFudElkKCJlbiIpLmJ1aWxkKCk7CisKKyAgICAvLyBJbml0aWFsbHksIGFzc2VydCB0aGF0IGdyb3VwcyBkb24ndCBleGlzdAorICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5nZXRGaWxlR3JvdXAoZGVmYXVsdEdyb3VwS2V5LCB0cnVlKS5nZXQoKSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmdldEZpbGVHcm91cChlbkdyb3VwS2V5LCB0cnVlKS5nZXQoKSkuaXNOdWxsKCk7CisKKyAgICAvLyBDcmVhdGUgZ3JvdXBzIGFuZCB3cml0ZSB0aGVtCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRlZmF1bHRGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGVuRmlsZUdyb3VwID0gZGVmYXVsdEZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRWYXJpYW50SWQoImVuIikuYnVpbGQoKTsKKworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChnZXREb3dubG9hZGVkS2V5KGRlZmF1bHRHcm91cEtleSksIGRlZmF1bHRGaWxlR3JvdXApOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChnZXREb3dubG9hZGVkS2V5KGVuR3JvdXBLZXkpLCBlbkZpbGVHcm91cCk7CisKKyAgICAvLyBBc3NlcnQgdGhlIGNvcnJlY3QgZ3JvdXAgaXMgcmV0dXJuZWQgZm9yIGVhY2gga2V5CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGdyb3VwRm9yRGVmYXVsdEtleSA9CisgICAgICAgIGZpbGVHcm91cE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGRlZmF1bHRHcm91cEtleSwgdHJ1ZSkuZ2V0KCk7CisgICAgTWRkVGVzdFV0aWwuYXNzZXJ0TWVzc2FnZUVxdWFscyhkZWZhdWx0RmlsZUdyb3VwLCBncm91cEZvckRlZmF1bHRLZXkpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGdyb3VwRm9yRW5LZXkgPSBmaWxlR3JvdXBNYW5hZ2VyLmdldEZpbGVHcm91cChlbkdyb3VwS2V5LCB0cnVlKS5nZXQoKTsKKyAgICBNZGRUZXN0VXRpbC5hc3NlcnRNZXNzYWdlRXF1YWxzKGVuRmlsZUdyb3VwLCBncm91cEZvckVuS2V5KTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RHZXRQZW5kaW5nR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuZ2V0RmlsZUdyb3VwKHRlc3RLZXksIGZhbHNlKS5nZXQoKSkuaXNOdWxsKCk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZGF0YUZpbGVHcm91cCk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcGVuZGluZ0dyb3VwID0gZmlsZUdyb3VwTWFuYWdlci5nZXRGaWxlR3JvdXAodGVzdEtleSwgZmFsc2UpLmdldCgpOworICAgIE1kZFRlc3RVdGlsLmFzc2VydE1lc3NhZ2VFcXVhbHMoZGF0YUZpbGVHcm91cCwgcGVuZGluZ0dyb3VwKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RHZXRQZW5kaW5nR3JvdXBfd2hlbk11bHRpcGxlVmFyaWFudHNFeGlzdHNfZ2V0c0NvcnJlY3RHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEdyb3VwS2V5IGRlZmF1bHRHcm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBHcm91cEtleSBlbkdyb3VwS2V5ID0gZGVmYXVsdEdyb3VwS2V5LnRvQnVpbGRlcigpLnNldFZhcmlhbnRJZCgiZW4iKS5idWlsZCgpOworCisgICAgLy8gSW5pdGlhbGx5LCBhc3NlcnQgdGhhdCBncm91cHMgZG9uJ3QgZXhpc3QKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGRlZmF1bHRHcm91cEtleSwgZmFsc2UpLmdldCgpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGVuR3JvdXBLZXksIGZhbHNlKS5nZXQoKSkuaXNOdWxsKCk7CisKKyAgICAvLyBDcmVhdGUgZ3JvdXBzIGFuZCB3cml0ZSB0aGVtCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRlZmF1bHRGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGVuRmlsZUdyb3VwID0gZGVmYXVsdEZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRWYXJpYW50SWQoImVuIikuYnVpbGQoKTsKKworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChnZXRQZW5kaW5nS2V5KGRlZmF1bHRHcm91cEtleSksIGRlZmF1bHRGaWxlR3JvdXApOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChnZXRQZW5kaW5nS2V5KGVuR3JvdXBLZXkpLCBlbkZpbGVHcm91cCk7CisKKyAgICAvLyBBc3NlcnQgdGhlIGNvcnJlY3QgZ3JvdXAgaXMgcmV0dXJuZWQgZm9yIGVhY2gga2V5CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGdyb3VwRm9yRGVmYXVsdEtleSA9CisgICAgICAgIGZpbGVHcm91cE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGRlZmF1bHRHcm91cEtleSwgZmFsc2UpLmdldCgpOworICAgIE1kZFRlc3RVdGlsLmFzc2VydE1lc3NhZ2VFcXVhbHMoZGVmYXVsdEZpbGVHcm91cCwgZ3JvdXBGb3JEZWZhdWx0S2V5KTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBncm91cEZvckVuS2V5ID0gZmlsZUdyb3VwTWFuYWdlci5nZXRGaWxlR3JvdXAoZW5Hcm91cEtleSwgZmFsc2UpLmdldCgpOworICAgIE1kZFRlc3RVdGlsLmFzc2VydE1lc3NhZ2VFcXVhbHMoZW5GaWxlR3JvdXAsIGdyb3VwRm9yRW5LZXkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFNldEdyb3VwQWN0aXZhdGlvbl9kZWFjdGl2YXRpb25SZW1vdmVzR3JvdXBzUmVxdWlyaW5nQWN0aXZhdGlvbigpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmbGFncy5lbmFibGVEZWxheWVkRG93bmxvYWQgPSBPcHRpb25hbC5vZih0cnVlKTsKKyAgICAvLyBDcmVhdGUgMiBncm91cHMsIG9uZSBvZiB3aGljaCByZXF1aXJlcyBkZXZpY2Ugc2lkZSBhY3RpdmF0aW9uLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGZpbGVHcm91cDEgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCk7CisgICAgRG93bmxvYWRDb25kaXRpb25zLkJ1aWxkZXIgZG93bmxvYWRDb25kaXRpb25zID0KKyAgICAgICAgRG93bmxvYWRDb25kaXRpb25zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEFjdGl2YXRpbmdDb25kaXRpb24oQWN0aXZhdGluZ0NvbmRpdGlvbi5ERVZJQ0VfQUNUSVZBVEVEKTsKKyAgICBmaWxlR3JvdXAxLnNldERvd25sb2FkQ29uZGl0aW9ucyhkb3dubG9hZENvbmRpdGlvbnMpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDIgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAzKTsKKworICAgIC8vIEFjdGl2YXRlIGJvdGggZ3JvdXAga2V5cyBhbmQgYWRkIGdyb3VwcyB0byBGaWxlR3JvdXBNYW5hZ2VyLgorICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5zZXRHcm91cEFjdGl2YXRpb24odGVzdEtleSwgdHJ1ZSkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZmlsZUdyb3VwMS5idWlsZCgpKS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuc2V0R3JvdXBBY3RpdmF0aW9uKHRlc3RLZXkyLCB0cnVlKS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZCh0ZXN0S2V5MiwgZmlsZUdyb3VwMikuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgLy8gQWRkIGEgZG93bmxvYWRlZCB2ZXJzaW9uIG9mIHRoZSBzZWNvbmQgZ3JvdXAsIHRoYXQgcmVxdWlyZXMgZGV2aWNlIHNpZGUgYWN0aXZhdGlvbi4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZGZpbGVHcm91cDIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEb3dubG9hZGVkRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMSk7CisgICAgZG93bmxvYWRDb25kaXRpb25zID0gRG93bmxvYWRDb25kaXRpb25zLm5ld0J1aWxkZXIoKTsKKyAgICBkb3dubG9hZGVkZmlsZUdyb3VwMiA9CisgICAgICAgIGRvd25sb2FkZWRmaWxlR3JvdXAyLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKAorICAgICAgICAgICAgICAgIGRvd25sb2FkQ29uZGl0aW9ucy5zZXRBY3RpdmF0aW5nQ29uZGl0aW9uKEFjdGl2YXRpbmdDb25kaXRpb24uREVWSUNFX0FDVElWQVRFRCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleTIsIGRvd25sb2FkZWRmaWxlR3JvdXAyKTsKKworICAgIC8vIERlYWN0aXZhdGUgYm90aCBncm91cCBrZXlzLCBhbmQgY2hlY2sgdGhhdCB0aGUgZ3JvdXBzIHRoYXQgcmVxdWlyZWQgYWN0aXZhdGlvbiBhcmUgZGVsZXRlZC4KKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuc2V0R3JvdXBBY3RpdmF0aW9uKHRlc3RLZXksIGZhbHNlKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgLy8gU2V0dGluZyBncm91cCBhY3RpdmF0aW9uIHRvIGZhbHNlIHdpbGwgb25seSByZW1vdmUgZ3JvdXBzIHRoYXQgaGF2ZQorICAgIC8vIEFjdGl2YXRpbmdDb25kaXRpb24uREVWSUNFX0FDVElWQVRFRC4gU28gdGhlIHBlbmRpbmcgdmVyc2lvbiB3aWxsIHJlbWFpbiwgd2hpbGUgdGhlCisgICAgLy8gZG93bmxvYWRlZCBvbmUgaXMgcmVtb3ZlZC4KKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuc2V0R3JvdXBBY3RpdmF0aW9uKHRlc3RLZXkyLCBmYWxzZSkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5MikpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleTIpKS5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnRGaWxlc0ludG9GaWxlR3JvdXBfd2hlbkV4aXN0aW5nR3JvdXBEb2VzTm90RXhpc3RfZmFpbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZSBpbmxpbmVGaWxlID0KKyAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZUlkKCJpbmxpbmUtZmlsZSIpCisgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oImFiYyIpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTpzaGExOmFiYyIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBJbW11dGFibGVMaXN0PERhdGFGaWxlPiB1cGRhdGVkRGF0YUZpbGVMaXN0ID0gSW1tdXRhYmxlTGlzdC5vZihpbmxpbmVGaWxlKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZSgibm9uLWV4aXN0aW5nLWdyb3VwIikuYnVpbGQoKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAuaW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBidWlsZElkID0gKi8gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIHZhcmlhbnRJZCA9ICovICIiLAorICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZERhdGFGaWxlTGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGlubGluZUZpbGVNYXAgPSAqLyBJbW11dGFibGVNYXAub2YoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGN1c3RvbVByb3BlcnR5T3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAgICAgICAgICAgICAuZ2V0KCkpOworCisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkZXggPSAoRG93bmxvYWRFeGNlcHRpb24pIGV4LmdldENhdXNlKCk7CisgICAgYXNzZXJ0VGhhdChkZXguZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuR1JPVVBfTk9UX0ZPVU5EX0VSUk9SKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnRGaWxlc0ludG9GaWxlR3JvdXBfd2hlbkV4aXN0aW5nUGVuZGluZ0dyb3VwRG9lc05vdE1hdGNoSWRlbnRpZmllcnNfZmFpbHMoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gU2V0IHVwIGV4aXN0aW5nIHBlbmRpbmcgZmlsZSBncm91cAorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBleGlzdGluZ0ZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoImlubGluZS1maWxlIikKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKCJhYmMiKQorICAgICAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTpzaGExOmFiYyIpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPSBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApLmJ1aWxkKCk7CisKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAoZ2V0UGVuZGluZ0tleShncm91cEtleSksIGV4aXN0aW5nRmlsZUdyb3VwKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLCBleGlzdGluZ0ZpbGVHcm91cCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgLyogYnVpbGRJZCA9ICovIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAvKiB2YXJpYW50SWQgPSAqLyAiIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZWREYXRhRmlsZUxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmxpbmVGaWxlTWFwID0gKi8gSW1tdXRhYmxlTWFwLm9mKCksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgICAgICAgICBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgICAgICAgICAgICAgLmdldCgpKTsKKworICAgIGFzc2VydFRoYXQoZXgpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gZGV4ID0gKERvd25sb2FkRXhjZXB0aW9uKSBleC5nZXRDYXVzZSgpOworICAgIGFzc2VydFRoYXQoZGV4LmdldERvd25sb2FkUmVzdWx0Q29kZSgpKS5pc0VxdWFsVG8oRG93bmxvYWRSZXN1bHRDb2RlLkdST1VQX05PVF9GT1VORF9FUlJPUik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZAorICAgICAgdGVzdEltcG9ydEZpbGVzSW50b0ZpbGVHcm91cF93aGVuRXhpc3RpbmdEb3dubG9hZGVkR3JvdXBEb2VzTm90TWF0Y2hJZGVudGlmaWVyc19mYWlscygpCisgICAgICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gU2V0IHVwIGV4aXN0aW5nIGRvd25sb2FkZWQgZmlsZSBncm91cAorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBleGlzdGluZ0ZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoImlubGluZS1maWxlIikKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKCJhYmMiKQorICAgICAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTpzaGExOmFiYyIpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPSBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApLmJ1aWxkKCk7CisKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAoZ2V0RG93bmxvYWRlZEtleShncm91cEtleSksIGV4aXN0aW5nRmlsZUdyb3VwKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLCBleGlzdGluZ0ZpbGVHcm91cCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgLyogYnVpbGRJZCA9ICovIDAsCisgICAgICAgICAgICAgICAgICAgICAgICAvKiB2YXJpYW50SWQgPSAqLyAidGVzdHZhcmlhbnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgLyogdXBkYXRlZERhdGFGaWxlTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGlubGluZUZpbGVNYXAgPSAqLyBJbW11dGFibGVNYXAub2YoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGN1c3RvbVByb3BlcnR5T3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAgICAgICAgICAgICAuZ2V0KCkpOworCisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkZXggPSAoRG93bmxvYWRFeGNlcHRpb24pIGV4LmdldENhdXNlKCk7CisgICAgYXNzZXJ0VGhhdChkZXguZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuR1JPVVBfTk9UX0ZPVU5EX0VSUk9SKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnRGaWxlc0ludG9GaWxlR3JvdXBfd2hlbkJ1aWxkSWREb2VzTm90TWF0Y2hfZmFpbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBTZXQgdXAgZXhpc3RpbmcgcGVuZGluZy9kb3dubG9hZGVkIGdyb3VwcyBhbmQgY2hlY2sgdGhhdCB0aGV5IGRvIG5vdCBtYXRjaCBkdWUgdG8gYnVpbGQgSUQKKyAgICAvLyBkaWZmZXJlbmNlcy4KKworICAgIC8vIEFueSBjYW4gcGFjayBwcm90byBtZXNzYWdlcyBvbmx5LCBzbyB1c2UgU3RyaW5nVmFsdWUuCisgICAgQW55IGN1c3RvbVByb3BlcnR5ID0KKyAgICAgICAgQW55LnBhcnNlRnJvbSgKKyAgICAgICAgICAgIFN0cmluZ1ZhbHVlLm9mKCJ0ZXN0Q3VzdG9tUHJvcGVydHkiKS50b0J5dGVTdHJpbmcoKSwKKyAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5nZXRFbXB0eVJlZ2lzdHJ5KCkpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBleGlzdGluZ0Rvd25sb2FkZWRGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRCdWlsZElkKDEpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKCJ0ZXN0dmFyaWFudCIpCisgICAgICAgICAgICAuc2V0Q3VzdG9tUHJvcGVydHkoY3VzdG9tUHJvcGVydHkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZXhpc3RpbmdQZW5kaW5nRmlsZUdyb3VwID0KKyAgICAgICAgZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldEJ1aWxkSWQoMikuYnVpbGQoKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShURVNUX0dST1VQKS5idWlsZCgpOworCisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGdldERvd25sb2FkZWRLZXkoZ3JvdXBLZXkpLCBleGlzdGluZ0Rvd25sb2FkZWRGaWxlR3JvdXApOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChnZXRQZW5kaW5nS2V5KGdyb3VwS2V5KSwgZXhpc3RpbmdQZW5kaW5nRmlsZUdyb3VwKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAuaW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBidWlsZElkID0gKi8gMywKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIHZhcmlhbnRJZCA9ICovICJ0ZXN0dmFyaWFudCIsCisgICAgICAgICAgICAgICAgICAgICAgICAvKiB1cGRhdGVkRGF0YUZpbGVMaXN0ID0gKi8gSW1tdXRhYmxlTGlzdC5vZigpLAorICAgICAgICAgICAgICAgICAgICAgICAgLyogaW5saW5lRmlsZU1hcCA9ICovIEltbXV0YWJsZU1hcC5vZigpLAorICAgICAgICAgICAgICAgICAgICAgICAgLyogY3VzdG9tUHJvcGVydHlPcHRpb25hbCA9ICovIE9wdGlvbmFsLm9mKGN1c3RvbVByb3BlcnR5KSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAgICAgICAgICAgICAuZ2V0KCkpOworCisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkZXggPSAoRG93bmxvYWRFeGNlcHRpb24pIGV4LmdldENhdXNlKCk7CisgICAgYXNzZXJ0VGhhdChkZXguZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuR1JPVVBfTk9UX0ZPVU5EX0VSUk9SKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnRGaWxlc0ludG9GaWxlR3JvdXBfd2hlblZhcmlhbnRJZERvZXNOb3RNYXRjaF9mYWlscygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFNldCB1cCBleGlzdGluZyBwZW5kaW5nL2Rvd25sb2FkZWQgZ3JvdXBzIGFuZCBjaGVjayB0aGF0IHRoZXkgZG8gbm90IG1hdGNoIGR1ZSB0byB2YXJpYW50IElECisgICAgLy8gZGlmZmVyZW5jZXMuCisKKyAgICAvLyBBbnkgY2FuIHBhY2sgcHJvdG8gbWVzc2FnZXMgb25seSwgc28gdXNlIFN0cmluZ1ZhbHVlLgorICAgIEFueSBjdXN0b21Qcm9wZXJ0eSA9CisgICAgICAgIEFueS5wYXJzZUZyb20oCisgICAgICAgICAgICBTdHJpbmdWYWx1ZS5vZigidGVzdEN1c3RvbVByb3BlcnR5IikudG9CeXRlU3RyaW5nKCksCisgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUuZ2V0RW1wdHlSZWdpc3RyeSgpKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0QnVpbGRJZCgxKQorICAgICAgICAgICAgLnNldFZhcmlhbnRJZCgidGVzdHZhcmlhbnQiKQorICAgICAgICAgICAgLnNldEN1c3RvbVByb3BlcnR5KGN1c3RvbVByb3BlcnR5KQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGV4aXN0aW5nUGVuZGluZ0ZpbGVHcm91cCA9CisgICAgICAgIGV4aXN0aW5nRG93bmxvYWRlZEZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRWYXJpYW50SWQoInRlc3R2YXJpYW50MiIpLmJ1aWxkKCk7CisKKyAgICBHcm91cEtleSBncm91cEtleSA9IEdyb3VwS2V5Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkuYnVpbGQoKTsKKworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChnZXREb3dubG9hZGVkS2V5KGdyb3VwS2V5KSwgZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAoZ2V0UGVuZGluZ0tleShncm91cEtleSksIGV4aXN0aW5nUGVuZGluZ0ZpbGVHcm91cCk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgICAgICAgICAgICAgLyogYnVpbGRJZCA9ICovIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAvKiB2YXJpYW50SWQgPSAqLyAidGVzdHZhcmlhbnQzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZWREYXRhRmlsZUxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmxpbmVGaWxlTWFwID0gKi8gSW1tdXRhYmxlTWFwLm9mKCksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsID0gKi8gT3B0aW9uYWwub2YoY3VzdG9tUHJvcGVydHkpLAorICAgICAgICAgICAgICAgICAgICAgICAgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoKSk7CisKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIERvd25sb2FkRXhjZXB0aW9uIGRleCA9IChEb3dubG9hZEV4Y2VwdGlvbikgZXguZ2V0Q2F1c2UoKTsKKyAgICBhc3NlcnRUaGF0KGRleC5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkuaXNFcXVhbFRvKERvd25sb2FkUmVzdWx0Q29kZS5HUk9VUF9OT1RfRk9VTkRfRVJST1IpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEltcG9ydEZpbGVzSW50b0ZpbGVHcm91cF93aGVuQ3VzdG9tUHJvcGVydHlEb2VzTm90TWF0Y2hfd2hlbkR1ZVRvTWlzbWF0Y2hfZmFpbHMoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gU2V0IHVwIGV4aXN0aW5nIHBlbmRpbmcvZG93bmxvYWRlZCBncm91cHMgYW5kIGNoZWNrIHRoYXQgdGhleSBkbyBub3QgbWF0Y2ggZHVlIHRvIGN1c3RvbQorICAgIC8vIHByb3BlcnR5IGRpZmZlcmVuY2VzLgorCisgICAgLy8gQW55IGNhbiBwYWNrIHByb3RvIG1lc3NhZ2VzIG9ubHksIHNvIHVzZSBTdHJpbmdWYWx1ZS4KKyAgICBBbnkgZG93bmxvYWRlZEN1c3RvbVByb3BlcnR5ID0KKyAgICAgICAgQW55LnBhcnNlRnJvbSgKKyAgICAgICAgICAgIFN0cmluZ1ZhbHVlLm9mKCJ0ZXN0RG93bmxvYWRlZEN1c3RvbVByb3BlcnR5IikudG9CeXRlU3RyaW5nKCksCisgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUuZ2V0RW1wdHlSZWdpc3RyeSgpKTsKKyAgICBBbnkgcGVuZGluZ0N1c3RvbVByb3BlcnR5ID0KKyAgICAgICAgQW55LnBhcnNlRnJvbSgKKyAgICAgICAgICAgIFN0cmluZ1ZhbHVlLm9mKCJ0ZXN0UGVuZGluZ0N1c3RvbVByb3BlcnR5IikudG9CeXRlU3RyaW5nKCksCisgICAgICAgICAgICBFeHRlbnNpb25SZWdpc3RyeUxpdGUuZ2V0RW1wdHlSZWdpc3RyeSgpKTsKKyAgICBBbnkgbWlzbWF0Y2hlZEN1c3RvbVByb3BlcnR5ID0KKyAgICAgICAgQW55LnBhcnNlRnJvbSgKKyAgICAgICAgICAgIFN0cmluZ1ZhbHVlLm9mKCJ0ZXN0TWlzbWF0Y2hlQ3VzdG9tUHJvcGVydHkiKS50b0J5dGVTdHJpbmcoKSwKKyAgICAgICAgICAgIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5nZXRFbXB0eVJlZ2lzdHJ5KCkpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGV4aXN0aW5nRG93bmxvYWRlZEZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEJ1aWxkSWQoMSkKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoInRlc3R2YXJpYW50IikKKyAgICAgICAgICAgIC5zZXRDdXN0b21Qcm9wZXJ0eShkb3dubG9hZGVkQ3VzdG9tUHJvcGVydHkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZXhpc3RpbmdQZW5kaW5nRmlsZUdyb3VwID0KKyAgICAgICAgZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwLnRvQnVpbGRlcigpLnNldEN1c3RvbVByb3BlcnR5KHBlbmRpbmdDdXN0b21Qcm9wZXJ0eSkuYnVpbGQoKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShURVNUX0dST1VQKS5idWlsZCgpOworCisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGdldERvd25sb2FkZWRLZXkoZ3JvdXBLZXkpLCBleGlzdGluZ0Rvd25sb2FkZWRGaWxlR3JvdXApOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChnZXRQZW5kaW5nS2V5KGdyb3VwS2V5KSwgZXhpc3RpbmdQZW5kaW5nRmlsZUdyb3VwKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAuaW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBidWlsZElkID0gKi8gMSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIHZhcmlhbnRJZCA9ICovICJ0ZXN0dmFyaWFudCIsCisgICAgICAgICAgICAgICAgICAgICAgICAvKiB1cGRhdGVkRGF0YUZpbGVMaXN0ID0gKi8gSW1tdXRhYmxlTGlzdC5vZigpLAorICAgICAgICAgICAgICAgICAgICAgICAgLyogaW5saW5lRmlsZU1hcCA9ICovIEltbXV0YWJsZU1hcC5vZigpLAorICAgICAgICAgICAgICAgICAgICAgICAgLyogY3VzdG9tUHJvcGVydHlPcHRpb25hbCA9ICovIE9wdGlvbmFsLm9mKG1pc21hdGNoZWRDdXN0b21Qcm9wZXJ0eSksCisgICAgICAgICAgICAgICAgICAgICAgICBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgICAgICAgICAgICAgLmdldCgpKTsKKworICAgIGFzc2VydFRoYXQoZXgpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gZGV4ID0gKERvd25sb2FkRXhjZXB0aW9uKSBleC5nZXRDYXVzZSgpOworICAgIGFzc2VydFRoYXQoZGV4LmdldERvd25sb2FkUmVzdWx0Q29kZSgpKS5pc0VxdWFsVG8oRG93bmxvYWRSZXN1bHRDb2RlLkdST1VQX05PVF9GT1VORF9FUlJPUik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZAorICAgICAgdGVzdEltcG9ydEZpbGVzSW50b0ZpbGVHcm91cF93aGVuQ3VzdG9tUHJvcGVydHlEb2VzTm90TWF0Y2hfd2hlbkR1ZVRvQmVpbmdBYnNlbnRfZmFpbHMoKQorICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFNldCB1cCBleGlzdGluZyBwZW5kaW5nL2Rvd25sb2FkZWQgZ3JvdXBzIGFuZCBjaGVjayB0aGF0IHRoZXkgZG8gbm90IG1hdGNoIGR1ZSB0byBjdXN0b20KKyAgICAvLyBwcm9wZXJ0eSBkaWZmZXJlbmNlcy4KKworICAgIC8vIEFueSBjYW4gcGFjayBwcm90byBtZXNzYWdlcyBvbmx5LCBzbyB1c2UgU3RyaW5nVmFsdWUuCisgICAgQW55IGRvd25sb2FkZWRDdXN0b21Qcm9wZXJ0eSA9CisgICAgICAgIEFueS5wYXJzZUZyb20oCisgICAgICAgICAgICBTdHJpbmdWYWx1ZS5vZigidGVzdERvd25sb2FkZWRDdXN0b21Qcm9wZXJ0eSIpLnRvQnl0ZVN0cmluZygpLAorICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmdldEVtcHR5UmVnaXN0cnkoKSk7CisgICAgQW55IHBlbmRpbmdDdXN0b21Qcm9wZXJ0eSA9CisgICAgICAgIEFueS5wYXJzZUZyb20oCisgICAgICAgICAgICBTdHJpbmdWYWx1ZS5vZigidGVzdFBlbmRpbmdDdXN0b21Qcm9wZXJ0eSIpLnRvQnl0ZVN0cmluZygpLAorICAgICAgICAgICAgRXh0ZW5zaW9uUmVnaXN0cnlMaXRlLmdldEVtcHR5UmVnaXN0cnkoKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0QnVpbGRJZCgxKQorICAgICAgICAgICAgLnNldFZhcmlhbnRJZCgidGVzdHZhcmlhbnQiKQorICAgICAgICAgICAgLnNldEN1c3RvbVByb3BlcnR5KGRvd25sb2FkZWRDdXN0b21Qcm9wZXJ0eSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBleGlzdGluZ1BlbmRpbmdGaWxlR3JvdXAgPQorICAgICAgICBleGlzdGluZ0Rvd25sb2FkZWRGaWxlR3JvdXAudG9CdWlsZGVyKCkuc2V0Q3VzdG9tUHJvcGVydHkocGVuZGluZ0N1c3RvbVByb3BlcnR5KS5idWlsZCgpOworCisgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPSBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApLmJ1aWxkKCk7CisKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAoZ2V0RG93bmxvYWRlZEtleShncm91cEtleSksIGV4aXN0aW5nRG93bmxvYWRlZEZpbGVHcm91cCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKGdldFBlbmRpbmdLZXkoZ3JvdXBLZXkpLCBleGlzdGluZ1BlbmRpbmdGaWxlR3JvdXApOworCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4ID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgKCkgLT4KKyAgICAgICAgICAgICAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgICAgICAgICAgICAgIC5pbXBvcnRGaWxlc0ludG9GaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgICAgICBncm91cEtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGJ1aWxkSWQgPSAqLyAxLAorICAgICAgICAgICAgICAgICAgICAgICAgLyogdmFyaWFudElkID0gKi8gInRlc3R2YXJpYW50IiwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZWREYXRhRmlsZUxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmxpbmVGaWxlTWFwID0gKi8gSW1tdXRhYmxlTWFwLm9mKCksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgICAgICAgICBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgICAgICAgICAgICAgLmdldCgpKTsKKworICAgIGFzc2VydFRoYXQoZXgpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gZGV4ID0gKERvd25sb2FkRXhjZXB0aW9uKSBleC5nZXRDYXVzZSgpOworICAgIGFzc2VydFRoYXQoZGV4LmdldERvd25sb2FkUmVzdWx0Q29kZSgpKS5pc0VxdWFsVG8oRG93bmxvYWRSZXN1bHRDb2RlLkdST1VQX05PVF9GT1VORF9FUlJPUik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwX3doZW5VbmFibGVUb1Jlc2VydmVOZXdGaWxlc19mYWlscygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFJlc2V0IHdpdGggbW9jayBTaGFyZWRGaWxlTWFuYWdlciB0byBmb3JjZSBmYWlsdXJlcworICAgIHJlc2V0RmlsZUdyb3VwTWFuYWdlcihmaWxlR3JvdXBzTWV0YWRhdGEsIG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisKKyAgICAvLyBDcmVhdGUgZXhpc3RpbmcgZmlsZSBncm91cCBhbmQgYSBuZXcgZmlsZSBncm91cCB0aGF0IHdpbGwgYWRkIGFuIGlubGluZSBmaWxlICh3aGljaCBuZWVkcyB0bworICAgIC8vIGJlIHJlc2VydmVkIGluIFNoYXJlZEZpbGVNYW5hZ2VyKS4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZXhpc3RpbmdGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgSW1tdXRhYmxlTGlzdDxEYXRhRmlsZT4gdXBkYXRlZERhdGFGaWxlTGlzdCA9CisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoCisgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCJpbmxpbmUtZmlsZSIpCisgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKCJhYmMiKQorICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJpbmxpbmVmaWxlOnNoYTE6YWJjIikKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisKKyAgICBHcm91cEtleSBncm91cEtleSA9IEdyb3VwS2V5Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkuYnVpbGQoKTsKKworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChnZXREb3dubG9hZGVkS2V5KGdyb3VwS2V5KSwgZXhpc3RpbmdGaWxlR3JvdXApOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIGV4aXN0aW5nRmlsZUdyb3VwLCBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIE5ld0ZpbGVLZXkgbmV3SW5saW5lRmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgdXBkYXRlZERhdGFGaWxlTGlzdC5nZXQoMCksIGV4aXN0aW5nRmlsZUdyb3VwLmdldEFsbG93ZWRSZWFkZXJzRW51bSgpKTsKKyAgICBOZXdGaWxlS2V5IGV4aXN0aW5nRmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgZXhpc3RpbmdGaWxlR3JvdXAuZ2V0RmlsZSgwKSwgZXhpc3RpbmdGaWxlR3JvdXAuZ2V0QWxsb3dlZFJlYWRlcnNFbnVtKCkpOworCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIucmVzZXJ2ZUZpbGVFbnRyeShuZXdJbmxpbmVGaWxlS2V5KSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmFsc2UpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5yZXNlcnZlRmlsZUVudHJ5KGV4aXN0aW5nRmlsZUtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAuaW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBidWlsZElkID0gKi8gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIHZhcmlhbnRJZCA9ICovICIiLAorICAgICAgICAgICAgICAgICAgICAgICAgLyogdXBkYXRlZERhdGFGaWxlTGlzdCA9ICovIHVwZGF0ZWREYXRhRmlsZUxpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBpbmxpbmVGaWxlTWFwID0gKi8gSW1tdXRhYmxlTWFwLm9mKCksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAgICAgICAgICAgICBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgICAgICAgICAgICAgLmdldCgpKTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIERvd25sb2FkRXhjZXB0aW9uIGRleCA9IChEb3dubG9hZEV4Y2VwdGlvbikgZXguZ2V0Q2F1c2UoKTsKKyAgICBhc3NlcnRUaGF0KGRleC5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuVU5BQkxFX1RPX1JFU0VSVkVfRklMRV9FTlRSWSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZAorICAgICAgdGVzdEltcG9ydEZpbGVzSW50b0ZpbGVHcm91cF93aGVuTm9OZXdJbmxpbmVGaWxlc1NwZWNpZmllZEFuZEZpbGVzRG93bmxvYWRlZF9jb21wbGV0ZXMoKQorICAgICAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENyZWF0ZSBhIGdyb3VwIHRoYXQgaGFzIDEgc3RhbmRhcmQgZmlsZSBhbmQgMSBpbmxpbmUgZmlsZSwgYm90aCBkb3dubG9hZGVkCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRGaWxlKAorICAgICAgICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCJpbmxpbmUtZmlsZSIpCisgICAgICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bSgiYWJjIikKKyAgICAgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImlubGluZWZpbGU6c2hhMTphYmMiKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEltbXV0YWJsZU1hcDxTdHJpbmcsIEZpbGVTb3VyY2U+IGlubGluZUZpbGVNYXAgPQorICAgICAgICBJbW11dGFibGVNYXAub2YoCisgICAgICAgICAgICAiaW5saW5lLWZpbGUiLCBGaWxlU291cmNlLm9mQnl0ZVN0cmluZyhCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiVEVTVF9DT05URU5UIikpKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShURVNUX0dST1VQKS5idWlsZCgpOworCisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGdldERvd25sb2FkZWRLZXkoZ3JvdXBLZXkpLCBkYXRhRmlsZUdyb3VwKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBkYXRhRmlsZUdyb3VwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgLyogYnVpbGRJZCA9ICovIDAsCisgICAgICAgICAgICAvKiB2YXJpYW50SWQgPSAqLyAiIiwKKyAgICAgICAgICAgIC8qIHVwZGF0ZWREYXRhRmlsZUxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICBpbmxpbmVGaWxlTWFwLAorICAgICAgICAgICAgLyogY3VzdG9tUHJvcGVydHlPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIFNpbmNlIG5vIG5ldyBmaWxlcyB3ZXJlIHNwZWNpZmllZCwgdGhlIGdyb3VwIHNob3VsZCByZW1haW4gdGhlIHNhbWUgKGRvd25sb2FkZWQpLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkRmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZ2V0RG93bmxvYWRlZEtleShncm91cEtleSkpLmdldCgpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZEZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKGRhdGFGaWxlR3JvdXAuZ2V0R3JvdXBOYW1lKCkpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZEZpbGVHcm91cC5nZXRCdWlsZElkKCkpLmlzRXF1YWxUbyhkYXRhRmlsZUdyb3VwLmdldEJ1aWxkSWQoKSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkRmlsZUdyb3VwLmdldFZhcmlhbnRJZCgpKS5pc0VxdWFsVG8oZGF0YUZpbGVHcm91cC5nZXRWYXJpYW50SWQoKSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkRmlsZUdyb3VwLmdldEZpbGVMaXN0KCkpCisgICAgICAgIC5jb250YWluc0V4YWN0bHlFbGVtZW50c0luKGRhdGFGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwX3doZW5Ob05ld0ZpbGVzU3BlY2lmaWVkQW5kRmlsZXNQZW5kaW5nX2NvbXBsZXRlcygpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShURVNUX0dST1VQKS5idWlsZCgpOworCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKGdldFBlbmRpbmdLZXkoZ3JvdXBLZXkpLCBkYXRhRmlsZUdyb3VwKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLCBkYXRhRmlsZUdyb3VwLCBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgLyogYnVpbGRJZCA9ICovIDAsCisgICAgICAgICAgICAvKiB2YXJpYW50SWQgPSAqLyAiIiwKKyAgICAgICAgICAgIC8qIHVwZGF0ZWREYXRhRmlsZUxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICAvKiBpbmxpbmVGaWxlTWFwID0gKi8gSW1tdXRhYmxlTWFwLm9mKCksCisgICAgICAgICAgICAvKiBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gU2luY2Ugbm8gbmV3IGZpbGVzIHdlcmUgc3BlY2lmaWVkLCB0aGUgZ3JvdXAgc2hvdWxkIHJlbWFpbiB0aGUgc2FtZSAocGVuZGluZykuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdGaWxlR3JvdXAgPSBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChnZXRQZW5kaW5nS2V5KGdyb3VwS2V5KSkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nRmlsZUdyb3VwLmdldEdyb3VwTmFtZSgpKS5pc0VxdWFsVG8oZGF0YUZpbGVHcm91cC5nZXRHcm91cE5hbWUoKSk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nRmlsZUdyb3VwLmdldEJ1aWxkSWQoKSkuaXNFcXVhbFRvKGRhdGFGaWxlR3JvdXAuZ2V0QnVpbGRJZCgpKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdGaWxlR3JvdXAuZ2V0VmFyaWFudElkKCkpLmlzRXF1YWxUbyhkYXRhRmlsZUdyb3VwLmdldFZhcmlhbnRJZCgpKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKSkuaXNFcXVhbFRvKGRhdGFGaWxlR3JvdXAuZ2V0RmlsZUxpc3QoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwX3doZW5JbXBvcnRpbmdJbmxpbmVGaWxlQW5kUGVuZGluZ19tZXJnZXNHcm91cCgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBTZXQgdXAgYW4gZXhpc3RpbmcgcGVuZGluZyBmaWxlIGdyb3VwIGFuZCBhIG5ldyBpbmxpbmUgZmlsZSB0byBtZXJnZQorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBleGlzdGluZ1BlbmRpbmdGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgSW1tdXRhYmxlTGlzdDxEYXRhRmlsZT4gdXBkYXRlZERhdGFGaWxlTGlzdCA9CisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoCisgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCJpbmxpbmUtZmlsZSIpCisgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKCJhYmMiKQorICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJpbmxpbmVmaWxlOnNoYTE6YWJjIikKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSk7CisgICAgSW1tdXRhYmxlTWFwPFN0cmluZywgRmlsZVNvdXJjZT4gaW5saW5lRmlsZU1hcCA9CisgICAgICAgIEltbXV0YWJsZU1hcC5vZigKKyAgICAgICAgICAgICJpbmxpbmUtZmlsZSIsIEZpbGVTb3VyY2Uub2ZCeXRlU3RyaW5nKEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KCJURVNUX0NPTlRFTlQiKSkpOworCisgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPSBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApLmJ1aWxkKCk7CisKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAoZ2V0UGVuZGluZ0tleShncm91cEtleSksIGV4aXN0aW5nUGVuZGluZ0ZpbGVHcm91cCk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZXhpc3RpbmdQZW5kaW5nRmlsZUdyb3VwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKworICAgIC8vIFRPRE86IHJlbW92ZSBvbmNlIFNGTSBjYW4gcGVyZm9ybSBpbXBvcnQKKyAgICAvLyB3cml0ZSBpbmxpbmUgZmlsZSBhcyBkb3dubG9hZGVkIHNvIEZHTSBjYW4gZmluZCBpdAorICAgIE5ld0ZpbGVLZXkgbmV3SW5saW5lRmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgdXBkYXRlZERhdGFGaWxlTGlzdC5nZXQoMCksIGV4aXN0aW5nUGVuZGluZ0ZpbGVHcm91cC5nZXRBbGxvd2VkUmVhZGVyc0VudW0oKSk7CisgICAgU2hhcmVkRmlsZSBuZXdJbmxpbmVTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSh1cGRhdGVkRGF0YUZpbGVMaXN0LmdldCgwKS5nZXRGaWxlSWQoKSkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0lubGluZUZpbGVLZXksIG5ld0lubGluZVNoYXJlZEZpbGUpLmdldCgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAuaW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwKAorICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAvKiBidWlsZElkID0gKi8gMCwKKyAgICAgICAgICAgIC8qIHZhcmlhbnRJZCA9ICovICIiLAorICAgICAgICAgICAgdXBkYXRlZERhdGFGaWxlTGlzdCwKKyAgICAgICAgICAgIGlubGluZUZpbGVNYXAsCisgICAgICAgICAgICAvKiBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gQ2hlY2sgdGhhdCByZXN1bHRpbmcgZmlsZSBncm91cCByZW1haW5zIHBlbmRpbmcsIGJ1dCBzaG91bGQgaGF2ZSBib3RoIGZpbGVzIG1lcmdlZCB0b2dldGhlcgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nRmlsZUdyb3VwQWZ0ZXJJbXBvcnQgPQorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChnZXRQZW5kaW5nS2V5KGdyb3VwS2V5KSkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nRmlsZUdyb3VwQWZ0ZXJJbXBvcnQuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygyKTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdGaWxlR3JvdXBBZnRlckltcG9ydC5nZXRGaWxlTGlzdCgpKQorICAgICAgICAuY29udGFpbnNFeGFjdGx5KGV4aXN0aW5nUGVuZGluZ0ZpbGVHcm91cC5nZXRGaWxlKDApLCB1cGRhdGVkRGF0YUZpbGVMaXN0LmdldCgwKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwX3doZW5JbXBvcnRpbmdJbmxpbmVGaWxlQW5kRG93bmxvYWRlZF9tZXJnZXNHcm91cCgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBTZXQgdXAgYW4gZXhpc3RpbmcgZG93bmxvYWRlZCBmaWxlIGdyb3VwIGFuZCBhIG5ldyBmaWxlIGdyb3VwIHdpdGggYW4gaW5saW5lIGZpbGUgdG8gbWVyZ2UKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIEltbXV0YWJsZUxpc3Q8RGF0YUZpbGU+IHVwZGF0ZWREYXRhRmlsZUxpc3QgPQorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKAorICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVJZCgiaW5saW5lLWZpbGUiKQorICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bSgiYWJjIikKKyAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTpzaGExOmFiYyIpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgIEltbXV0YWJsZU1hcDxTdHJpbmcsIEZpbGVTb3VyY2U+IGlubGluZUZpbGVNYXAgPQorICAgICAgICBJbW11dGFibGVNYXAub2YoCisgICAgICAgICAgICAiaW5saW5lLWZpbGUiLCBGaWxlU291cmNlLm9mQnl0ZVN0cmluZyhCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiVEVTVF9DT05URU5UIikpKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShURVNUX0dST1VQKS5idWlsZCgpOworCisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGdldERvd25sb2FkZWRLZXkoZ3JvdXBLZXkpLCBleGlzdGluZ0Rvd25sb2FkZWRGaWxlR3JvdXApOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGV4aXN0aW5nRG93bmxvYWRlZEZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICAvLyBUT0RPOiByZW1vdmUgb25jZSBTRk0gY2FuIHBlcmZvcm0gaW1wb3J0CisgICAgLy8gd3JpdGUgaW5saW5lIGZpbGUgYXMgZG93bmxvYWRlZCBzbyBGR00gY2FuIGZpbmQgaXQKKyAgICBOZXdGaWxlS2V5IG5ld0lubGluZUZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIHVwZGF0ZWREYXRhRmlsZUxpc3QuZ2V0KDApLCBleGlzdGluZ0Rvd25sb2FkZWRGaWxlR3JvdXAuZ2V0QWxsb3dlZFJlYWRlcnNFbnVtKCkpOworICAgIFNoYXJlZEZpbGUgbmV3SW5saW5lU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUodXBkYXRlZERhdGFGaWxlTGlzdC5nZXQoMCkuZ2V0RmlsZUlkKCkpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdJbmxpbmVGaWxlS2V5LCBuZXdJbmxpbmVTaGFyZWRGaWxlKS5nZXQoKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgLyogYnVpbGRJZCA9ICovIDAsCisgICAgICAgICAgICAvKiB2YXJpYW50SWQgPSAqLyAiIiwKKyAgICAgICAgICAgIHVwZGF0ZWREYXRhRmlsZUxpc3QsCisgICAgICAgICAgICBpbmxpbmVGaWxlTWFwLAorICAgICAgICAgICAgLyogY3VzdG9tUHJvcGVydHlPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIENoZWNrIHRoYXQgcmVzdWx0aW5nIGZpbGUgZ3JvdXAgaXMgZG93bmxvYWRlZCwgYnV0IHNob3VsZCBoYXZlIGJvdGggZmlsZXMgbWVyZ2VkIHRvZ2V0aGVyCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRGaWxlR3JvdXBBZnRlckltcG9ydCA9CisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGdldERvd25sb2FkZWRLZXkoZ3JvdXBLZXkpKS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRGaWxlR3JvdXBBZnRlckltcG9ydC5nZXRGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDIpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZEZpbGVHcm91cEFmdGVySW1wb3J0LmdldEZpbGVMaXN0KCkpCisgICAgICAgIC5jb250YWluc0V4YWN0bHkoZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwLmdldEZpbGUoMCksIHVwZGF0ZWREYXRhRmlsZUxpc3QuZ2V0KDApKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnRGaWxlc0ludG9GaWxlR3JvdXBfd2hlbk1hdGNoZXNEb3dubG9hZGVkQnV0Tm90UGVuZGluZ19pbXBvcnRzVG9Eb3dubG9hZGVkKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFNldCB1cCBhbiBleGlzdGluZyBwZW5kaW5nIGZpbGUgZ3JvdXAsIGFuIGV4aXN0aW5nIGRvd25sb2FkZWQgZmlsZSBncm91cCBhbmQgYSBuZXcgZmlsZQorICAgIC8vIGdyb3VwIHRoYXQgbWF0Y2hlcyB0aGUgZG93bmxvYWRlZCBmaWxlIGdyb3VwCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGV4aXN0aW5nUGVuZGluZ0ZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwID0KKyAgICAgICAgZXhpc3RpbmdQZW5kaW5nRmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuY2xlYXJGaWxlKCkKKyAgICAgICAgICAgIC5hZGRGaWxlKE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJkb3dubG9hZGVkLWZpbGUiLCAwKSkKKyAgICAgICAgICAgIC5zZXRCdWlsZElkKDEwKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgSW1tdXRhYmxlTGlzdDxEYXRhRmlsZT4gdXBkYXRlZERhdGFGaWxlTGlzdCA9CisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoCisgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCJpbmxpbmUtZmlsZSIpCisgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKCJhYmMiKQorICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJpbmxpbmVmaWxlOmFiYyIpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgIEltbXV0YWJsZU1hcDxTdHJpbmcsIEZpbGVTb3VyY2U+IGlubGluZUZpbGVNYXAgPQorICAgICAgICBJbW11dGFibGVNYXAub2YoCisgICAgICAgICAgICAiaW5saW5lLWZpbGUiLCBGaWxlU291cmNlLm9mQnl0ZVN0cmluZyhCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiVEVTVF9DT05URU5UIikpKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShURVNUX0dST1VQKS5idWlsZCgpOworCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKGdldFBlbmRpbmdLZXkoZ3JvdXBLZXkpLCBleGlzdGluZ1BlbmRpbmdGaWxlR3JvdXApOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChnZXREb3dubG9hZGVkS2V5KGdyb3VwS2V5KSwgZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwKTsKKworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGV4aXN0aW5nUGVuZGluZ0ZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIC8vIFRPRE86IHJlbW92ZSBvbmNlIFNGTSBjYW4gcGVyZm9ybSBpbXBvcnQKKyAgICAvLyB3cml0ZSBpbmxpbmUgZmlsZSBhcyBkb3dubG9hZGVkIHNvIEZHTSBjYW4gZmluZCBpdAorICAgIE5ld0ZpbGVLZXkgbmV3SW5saW5lRmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgdXBkYXRlZERhdGFGaWxlTGlzdC5nZXQoMCksIGV4aXN0aW5nRG93bmxvYWRlZEZpbGVHcm91cC5nZXRBbGxvd2VkUmVhZGVyc0VudW0oKSk7CisgICAgU2hhcmVkRmlsZSBuZXdJbmxpbmVTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSh1cGRhdGVkRGF0YUZpbGVMaXN0LmdldCgwKS5nZXRGaWxlSWQoKSkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0lubGluZUZpbGVLZXksIG5ld0lubGluZVNoYXJlZEZpbGUpLmdldCgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAuaW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwKAorICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAvKiBidWlsZElkID0gKi8gMTAsCisgICAgICAgICAgICAvKiB2YXJpYW50SWQgPSAqLyAiIiwKKyAgICAgICAgICAgIHVwZGF0ZWREYXRhRmlsZUxpc3QsCisgICAgICAgICAgICBpbmxpbmVGaWxlTWFwLAorICAgICAgICAgICAgLyogY3VzdG9tUHJvcGVydHlPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIENoZWNrIHRoYXQgZG93bmxvYWRlZCBmaWxlIGdyb3VwIG5vdyBjb250YWlucyB0aGUgbWVyZ2VkIGZpbGUgZ3JvdXAgYW5kIHBlbmRpbmcgZ3JvdXAgcmVtYWlucworICAgIC8vIHRoZSBzYW1lLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkRmlsZUdyb3VwQWZ0ZXJJbXBvcnQgPQorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChnZXREb3dubG9hZGVkS2V5KGdyb3VwS2V5KSkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkRmlsZUdyb3VwQWZ0ZXJJbXBvcnQuZ2V0QnVpbGRJZCgpKQorICAgICAgICAuaXNFcXVhbFRvKGV4aXN0aW5nRG93bmxvYWRlZEZpbGVHcm91cC5nZXRCdWlsZElkKCkpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlZEZpbGVHcm91cEFmdGVySW1wb3J0LmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMik7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkRmlsZUdyb3VwQWZ0ZXJJbXBvcnQuZ2V0RmlsZUxpc3QoKSkKKyAgICAgICAgLmNvbnRhaW5zRXhhY3RseShleGlzdGluZ0Rvd25sb2FkZWRGaWxlR3JvdXAuZ2V0RmlsZSgwKSwgdXBkYXRlZERhdGFGaWxlTGlzdC5nZXQoMCkpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZ2V0UGVuZGluZ0tleShncm91cEtleSkpLmdldCgpKQorICAgICAgICAuaXNFcXVhbFRvKGV4aXN0aW5nUGVuZGluZ0ZpbGVHcm91cCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwX3doZW5NYXRjaGVzUGVuZGluZ0J1dE5vdERvd25sb2FkZWRfaW1wb3J0c1RvUGVuZGluZygpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBTZXQgdXAgYW4gZXhpc3RpbmcgcGVuZGluZyBmaWxlIGdyb3VwLCBhbiBleGlzdGluZyBkb3dubG9hZGVkIGZpbGUgZ3JvdXAgYW5kIGEgbmV3IGZpbGUKKyAgICAvLyBncm91cCB0aGF0IG1hdGNoZXMgdGhlIHBlbmRpbmcgZmlsZSBncm91cAorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBleGlzdGluZ1BlbmRpbmdGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGV4aXN0aW5nRG93bmxvYWRlZEZpbGVHcm91cCA9CisgICAgICAgIGV4aXN0aW5nUGVuZGluZ0ZpbGVHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLmNsZWFyRmlsZSgpCisgICAgICAgICAgICAuYWRkRmlsZShNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZG93bmxvYWRlZC1maWxlIiwgMCkpCisgICAgICAgICAgICAuc2V0QnVpbGRJZCgxMCkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEltbXV0YWJsZUxpc3Q8RGF0YUZpbGU+IHVwZGF0ZWREYXRhRmlsZUxpc3QgPQorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKAorICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVJZCgiaW5saW5lLWZpbGUiKQorICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bSgiYWJjIikKKyAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTphYmMiKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICBJbW11dGFibGVNYXA8U3RyaW5nLCBGaWxlU291cmNlPiBpbmxpbmVGaWxlTWFwID0KKyAgICAgICAgSW1tdXRhYmxlTWFwLm9mKAorICAgICAgICAgICAgImlubGluZS1maWxlIiwgRmlsZVNvdXJjZS5vZkJ5dGVTdHJpbmcoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoIlRFU1RfQ09OVEVOVCIpKSk7CisKKyAgICBHcm91cEtleSBncm91cEtleSA9IEdyb3VwS2V5Lm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkuYnVpbGQoKTsKKworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChnZXRQZW5kaW5nS2V5KGdyb3VwS2V5KSwgZXhpc3RpbmdQZW5kaW5nRmlsZUdyb3VwKTsKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAoZ2V0RG93bmxvYWRlZEtleShncm91cEtleSksIGV4aXN0aW5nRG93bmxvYWRlZEZpbGVHcm91cCk7CisKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBleGlzdGluZ1BlbmRpbmdGaWxlR3JvdXAsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGV4aXN0aW5nRG93bmxvYWRlZEZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICAvLyBUT0RPOiByZW1vdmUgb25jZSBTRk0gY2FuIHBlcmZvcm0gaW1wb3J0CisgICAgLy8gd3JpdGUgaW5saW5lIGZpbGUgYXMgZG93bmxvYWRlZCBzbyBGR00gY2FuIGZpbmQgaXQKKyAgICBOZXdGaWxlS2V5IG5ld0lubGluZUZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIHVwZGF0ZWREYXRhRmlsZUxpc3QuZ2V0KDApLCBleGlzdGluZ1BlbmRpbmdGaWxlR3JvdXAuZ2V0QWxsb3dlZFJlYWRlcnNFbnVtKCkpOworICAgIFNoYXJlZEZpbGUgbmV3SW5saW5lU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUodXBkYXRlZERhdGFGaWxlTGlzdC5nZXQoMCkuZ2V0RmlsZUlkKCkpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdJbmxpbmVGaWxlS2V5LCBuZXdJbmxpbmVTaGFyZWRGaWxlKS5nZXQoKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgLyogYnVpbGRJZCA9ICovIDAsCisgICAgICAgICAgICAvKiB2YXJpYW50SWQgPSAqLyAiIiwKKyAgICAgICAgICAgIHVwZGF0ZWREYXRhRmlsZUxpc3QsCisgICAgICAgICAgICBpbmxpbmVGaWxlTWFwLAorICAgICAgICAgICAgLyogY3VzdG9tUHJvcGVydHlPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIENoZWNrIHRoYXQgcGVuZGluZyBmaWxlIGdyb3VwIG5vdyBjb250YWlucyB0aGUgbWVyZ2VkIGZpbGUgZ3JvdXAgYW5kIGRvd25sb2FkZWQgZ3JvdXAgcmVtYWlucworICAgIC8vIHRoZSBzYW1lLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nRmlsZUdyb3VwQWZ0ZXJJbXBvcnQgPQorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChnZXRQZW5kaW5nS2V5KGdyb3VwS2V5KSkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nRmlsZUdyb3VwQWZ0ZXJJbXBvcnQuZ2V0QnVpbGRJZCgpKQorICAgICAgICAuaXNFcXVhbFRvKGV4aXN0aW5nUGVuZGluZ0ZpbGVHcm91cC5nZXRCdWlsZElkKCkpOworICAgIGFzc2VydFRoYXQocGVuZGluZ0ZpbGVHcm91cEFmdGVySW1wb3J0LmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMik7CisgICAgYXNzZXJ0VGhhdChwZW5kaW5nRmlsZUdyb3VwQWZ0ZXJJbXBvcnQuZ2V0RmlsZUxpc3QoKSkKKyAgICAgICAgLmNvbnRhaW5zRXhhY3RseShleGlzdGluZ1BlbmRpbmdGaWxlR3JvdXAuZ2V0RmlsZSgwKSwgdXBkYXRlZERhdGFGaWxlTGlzdC5nZXQoMCkpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZ2V0RG93bmxvYWRlZEtleShncm91cEtleSkpLmdldCgpKQorICAgICAgICAuaXNFcXVhbFRvKGV4aXN0aW5nRG93bmxvYWRlZEZpbGVHcm91cCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwX3doZW5QZXJmb3JtaW5nSW1wb3J0X2Nob29zZXNGaWxlU291cmNlQnlJZCgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBVc2UgbW9ja1NoYXJlZEZpbGVNYW5hZ2VyIHRvIGNoZWNrIHN0YXJ0SW1wb3J0IGNhbGwKKyAgICByZXNldEZpbGVHcm91cE1hbmFnZXIoZmlsZUdyb3Vwc01ldGFkYXRhLCBtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworCisgICAgRmlsZVNvdXJjZSB0ZXN0RmlsZVNvdXJjZSA9CisgICAgICAgIEZpbGVTb3VyY2Uub2ZCeXRlU3RyaW5nKEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KCJURVNUX0ZJTEVfU09VUkNFIikpOworCisgICAgLy8gU2V0dXAgZmlsZSBncm91cCB3aXRoIGlubGluZSBmaWxlIHRvIGltcG9ydAorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRGaWxlKAorICAgICAgICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCJpbmxpbmUtZmlsZSIpCisgICAgICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bSgiYWJjIikKKyAgICAgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImlubGluZWZpbGU6c2hhMTphYmMiKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPSBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApLmJ1aWxkKCk7CisgICAgTmV3RmlsZUtleSBpbmxpbmVGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoCisgICAgICAgICAgICBmaWxlR3JvdXAuZ2V0RmlsZSgwKSwgZmlsZUdyb3VwLmdldEFsbG93ZWRSZWFkZXJzRW51bSgpKTsKKworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChnZXRQZW5kaW5nS2V5KGdyb3VwS2V5KSwgZmlsZUdyb3VwKTsKKworICAgIC8vIFNldHVwIG1vY2sgU0ZNIHdpdGggc3VjY2Vzc2Z1bCBjYWxscworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLnJlc2VydmVGaWxlRW50cnkoaW5saW5lRmlsZUtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRGaWxlU3RhdHVzKGlubGluZUZpbGVLZXkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuc3RhcnRJbXBvcnQoCisgICAgICAgICAgICBncm91cEtleUNhcHRvci5jYXB0dXJlKCksCisgICAgICAgICAgICBlcShmaWxlR3JvdXAuZ2V0RmlsZSgwKSksCisgICAgICAgICAgICBlcShpbmxpbmVGaWxlS2V5KSwKKyAgICAgICAgICAgIGFueSgpLAorICAgICAgICAgICAgZmlsZVNvdXJjZUNhcHRvci5jYXB0dXJlKCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKSk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgIC5pbXBvcnRGaWxlc0ludG9GaWxlR3JvdXAoCisgICAgICAgICAgICBncm91cEtleSwKKyAgICAgICAgICAgIC8qIGJ1aWxkSWQgPSAqLyAwLAorICAgICAgICAgICAgLyogdmFyaWFudElkID0gKi8gIiIsCisgICAgICAgICAgICAvKiB1cGRhdGVkRGF0YUZpbGVMaXN0ID0gKi8gSW1tdXRhYmxlTGlzdC5vZigpLAorICAgICAgICAgICAgLyogaW5saW5lRmlsZU1hcCA9ICovIEltbXV0YWJsZU1hcC5vZigiaW5saW5lLWZpbGUiLCB0ZXN0RmlsZVNvdXJjZSksCisgICAgICAgICAgICAvKiBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gQ2hlY2sgdGhhdCBTRk0gc3RhcnRJbXBvcnQgd2FzIGNhbGxlZCB3aXRoIGV4cGVjdGVkIGlucHV0cworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIsIHRpbWVzKDEpKS5zdGFydEltcG9ydChhbnkoKSwgYW55KCksIGFueSgpLCBhbnkoKSwgYW55KCkpOworICAgIGFzc2VydFRoYXQoZ3JvdXBLZXlDYXB0b3IuZ2V0VmFsdWUoKS5nZXRHcm91cE5hbWUoKSkuaXNFcXVhbFRvKFRFU1RfR1JPVVApOworICAgIGFzc2VydFRoYXQoZmlsZVNvdXJjZUNhcHRvci5nZXRWYWx1ZSgpKS5pc0VxdWFsVG8odGVzdEZpbGVTb3VyY2UpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEltcG9ydEZpbGVzSW50b0ZpbGVHcm91cF93aGVuRmlsZUFscmVhZHlEb3dubG9hZGVkX2RvZXNOb3RBdHRlbXB0VG9JbXBvcnQoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVXNlIG1vY2tTaGFyZWRGaWxlTWFuYWdlciB0byBjaGVjayBzdGFydEltcG9ydCBjYWxsCisgICAgcmVzZXRGaWxlR3JvdXBNYW5hZ2VyKGZpbGVHcm91cHNNZXRhZGF0YSwgbW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKworICAgIEZpbGVTb3VyY2UgdGVzdEZpbGVTb3VyY2UgPQorICAgICAgICBGaWxlU291cmNlLm9mQnl0ZVN0cmluZyhCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiVEVTVF9GSUxFX1NPVVJDRSIpKTsKKworICAgIC8vIENyZWF0ZSBhbiBleGlzdGluZyBkb3dubG9hZGVkIGZpbGUgZ3JvdXAgYW5kIGF0dGVtcHQgdG8gaW1wb3J0IGFnYWluIHdpdGggYSBnaXZlbiBzb3VyY2UuCisgICAgLy8gU2luY2UgdGhlIGZpbGUgaXMgYWxyZWFkeSBtYXJrZWQgRE9XTkxPQURfQ09NUExFVEUsIHRoZSBpbXBvcnQgc2hvdWxkIG5vdCBiZSBpbnZva2VkLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBleGlzdGluZ0Rvd25sb2FkZWRGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRGaWxlKAorICAgICAgICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCJpbmxpbmUtZmlsZSIpCisgICAgICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bSgiYWJjIikKKyAgICAgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImlubGluZWZpbGU6YWJjIikKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShURVNUX0dST1VQKS5idWlsZCgpOworICAgIE5ld0ZpbGVLZXkgaW5saW5lRmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgZXhpc3RpbmdEb3dubG9hZGVkRmlsZUdyb3VwLmdldEZpbGUoMCksCisgICAgICAgICAgICBleGlzdGluZ0Rvd25sb2FkZWRGaWxlR3JvdXAuZ2V0QWxsb3dlZFJlYWRlcnNFbnVtKCkpOworCisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGdldERvd25sb2FkZWRLZXkoZ3JvdXBLZXkpLCBleGlzdGluZ0Rvd25sb2FkZWRGaWxlR3JvdXApOworCisgICAgLy8gU2V0dXAgbW9jayBTRk0gd2l0aCBzdWNjZXNzZnVsIGNhbGxzCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIucmVzZXJ2ZUZpbGVFbnRyeShpbmxpbmVGaWxlS2V5KSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoaW5saW5lRmlsZUtleSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgIGdyb3VwS2V5LAorICAgICAgICAgICAgLyogYnVpbGRJZCA9ICovIDAsCisgICAgICAgICAgICAvKiB2YXJpYW50SWQgPSAqLyAiIiwKKyAgICAgICAgICAgIC8qIHVwZGF0ZWREYXRhRmlsZUxpc3QgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCksCisgICAgICAgICAgICAvKiBpbmxpbmVGaWxlTWFwID0gKi8gSW1tdXRhYmxlTWFwLm9mKCJpbmxpbmUtZmlsZSIsIHRlc3RGaWxlU291cmNlKSwKKyAgICAgICAgICAgIC8qIGN1c3RvbVByb3BlcnR5T3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAuZ2V0KCk7CisKKyAgICAvLyBDaGVjayB0aGF0IFNGTSBzdGFydEltcG9ydCB3YXMgbm90IGNhbGxlZAorICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIsIHRpbWVzKDApKS5zdGFydEltcG9ydChhbnkoKSwgYW55KCksIGFueSgpLCBhbnkoKSwgYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEltcG9ydEZpbGVzSW50b0ZpbGVHcm91cHNfd2hlbkZpbGVTb3VyY2VOb3RQcm92aWRlZF9mYWlscygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIGNyZWF0ZSBhIGZpbGUgZ3JvdXAgYWRkZWQgdG8gTUREIHdpdGggYW4gaW5saW5lIGZpbGUgYW5kIGNoZWNrIHRoYXQgaW1wb3J0IGNhbGwgZmFpbHMgaWYKKyAgICAvLyBzb3VyY2UgaXMgbm90IHByb3ZpZGVkLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBleGlzdGluZ0ZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoImlubGluZS1maWxlIikKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKCJhYmMiKQorICAgICAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTphYmMiKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPSBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApLmJ1aWxkKCk7CisKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAoZ2V0UGVuZGluZ0tleShncm91cEtleSksIGV4aXN0aW5nRmlsZUdyb3VwKTsKKworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIGV4aXN0aW5nRmlsZUdyb3VwLCBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAuaW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwKAorICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXksCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBidWlsZElkID0gKi8gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIHZhcmlhbnRJZCA9ICovICIiLAorICAgICAgICAgICAgICAgICAgICAgICAgLyogdXBkYXRlZERhdGFGaWxlTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGlubGluZUZpbGVNYXAgPSAqLyBJbW11dGFibGVNYXAub2YoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGN1c3RvbVByb3BlcnR5T3B0aW9uYWwgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAgICAgICAgICAgICAuZ2V0KCkpOworICAgIGFzc2VydFRoYXQoZXgpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihBZ2dyZWdhdGVFeGNlcHRpb24uY2xhc3MpOworICAgIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiBhZXggPSAoQWdncmVnYXRlRXhjZXB0aW9uKSBleC5nZXRDYXVzZSgpOworICAgIGFzc2VydFRoYXQoYWV4LmdldEZhaWx1cmVzKCkpLmhhc1NpemUoMSk7CisgICAgYXNzZXJ0VGhhdChhZXguZ2V0RmFpbHVyZXMoKS5nZXQoMCkpLmlzSW5zdGFuY2VPZihEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gZGV4ID0gKERvd25sb2FkRXhjZXB0aW9uKSBhZXguZ2V0RmFpbHVyZXMoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChkZXguZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpCisgICAgICAgIC5pc0VxdWFsVG8oRG93bmxvYWRSZXN1bHRDb2RlLk1JU1NJTkdfSU5MSU5FX0ZJTEVfU09VUkNFKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnRGaWxlc0ludG9GaWxlR3JvdXBfd2hlbkltcG9ydEZhaWxzX3ByZXZlbnRzTWV0YWRhdGFVcGRhdGUoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVXNlIG1vY2tTaGFyZWRGaWxlTWFuYWdlciB0byBtb2NrIGEgZmFpbHVyZSBmb3IgYW4gaW1wb3J0CisgICAgcmVzZXRGaWxlR3JvdXBNYW5hZ2VyKGZpbGVHcm91cHNNZXRhZGF0YSwgbW9ja1NoYXJlZEZpbGVNYW5hZ2VyKTsKKworICAgIEZpbGVTb3VyY2UgdGVzdEZpbGVTb3VyY2UxID0KKyAgICAgICAgRmlsZVNvdXJjZS5vZkJ5dGVTdHJpbmcoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoIlRFU1RfRklMRV9TT1VSQ0VfMSIpKTsKKyAgICBGaWxlU291cmNlIHRlc3RGaWxlU291cmNlMiA9CisgICAgICAgIEZpbGVTb3VyY2Uub2ZCeXRlU3RyaW5nKEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KCJURVNUX0ZJTEVfU09VUkNFXzIiKSk7CisKKyAgICAvLyBTZXR1cCBlbXB0eSBmaWxlIGdyb3VwCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAwKTsKKworICAgIC8vIFNldHVwIGxpc3Qgb2YgZmlsZXMgdGhhdCBzaG91bGQgYmUgaW1wb3J0ZWQKKyAgICBJbW11dGFibGVMaXN0PERhdGFGaWxlPiB1cGRhdGVkRGF0YUZpbGVMaXN0ID0KKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoImlubGluZS1maWxlLTEiKQorICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bSgiYWJjIikKKyAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTpzaGExOmFiYyIpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCksCisgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCJpbmxpbmUtZmlsZS0yIikKKyAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oImRlZiIpCisgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImlubGluZWZpbGU6c2hhMTpkZWYiKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5ID0gR3JvdXBLZXkubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShURVNUX0dST1VQKS5idWlsZCgpOworICAgIE5ld0ZpbGVLZXkgaW5saW5lRmlsZUtleTEgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIHVwZGF0ZWREYXRhRmlsZUxpc3QuZ2V0KDApLCBmaWxlR3JvdXAuZ2V0QWxsb3dlZFJlYWRlcnNFbnVtKCkpOworICAgIE5ld0ZpbGVLZXkgaW5saW5lRmlsZUtleTIgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIHVwZGF0ZWREYXRhRmlsZUxpc3QuZ2V0KDEpLCBmaWxlR3JvdXAuZ2V0QWxsb3dlZFJlYWRlcnNFbnVtKCkpOworCisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGdldERvd25sb2FkZWRLZXkoZ3JvdXBLZXkpLCBmaWxlR3JvdXApOworCisgICAgLy8gU2V0dXAgbW9jayBjYWxscyB0byBTRk0KKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5yZXNlcnZlRmlsZUVudHJ5KGFueSgpKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisKKyAgICAvLyBNb2NrIHRoYXQgaW5saW5lIGZpbGUgMSBjb21wbGV0ZWQsIGJ1dCBpbmxpbmUgZmlsZSAyIGZhaWxlZAorICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmdldEZpbGVTdGF0dXMoaW5saW5lRmlsZUtleTEpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0RmlsZVN0YXR1cyhpbmxpbmVGaWxlS2V5MikpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZpbGVTdGF0dXMuRE9XTkxPQURfRkFJTEVEKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuc3RhcnRJbXBvcnQoCisgICAgICAgICAgICBhbnkoKSwgZXEodXBkYXRlZERhdGFGaWxlTGlzdC5nZXQoMCkpLCBlcShpbmxpbmVGaWxlS2V5MSksIGFueSgpLCBhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5zdGFydEltcG9ydCgKKyAgICAgICAgICAgIGFueSgpLCBlcSh1cGRhdGVkRGF0YUZpbGVMaXN0LmdldCgxKSksIGVxKGlubGluZUZpbGVLZXkyKSwgYW55KCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oCisgICAgICAgICAgICBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkUmVzdWx0Q29kZShEb3dubG9hZFJlc3VsdENvZGUuRE9XTkxPQURfVFJBTlNGT1JNX0lPX0VSUk9SKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkpOworCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4ID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgKCkgLT4KKyAgICAgICAgICAgICAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgICAgICAgICAgICAgIC5pbXBvcnRGaWxlc0ludG9GaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgICAgICBncm91cEtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGJ1aWxkSWQgPSAqLyAwLAorICAgICAgICAgICAgICAgICAgICAgICAgLyogdmFyaWFudElkID0gKi8gIiIsCisgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkRGF0YUZpbGVMaXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgLyogaW5saW5lRmlsZU1hcCA9ICovIEltbXV0YWJsZU1hcC5vZigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW5saW5lLWZpbGUtMSIsIHRlc3RGaWxlU291cmNlMSwgImlubGluZS1maWxlLTIiLCB0ZXN0RmlsZVNvdXJjZTIpLAorICAgICAgICAgICAgICAgICAgICAgICAgLyogY3VzdG9tUHJvcGVydHlPcHRpb25hbCA9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoKSk7CisKKyAgICAvLyBDaGVjayBmb3IgZXhwZWN0ZWQgY2F1c2UKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoQWdncmVnYXRlRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBBZ2dyZWdhdGVFeGNlcHRpb24gYWV4ID0gKEFnZ3JlZ2F0ZUV4Y2VwdGlvbikgZXguZ2V0Q2F1c2UoKTsKKyAgICBhc3NlcnRUaGF0KGFleC5nZXRGYWlsdXJlcygpKS5oYXNTaXplKDEpOworICAgIGFzc2VydFRoYXQoYWV4LmdldEZhaWx1cmVzKCkuZ2V0KDApKS5pc0luc3RhbmNlT2YoRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIERvd25sb2FkRXhjZXB0aW9uIGRleCA9IChEb3dubG9hZEV4Y2VwdGlvbikgYWV4LmdldEZhaWx1cmVzKCkuZ2V0KDApOworICAgIGFzc2VydFRoYXQoZGV4LmdldERvd25sb2FkUmVzdWx0Q29kZSgpKQorICAgICAgICAuaXNFcXVhbFRvKERvd25sb2FkUmVzdWx0Q29kZS5ET1dOTE9BRF9UUkFOU0ZPUk1fSU9fRVJST1IpOworCisgICAgLy8gQ2hlY2sgdGhhdCBleGlzdGluZyAoZW1wdHkpIGdyb3VwIHJlbWFpbnMgaW4gbWV0YWRhdGEuIGlvdywgdGhlIGZpbGVzIGZyb20KKyAgICAvLyB1cGRhdGVkRGF0YUZpbGVMaXN0IHdlcmUgbm90IGFkZGVkIHNpbmNlIHRoZSBpbXBvcnQgZmFpbGVkLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBleGlzdGluZ0ZpbGVHcm91cCA9CisgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGdldERvd25sb2FkZWRLZXkoZ3JvdXBLZXkpKS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGV4aXN0aW5nRmlsZUdyb3VwLmdldEZpbGVMaXN0KCkpLmlzRW1wdHkoKTsKKworICAgIC8vIENoZWNrIHRoYXQgU0ZNIHN0YXJ0SW1wb3J0IHdhcyBjYWxsZWQgd2l0aCBleHBlY3RlZCBpbnB1dHMKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyLCB0aW1lcygyKSkuc3RhcnRJbXBvcnQoYW55KCksIGFueSgpLCBhbnkoKSwgYW55KCksIGFueSgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnRGaWxlc0ludG9GaWxlR3JvdXBfc2tpcHNTaWRlbG9hZGVkRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENyZWF0ZSBzaWRlbG9hZGVkIGdyb3VwIHdpdGggaW5saW5lIGZpbGUKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgc2lkZWxvYWRlZEdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoInNpZGVsb2FkZWRfZmlsZSIpCisgICAgICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJmaWxlOi90ZXN0IikKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtVHlwZShEYXRhRmlsZS5DaGVja3N1bVR5cGUuTk9ORSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYWRkRmlsZSgKKyAgICAgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEZpbGVJZCgiaW5saW5lX2ZpbGUiKQorICAgICAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTpzaGExOmNoZWNrc3VtIikKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKCJjaGVja3N1bSIpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgSW1tdXRhYmxlTWFwPFN0cmluZywgRmlsZVNvdXJjZT4gaW5saW5lRmlsZU1hcCA9CisgICAgICAgIEltbXV0YWJsZU1hcC5vZigKKyAgICAgICAgICAgICJpbmxpbmVfZmlsZSIsIEZpbGVTb3VyY2Uub2ZCeXRlU3RyaW5nKEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KCJURVNUX0NPTlRFTlQiKSkpOworICAgIE5ld0ZpbGVLZXkgaW5saW5lRmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgc2lkZWxvYWRlZEdyb3VwLmdldEZpbGUoMSksIHNpZGVsb2FkZWRHcm91cC5nZXRBbGxvd2VkUmVhZGVyc0VudW0oKSk7CisKKyAgICAvLyBXcml0ZSBncm91cCBhcyBwZW5kaW5nIHNpbmNlIHdlIGFyZSB3YWl0aW5nIG9uIGlubGluZSBmaWxlCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIHNpZGVsb2FkZWRHcm91cCk7CisKKyAgICAvLyBXcml0ZSBpbmxpbmUgZmlsZSBhcyBzdWNjZWVkZWQgc28gd2Ugc2tpcCBTRk0ncyBpbXBvcnQgY2FsbAorICAgIFNoYXJlZEZpbGUgaW5saW5lU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoc2lkZWxvYWRlZEdyb3VwLmdldEZpbGUoMSkuZ2V0RmlsZUlkKCkpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShpbmxpbmVGaWxlS2V5LCBpbmxpbmVTaGFyZWRGaWxlKS5nZXQoKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgIHRlc3RLZXksCisgICAgICAgICAgICBzaWRlbG9hZGVkR3JvdXAuZ2V0QnVpbGRJZCgpLAorICAgICAgICAgICAgc2lkZWxvYWRlZEdyb3VwLmdldFZhcmlhbnRJZCgpLAorICAgICAgICAgICAgLyogdXBkYXRlZERhdGFGaWxlTGlzdCA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSwKKyAgICAgICAgICAgIGlubGluZUZpbGVNYXAsCisgICAgICAgICAgICAvKiBjdXN0b21Qcm9wZXJ0eU9wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOb3ROdWxsKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG93bmxvYWRQZW5kaW5nR3JvdXBfc3VjY2VzcygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdyaXRlIDEgZ3JvdXAgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgICAgICAgVEVTVF9HUk9VUCwKKyAgICAgICAgICAgIC8qZmlsZUNvdW50PSovIDIsCisgICAgICAgICAgICAvKmRvd25sb2FkQXR0ZW1wdENvdW50PSovIDMsCisgICAgICAgICAgICAvKm5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXA9Ki8gdGVzdENsb2NrLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSA1MDBMKTsKKyAgICBFeHRyYUh0dHBIZWFkZXIgZXh0cmFIdHRwSGVhZGVyID0KKyAgICAgICAgRXh0cmFIdHRwSGVhZGVyLm5ld0J1aWxkZXIoKS5zZXRLZXkoInVzZXItYWdlbnQiKS5zZXRWYWx1ZSgibWRkLWRvd25sb2FkZXIiKS5idWlsZCgpOworCisgICAgZmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLnNldFRyYWZmaWNUYWcoVFJBRkZJQ19UQUcpCisgICAgICAgICAgICAuYWRkR3JvdXBFeHRyYUh0dHBIZWFkZXJzKGV4dHJhSHR0cEhlYWRlcikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5LCBmaWxlR3JvdXApOworCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZmlsZUdyb3VwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKHRlc3RLZXksIERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHBlbmRpbmcga2V5IGlzIHJlbW92ZWQgaWYgZG93bmxvYWQgaXMgY29tcGxldGUuCisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOdWxsKCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBkb3dubG9hZGVkIGtleSBpcyB3cml0dGVuIGludG8gbWV0YWRhdGEgaWYgZG93bmxvYWQgaXMgY29tcGxldGUuCisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOb3ROdWxsKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG93bmxvYWRQZW5kaW5nR3JvdXBfd2l0aEZhaWxpbmdDdXN0b21WYWxpZGF0b3IoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSAxIGdyb3VwIHRvIHRoZSBwZW5kaW5nIHNoYXJlZCBwcmVmcy4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIFRFU1RfR1JPVVAsCisgICAgICAgICAgICAvKmZpbGVDb3VudD0qLyAyLAorICAgICAgICAgICAgLypkb3dubG9hZEF0dGVtcHRDb3VudD0qLyAzLAorICAgICAgICAgICAgLypuZXdGaWxlc1JlY2VpdmVkVGltZXN0YW1wPSovIHRlc3RDbG9jay5jdXJyZW50VGltZU1pbGxpcygpIC0gNTAwTCk7CisgICAgRXh0cmFIdHRwSGVhZGVyIGV4dHJhSHR0cEhlYWRlciA9CisgICAgICAgIEV4dHJhSHR0cEhlYWRlci5uZXdCdWlsZGVyKCkuc2V0S2V5KCJ1c2VyLWFnZW50Iikuc2V0VmFsdWUoIm1kZC1kb3dubG9hZGVyIikuYnVpbGQoKTsKKworICAgIGZpbGVHcm91cCA9CisgICAgICAgIGZpbGVHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5zZXRUcmFmZmljVGFnKFRSQUZGSUNfVEFHKQorICAgICAgICAgICAgLmFkZEdyb3VwRXh0cmFIdHRwSGVhZGVycyhleHRyYUh0dHBIZWFkZXIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZmlsZUdyb3VwKTsKKworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICBBc3luY0Z1bmN0aW9uPERhdGFGaWxlR3JvdXBJbnRlcm5hbCwgQm9vbGVhbj4gZmFpbGluZ1ZhbGlkYXRvciA9CisgICAgICAgIHVudXNlZCAtPiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmYWxzZSk7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgZmlsZUdyb3VwTWFuYWdlci5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIHRlc3RLZXksIERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgZmFpbGluZ1ZhbGlkYXRvcik7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXhjZXB0aW9uID0gYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgZG93bmxvYWRGdXR1cmU6OmdldCk7CisgICAgYXNzZXJ0VGhhdChleGNlcHRpb24pLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gY2F1c2UgPSAoRG93bmxvYWRFeGNlcHRpb24pIGV4Y2VwdGlvbi5nZXRDYXVzZSgpOworICAgIGFzc2VydFRoYXQoY2F1c2UpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoY2F1c2UpLmhhc01lc3NhZ2VUaGF0KCkuY29udGFpbnMoIkNVU1RPTV9GSUxFR1JPVVBfVkFMSURBVElPTl9GQUlMRUQiKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHBlbmRpbmcga2V5IHdhcyByZW1vdmVkLiBUaGlzIHdpbGwgZW5zdXJlIHRoZSBmaWxlcyBhcmUgZWxpZ2libGUgZm9yIGdhcmJhZ2UKKyAgICAvLyBjb2xsZWN0aW9uLgorICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkRmlsZUdyb3VwX2ZhaWxlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdyaXRlIDEgZ3JvdXAgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoInRlc3QtdmFyaWFudCIpCisgICAgICAgICAgICAuc2V0QnVpbGRJZCgxMCkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXlbXSBrZXlzID0gTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwoZmlsZUdyb3VwKTsKKyAgICBmaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZmlsZUdyb3VwKTsKKworICAgIC8vIE5vdCBhbGwgZmlsZXMgYXJlIGRvd25sb2FkZWQuCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZmlsZUdyb3VwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MsIEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKworICAgIC8vIEZpcnN0IGZpbGUgZmFpbGVkLgorICAgIFVyaSBmYWlsaW5nRmlsZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAga2V5c1swXS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgZmlsZUdyb3VwLmdldEZpbGUoMCkuZ2V0RmlsZUlkKCksCisgICAgICAgICAgICBmaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgLyogaW5zdGFuY2VJZD0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBmYWxzZSk7CisgICAgZmlsZURvd25sb2FkRmFpbHMoa2V5c1swXSwgZmFpbGluZ0ZpbGVVcmksIERvd25sb2FkUmVzdWx0Q29kZS5MT1dfRElTS19FUlJPUik7CisKKyAgICAvLyBTZWNvbmQgZmlsZSBzdWNjZWVkZWQuCisgICAgVXJpIHN1Y2NlZWRpbmdGaWxlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBrZXlzWzFdLmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBmaWxlR3JvdXAuZ2V0RmlsZSgxKS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgIGZpbGVHcm91cC5nZXRGaWxlKDEpLmdldENoZWNrc3VtKCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAvKiBpbnN0YW5jZUlkPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZhbHNlKTsKKyAgICBmaWxlRG93bmxvYWRTdWNjZWVkcyhrZXlzWzFdLCBzdWNjZWVkaW5nRmlsZVVyaSk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBmaWxlR3JvdXBNYW5hZ2VyLmRvd25sb2FkRmlsZUdyb3VwKAorICAgICAgICAgICAgdGVzdEtleSwgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXhjZXB0aW9uID0gYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgZG93bmxvYWRGdXR1cmU6OmdldCk7CisgICAgYXNzZXJ0VGhhdChleGNlcHRpb24pLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihBZ2dyZWdhdGVFeGNlcHRpb24uY2xhc3MpOworICAgIEFnZ3JlZ2F0ZUV4Y2VwdGlvbiBjYXVzZSA9IChBZ2dyZWdhdGVFeGNlcHRpb24pIGV4Y2VwdGlvbi5nZXRDYXVzZSgpOworICAgIGFzc2VydFRoYXQoY2F1c2UpLmlzTm90TnVsbCgpOworICAgIEltbXV0YWJsZUxpc3Q8VGhyb3dhYmxlPiBmYWlsdXJlcyA9IGNhdXNlLmdldEZhaWx1cmVzKCk7CisgICAgYXNzZXJ0VGhhdChmYWlsdXJlcykuaGFzU2l6ZSgxKTsKKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldCgwKSkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldCgwKSkuaGFzTWVzc2FnZVRoYXQoKS5jb250YWlucygiTE9XX0RJU0tfRVJST1IiKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBwZW5kaW5nIGdyb3VwIGlzIHN0aWxsIHBhcnQgb2YgcGVuZGluZyBncm91cHMgcHJlZnMuCisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOb3ROdWxsKCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgcGVuZGluZyBncm91cCBpcyBub3QgY2hhbmdlZCBmcm9tIHBlbmRpbmcgdG8gZG93bmxvYWRlZC4KKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkpKS5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REb3dubG9hZEZpbGVHcm91cF9mYWlsZWRXaXRoTXVsdGlwbGVFeGNlcHRpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV3JpdGUgMSBncm91cCB0byB0aGUgcGVuZGluZyBzaGFyZWQgcHJlZnMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAzKTsKKyAgICBOZXdGaWxlS2V5W10ga2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGZpbGVHcm91cCk7CisgICAgZmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cCk7CisKKyAgICAvLyBOb3QgYWxsIGZpbGVzIGFyZSBkb3dubG9hZGVkLgorICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgIEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MsCisgICAgICAgICAgICBGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTLAorICAgICAgICAgICAgRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworCisgICAgLy8gRmlyc3QgZmlsZSBzdWNjZWVkZWQuCisgICAgVXJpIHN1Y2NlZWRpbmdGaWxlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBrZXlzWzBdLmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBmaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgIGZpbGVHcm91cC5nZXRGaWxlKDApLmdldENoZWNrc3VtKCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAvKiBpbnN0YW5jZUlkPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZhbHNlKTsKKyAgICBmaWxlRG93bmxvYWRTdWNjZWVkcyhrZXlzWzBdLCBzdWNjZWVkaW5nRmlsZVVyaSk7CisKKyAgICAvLyBTZWNvbmQgZmlsZSBmYWlsZWQgd2l0aCBkb3dubG9hZCB0cmFuc2Zvcm0gSS9PIGVycm9yLgorICAgIFVyaSBmYWlsaW5nRmlsZVVyaTEgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE9uRGV2aWNlVXJpKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIGtleXNbMV0uZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgIGZpbGVHcm91cC5nZXRGaWxlKDEpLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgZmlsZUdyb3VwLmdldEZpbGUoMSkuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgZmFsc2UpOworICAgIGZpbGVEb3dubG9hZEZhaWxzKGtleXNbMV0sIGZhaWxpbmdGaWxlVXJpMSwgRG93bmxvYWRSZXN1bHRDb2RlLkRPV05MT0FEX1RSQU5TRk9STV9JT19FUlJPUik7CisKKyAgICAvLyBUaGlyZCBmaWxlIGZhaWxlZCB3aXRoIGFuZHJvaWQgZG93bmxvYWRlciBodHRwIGVycm9yLgorICAgIFVyaSBmYWlsaW5nRmlsZVVyaTIgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE9uRGV2aWNlVXJpKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIGtleXNbMl0uZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgIGZpbGVHcm91cC5nZXRGaWxlKDIpLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgZmlsZUdyb3VwLmdldEZpbGUoMikuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgZmFsc2UpOworICAgIGZpbGVEb3dubG9hZEZhaWxzKGtleXNbMl0sIGZhaWxpbmdGaWxlVXJpMiwgRG93bmxvYWRSZXN1bHRDb2RlLkFORFJPSURfRE9XTkxPQURFUl9IVFRQX0VSUk9SKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8RGF0YUZpbGVHcm91cEludGVybmFsPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIGZpbGVHcm91cE1hbmFnZXIuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICB0ZXN0S2V5LCBEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCksIG5vQ3VzdG9tVmFsaWRhdGlvbigpKTsKKworICAgIC8vIEVuc3VyZSB0aGF0IGFsbCBleGNlcHRpb25zIGFyZSBhZ2dyZWdhdGVkLgorICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleGNlcHRpb24gPSBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCBkb3dubG9hZEZ1dHVyZTo6Z2V0KTsKKyAgICBhc3NlcnRUaGF0KGV4Y2VwdGlvbikuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKEFnZ3JlZ2F0ZUV4Y2VwdGlvbi5jbGFzcyk7CisgICAgQWdncmVnYXRlRXhjZXB0aW9uIGNhdXNlID0gKEFnZ3JlZ2F0ZUV4Y2VwdGlvbikgZXhjZXB0aW9uLmdldENhdXNlKCk7CisgICAgYXNzZXJ0VGhhdChjYXVzZSkuaXNOb3ROdWxsKCk7CisgICAgSW1tdXRhYmxlTGlzdDxUaHJvd2FibGU+IGZhaWx1cmVzID0gY2F1c2UuZ2V0RmFpbHVyZXMoKTsKKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzKS5oYXNTaXplKDIpOworICAgIGFzc2VydFRoYXQoZmFpbHVyZXMuZ2V0KDApKS5pc0luc3RhbmNlT2YoRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIGFzc2VydFRoYXQoZmFpbHVyZXMuZ2V0KDApKS5oYXNNZXNzYWdlVGhhdCgpLmNvbnRhaW5zKCJET1dOTE9BRF9UUkFOU0ZPUk1fSU9fRVJST1IiKTsKKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldCgxKSkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBhc3NlcnRUaGF0KGZhaWx1cmVzLmdldCgxKSkuaGFzTWVzc2FnZVRoYXQoKS5jb250YWlucygiQU5EUk9JRF9ET1dOTE9BREVSX0hUVFBfRVJST1IiKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBwZW5kaW5nIGdyb3VwIGlzIHN0aWxsIHBhcnQgb2YgcGVuZGluZyBncm91cHMgcHJlZnMuCisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOb3ROdWxsKCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgcGVuZGluZyBncm91cCBpcyBub3QgY2hhbmdlZCBmcm9tIHBlbmRpbmcgdG8gZG93bmxvYWRlZC4KKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkpKS5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REb3dubG9hZEZpbGVHcm91cF9mYWlsZWRXaXRoVW5rbm93bkVycm9yKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV3JpdGUgMSBncm91cCB0byB0aGUgcGVuZGluZyBzaGFyZWQgcHJlZnMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICBOZXdGaWxlS2V5W10ga2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGZpbGVHcm91cCk7CisgICAgZmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cCk7CisKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUywgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworCisgICAgLy8gRmlyc3QgZmlsZSBmYWlsZWQuCisgICAgVXJpIGZhaWxpbmdGaWxlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBrZXlzWzBdLmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBmaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgIGZpbGVHcm91cC5nZXRGaWxlKDApLmdldENoZWNrc3VtKCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAvKiBpbnN0YW5jZUlkPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZhbHNlKTsKKyAgICAvLyBUaGUgZmlsZSBzdGF0dXMgaXMgc2V0IHRvIERPV05MT0FEX0ZBSUxFRCBidXQgdGhlIGRvd25sb2FkZXIgcmV0dXJucyBhbiBpbW1lZGlhdGVWb2lkRnV0dXJlLgorICAgIC8vIEFuIFVOS05PV05fRVJST1IgaXMgbG9nZ2VkLgorICAgIGZpbGVEb3dubG9hZEZhaWxzKGtleXNbMF0sIGZhaWxpbmdGaWxlVXJpLCAvKiBmYWlsdXJlQ29kZSA9ICovIG51bGwpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgZmlsZUdyb3VwTWFuYWdlci5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIHRlc3RLZXksIERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpOworCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4Y2VwdGlvbiA9IGFzc2VydFRocm93cyhFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsIGRvd25sb2FkRnV0dXJlOjpnZXQpOworICAgIGFzc2VydFRoYXQoZXhjZXB0aW9uKS5oYXNNZXNzYWdlVGhhdCgpLmNvbnRhaW5zKCJVTktOT1dOX0VSUk9SIik7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgcGVuZGluZyBncm91cCBpcyBzdGlsbCBwYXJ0IG9mIHBlbmRpbmcgZ3JvdXBzIHByZWZzLgorICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzTm90TnVsbCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIHBlbmRpbmcgZ3JvdXAgaXMgbm90IGNoYW5nZWQgZnJvbSBwZW5kaW5nIHRvIGRvd25sb2FkZWQuCisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOdWxsKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG93bmxvYWRGaWxlR3JvdXBfcGVuZGluZygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdyaXRlIDEgZ3JvdXAgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgZmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cCk7CisKKyAgICAvLyBOb3QgYWxsIGZpbGVzIGFyZSBkb3dubG9hZGVkLgorICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisKKyAgICB3aGVuKG1vY2tEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoCisgICAgICAgICAgICBhbnkoR3JvdXBLZXkuY2xhc3MpLAorICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICBhbnlMb25nKCksCisgICAgICAgICAgICBhbnkoVXJpLmNsYXNzKSwKKyAgICAgICAgICAgIGFueShTdHJpbmcuY2xhc3MpLAorICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICBhbnkoRG93bmxvYWRDb25kaXRpb25zLmNsYXNzKSwKKyAgICAgICAgICAgIGlzQShEb3dubG9hZGVyQ2FsbGJhY2tJbXBsLmNsYXNzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55TGlzdCgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgZmlsZUdyb3VwTWFuYWdlci5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIHRlc3RLZXksIERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpOworCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4Y2VwdGlvbiA9IGFzc2VydFRocm93cyhFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsIGRvd25sb2FkRnV0dXJlOjpnZXQpOworICAgIGFzc2VydFRoYXQoZXhjZXB0aW9uKS5oYXNNZXNzYWdlVGhhdCgpLmNvbnRhaW5zKCJVTktOT1dOX0VSUk9SIik7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgcGVuZGluZyBncm91cCBpcyBzdGlsbCBwYXJ0IG9mIHBlbmRpbmcgZ3JvdXBzIHByZWZzLgorICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzTm90TnVsbCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIHBlbmRpbmcgZ3JvdXAgaXMgbm90IGNoYW5nZWQgZnJvbSBwZW5kaW5nIHRvIGRvd25sb2FkZWQuCisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOdWxsKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG93bmxvYWRGaWxlR3JvdXBfYWxyZWFkeURvd25sb2FkZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSAxIGdyb3VwIHRvIHRoZSBkb3dubG9hZGVkIHNoYXJlZCBwcmVmcy4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIGZpbGVHcm91cCA9CisgICAgICAgIGZpbGVHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5LCBmaWxlR3JvdXApOworCisgICAgTGlzdDxHcm91cEtleT4gb3JpZ2luYWxLZXlzID0gZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEdyb3VwS2V5cygpLmdldCgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgZmlsZUdyb3VwTWFuYWdlci5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIHRlc3RLZXksIERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpOworCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZEZ1dHVyZS5nZXQoKSkuaXNFcXVhbFRvKGZpbGVHcm91cCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgZG93bmxvYWRlZCBncm91cCBpcyBzdGlsbCBwYXJ0IG9mIGRvd25sb2FkZWQgZ3JvdXBzIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkR3JvdXAgPSByZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5KTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRHcm91cCkuaXNFcXVhbFRvKGZpbGVHcm91cCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBubyBncm91cCBtZXRhZGF0YSBpcyB3cml0dGVuIG9yIHJlbW92ZWQuCisgICAgYXNzZXJ0VGhhdChvcmlnaW5hbEtleXMpLmlzRXF1YWxUbyhmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsR3JvdXBLZXlzKCkuZ2V0KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkRmlsZUdyb3VwX251bGxEb3dubG9hZENvbmRpdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMgPQorICAgICAgICBEb3dubG9hZENvbmRpdGlvbnMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGV2aWNlTmV0d29ya1BvbGljeShEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSkKKyAgICAgICAgICAgIC5zZXREZXZpY2VTdG9yYWdlUG9saWN5KERldmljZVN0b3JhZ2VQb2xpY3kuQkxPQ0tfRE9XTkxPQURfSU5fTE9XX1NUT1JBR0UpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIFdyaXRlIDEgZ3JvdXAgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoZG93bmxvYWRDb25kaXRpb25zKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cCk7CisKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUywgRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworCisgICAgQXJndW1lbnRDYXB0b3I8RG93bmxvYWRDb25kaXRpb25zPiBkb3dubG9hZENvbmRpdGlvbnNDYXB0b3IgPQorICAgICAgICBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhEb3dubG9hZENvbmRpdGlvbnMuY2xhc3MpOworICAgIHdoZW4obW9ja0Rvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIGFueShHcm91cEtleS5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueUxvbmcoKSwKKyAgICAgICAgICAgIGFueShVcmkuY2xhc3MpLAorICAgICAgICAgICAgYW55KFN0cmluZy5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGRvd25sb2FkQ29uZGl0aW9uc0NhcHRvci5jYXB0dXJlKCksCisgICAgICAgICAgICBpc0EoRG93bmxvYWRlckNhbGxiYWNrSW1wbC5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueUxpc3QoKSkpCisgICAgICAgIC50aGVuKAorICAgICAgICAgICAgbmV3IEFuc3dlcjxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PigpIHsKKyAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGFuc3dlcihJbnZvY2F0aW9uT25Nb2NrIGludm9jYXRpb24pIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCB1cGRhdGVkRmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICAgICAgRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRTdGFydGVkQ291bnQoMSkKKyAgICAgICAgICAgICAgICAgICAgLnNldEdyb3VwRG93bmxvYWRTdGFydGVkVGltZXN0YW1wSW5NaWxsaXMoMTAwMEwpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBDYWxsaW5nIHdpdGggRG93bmxvYWRDb25kaXRpb25zID0gbnVsbCB3aWxsIHVzZSB0aGUgY29uZmlnIGZyb20gc2VydmVyLgorICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgICAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKHRlc3RLZXksIG51bGwgLypkb3dubG9hZENvbmRpdGlvbnMqLywgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNFcXVhbFRvKHVwZGF0ZWRGaWxlR3JvdXApOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRDb25kaXRpb25zQ2FwdG9yLmdldFZhbHVlKCkpLmlzRXF1YWxUbyhkb3dubG9hZENvbmRpdGlvbnMpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkRmlsZUdyb3VwX25vbk51bGxEb3dubG9hZENvbmRpdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMgPQorICAgICAgICBEb3dubG9hZENvbmRpdGlvbnMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGV2aWNlTmV0d29ya1BvbGljeShEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OTFlfT05fV0lGSSkKKyAgICAgICAgICAgIC5zZXREZXZpY2VTdG9yYWdlUG9saWN5KERldmljZVN0b3JhZ2VQb2xpY3kuQkxPQ0tfRE9XTkxPQURfSU5fTE9XX1NUT1JBR0UpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIFdyaXRlIDEgZ3JvdXAgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoZG93bmxvYWRDb25kaXRpb25zKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cCk7CisKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUywgRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworCisgICAgQXJndW1lbnRDYXB0b3I8RG93bmxvYWRDb25kaXRpb25zPiBkb3dubG9hZENvbmRpdGlvbnNDYXB0b3IgPQorICAgICAgICBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhEb3dubG9hZENvbmRpdGlvbnMuY2xhc3MpOworICAgIHdoZW4obW9ja0Rvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIGFueShHcm91cEtleS5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueUxvbmcoKSwKKyAgICAgICAgICAgIGFueShVcmkuY2xhc3MpLAorICAgICAgICAgICAgYW55KFN0cmluZy5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGRvd25sb2FkQ29uZGl0aW9uc0NhcHRvci5jYXB0dXJlKCksCisgICAgICAgICAgICBpc0EoRG93bmxvYWRlckNhbGxiYWNrSW1wbC5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueUxpc3QoKSkpCisgICAgICAgIC50aGVuKAorICAgICAgICAgICAgbmV3IEFuc3dlcjxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PigpIHsKKyAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGFuc3dlcihJbnZvY2F0aW9uT25Nb2NrIGludm9jYXRpb24pIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9KTsKKworICAgIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMyID0KKyAgICAgICAgRG93bmxvYWRDb25kaXRpb25zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERldmljZU5ldHdvcmtQb2xpY3koRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSykKKyAgICAgICAgICAgIC5zZXREZXZpY2VTdG9yYWdlUG9saWN5KERldmljZVN0b3JhZ2VQb2xpY3kuQkxPQ0tfRE9XTkxPQURfSU5fTE9XX1NUT1JBR0UpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCB1cGRhdGVkRmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICAgICAgRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRTdGFydGVkQ291bnQoMSkKKyAgICAgICAgICAgICAgICAgICAgLnNldEdyb3VwRG93bmxvYWRTdGFydGVkVGltZXN0YW1wSW5NaWxsaXMoMTAwMEwpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBkb3dubG9hZENvbmRpdGlvbnMyIHdpbGwgb3ZlcnJpZGUgdGhlIHBlbmRpbmdHcm91cC5kb3dubG9hZENvbmRpdGlvbnMKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCh0ZXN0S2V5LCBkb3dubG9hZENvbmRpdGlvbnMyLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc0VxdWFsVG8odXBkYXRlZEZpbGVHcm91cCk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZENvbmRpdGlvbnNDYXB0b3IuZ2V0VmFsdWUoKSkuaXNFcXVhbFRvKGRvd25sb2FkQ29uZGl0aW9uczIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkRmlsZUdyb3VwX25vdEZvdW5kR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNb2NrIEZpbGVHcm91cHNNZXRhZGF0YSB0byB0ZXN0IGZhaWx1cmUgc2NlbmFyaW8uCisgICAgcmVzZXRGaWxlR3JvdXBNYW5hZ2VyKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsIHNoYXJlZEZpbGVNYW5hZ2VyKTsKKyAgICAvLyBDYW4ndCBmaW5kIHRoZSBncm91cC4KKyAgICBBcmd1bWVudENhcHRvcjxHcm91cEtleT4gZ3JvdXBLZXlDYXB0b3IgPSBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhHcm91cEtleS5jbGFzcyk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZ3JvdXBLZXlDYXB0b3IuY2FwdHVyZSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworCisgICAgLy8gRG93bmxvYWQgbm90LWZvdW5kIGdyb3VwIHdpbGwgbGVhZCB0byBmYWlsZWQgZnV0dXJlLgorICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleGNlcHRpb24gPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgICAgICAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKHRlc3RLZXksIG51bGwgLypkb3dubG9hZENvbmRpdGlvbnMqLywgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoKSk7CisgICAgYXNzZXJ0VGhhdChleGNlcHRpb24pLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisKKyAgICAvLyBNYWtlIHN1cmUgdGhhdCBmaWxlIGdyb3VwIG1hbmFnZXIgYXR0ZW1wdGVkIHRvIHJlYWQgYm90aCBwZW5kaW5nIGtleSBhbmQgZG93bmxvYWRlZCBrZXkuCisgICAgYXNzZXJ0VGhhdChncm91cEtleUNhcHRvci5nZXRBbGxWYWx1ZXMoKSkKKyAgICAgICAgLmNvbnRhaW5zQXRMZWFzdChnZXRQZW5kaW5nS2V5KHRlc3RLZXkpLCBnZXREb3dubG9hZGVkS2V5KHRlc3RLZXkpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REb3dubG9hZEZpbGVHcm91cF9kb3dubG9hZFN0YXJ0ZWRUaW1lc3RhbXBBYnNlbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSAxIGdyb3VwIHRvIHRoZSBwZW5kaW5nIHNoYXJlZCBwcmVmcy4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIGZpbGVHcm91cCA9CisgICAgICAgIGZpbGVHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5zZXRUcmFmZmljVGFnKFRSQUZGSUNfVEFHKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cCk7CisKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworCisgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAodGVzdEtleSwgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nIGJvb2trZWVwaW5nID0gcmVhZERvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleSkuZ2V0Qm9va2tlZXBpbmcoKTsKKyAgICBhc3NlcnRUaGF0KGJvb2trZWVwaW5nLmhhc0dyb3VwRG93bmxvYWRTdGFydGVkVGltZXN0YW1wSW5NaWxsaXMoKSkuaXNUcnVlKCk7CisgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGRvd25sb2FkIHN0YXJ0ZWQgdGltZXN0YW1wIGlzIHNldCB0byBjdXJyZW50IHRpbWUuCisgICAgYXNzZXJ0VGhhdChib29ra2VlcGluZy5nZXRHcm91cERvd25sb2FkU3RhcnRlZFRpbWVzdGFtcEluTWlsbGlzKCkpCisgICAgICAgIC5pc0VxdWFsVG8odGVzdENsb2NrLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBkb3dubG9hZCBzdGFydGVkIGNvdW50IGlzIGFjY3VtdWxhdGVkLgorICAgIGFzc2VydFRoYXQoYm9va2tlZXBpbmcuZ2V0RG93bmxvYWRTdGFydGVkQ291bnQoKSkuaXNFcXVhbFRvKDEpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkRmlsZUdyb3VwX2Rvd25sb2FkU3RhcnRlZFRpbWVzdGFtcFByZXNlbnQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSAxIGdyb3VwIHRvIHRoZSBwZW5kaW5nIHNoYXJlZCBwcmVmcy4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworCisgICAgZmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLnNldFRyYWZmaWNUYWcoVFJBRkZJQ19UQUcpCisgICAgICAgICAgICAuc2V0Qm9va2tlZXBpbmcoCisgICAgICAgICAgICAgICAgRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBEb3dubG9hZFN0YXJ0ZWRUaW1lc3RhbXBJbk1pbGxpcygxMjM0NTYpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFN0YXJ0ZWRDb3VudCgyKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5LCBmaWxlR3JvdXApOworCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZmlsZUdyb3VwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKHRlc3RLZXksIERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIERhdGFGaWxlR3JvdXBCb29ra2VlcGluZyBib29ra2VlcGluZyA9IHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkpLmdldEJvb2trZWVwaW5nKCk7CisgICAgYXNzZXJ0VGhhdChib29ra2VlcGluZy5oYXNHcm91cERvd25sb2FkU3RhcnRlZFRpbWVzdGFtcEluTWlsbGlzKCkpLmlzVHJ1ZSgpOworICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBkb3dubG9hZCBzdGFydGVkIHRpbWVzdGFtcCBpcyBub3QgY2hhbmdlZC4KKyAgICBhc3NlcnRUaGF0KGJvb2trZWVwaW5nLmdldEdyb3VwRG93bmxvYWRTdGFydGVkVGltZXN0YW1wSW5NaWxsaXMoKSkuaXNFcXVhbFRvKDEyMzQ1Nik7CisgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGRvd25sb2FkIHN0YXJ0ZWQgY291bnQgaXMgYWNjdW11bGF0ZWQuCisgICAgYXNzZXJ0VGhhdChib29ra2VlcGluZy5nZXREb3dubG9hZFN0YXJ0ZWRDb3VudCgpKS5pc0VxdWFsVG8oMyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG93bmxvYWRGaWxlR3JvdXBfdXBkYXRlQm9va2tlZXBpbmdPbkRvd25sb2FkRmFpbGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gTW9jayBGaWxlR3JvdXBzTWV0YWRhdGEgdG8gdGVzdCBmYWlsdXJlIHNjZW5hcmlvLgorICAgIHJlc2V0RmlsZUdyb3VwTWFuYWdlcihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLCBzaGFyZWRGaWxlTWFuYWdlcik7CisgICAgLy8gV3JpdGUgMSBncm91cCB0byB0aGUgcGVuZGluZyBzaGFyZWQgcHJlZnMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICBmaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuc2V0VHJhZmZpY1RhZyhUUkFGRklDX1RBRykKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEdyb3VwS2V5IHBlbmRpbmdLZXkgPSB0ZXN0S2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQocGVuZGluZ0tleSkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmlsZUdyb3VwKSk7CisKKyAgICAvLyBBbGwgZmlsZXMgYXJlIGRvd25sb2FkZWQuCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZmlsZUdyb3VwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIEFyZ3VtZW50Q2FwdG9yPERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZmlsZUdyb3VwQ2FwdG9yID0KKyAgICAgICAgQXJndW1lbnRDYXB0b3IuZm9yQ2xhc3MoRGF0YUZpbGVHcm91cEludGVybmFsLmNsYXNzKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUoZXEocGVuZGluZ0tleSksIGZpbGVHcm91cENhcHRvci5jYXB0dXJlKCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmYWxzZSkpOworCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4ZWN1dGlvbkV4Y2VwdGlvbiA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0S2V5LCBEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCksIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAgICAgICAgICAgICAuZ2V0KCkpOworICAgIGFzc2VydFRoYXQoZXhlY3V0aW9uRXhjZXB0aW9uKS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoRG93bmxvYWRFeGNlcHRpb24uY2xhc3MpOworICAgIERvd25sb2FkRXhjZXB0aW9uIGRvd25sb2FkRXhjZXB0aW9uID0gKERvd25sb2FkRXhjZXB0aW9uKSBleGVjdXRpb25FeGNlcHRpb24uZ2V0Q2F1c2UoKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkRXhjZXB0aW9uKS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoSU9FeGNlcHRpb24uY2xhc3MpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRFeGNlcHRpb24uZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpCisgICAgICAgIC5pc0VxdWFsVG8oRG93bmxvYWRSZXN1bHRDb2RlLlVOQUJMRV9UT19VUERBVEVfR1JPVVBfTUVUQURBVEFfRVJST1IpOworCisgICAgRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nIGJvb2trZWVwaW5nID0gZmlsZUdyb3VwQ2FwdG9yLmdldFZhbHVlKCkuZ2V0Qm9va2tlZXBpbmcoKTsKKyAgICBhc3NlcnRUaGF0KGJvb2trZWVwaW5nLmhhc0dyb3VwRG93bmxvYWRTdGFydGVkVGltZXN0YW1wSW5NaWxsaXMoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChib29ra2VlcGluZy5nZXRHcm91cERvd25sb2FkU3RhcnRlZFRpbWVzdGFtcEluTWlsbGlzKCkpCisgICAgICAgIC5pc0VxdWFsVG8odGVzdENsb2NrLmN1cnJlbnRUaW1lTWlsbGlzKCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkVG9CZVNoYXJlZFBlbmRpbmdHcm91cF9zdWNjZXNzX2xvd1Nka19ub3RTaGFyZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBSZWZsZWN0aW9uSGVscGVycy5zZXRTdGF0aWNGaWVsZChCdWlsZC5WRVJTSU9OLmNsYXNzLCAiU0RLX0lOVCIsIEJ1aWxkLlZFUlNJT05fQ09ERVMuUiAtIDEpOworICAgIC8vIFdyaXRlIDEgZ3JvdXAgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgICAgICAgVEVTVF9HUk9VUCwKKyAgICAgICAgICAgIC8qZmlsZUNvdW50PSovIDAsCisgICAgICAgICAgICAvKmRvd25sb2FkQXR0ZW1wdENvdW50PSovIDMsCisgICAgICAgICAgICAvKm5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXA9Ki8gdGVzdENsb2NrLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSA1MDBMKTsKKyAgICBFeHRyYUh0dHBIZWFkZXIgZXh0cmFIdHRwSGVhZGVyID0KKyAgICAgICAgRXh0cmFIdHRwSGVhZGVyLm5ld0J1aWxkZXIoKS5zZXRLZXkoInVzZXItYWdlbnQiKS5zZXRWYWx1ZSgibWRkLWRvd25sb2FkZXIiKS5idWlsZCgpOworCisgICAgZmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLnNldFRyYWZmaWNUYWcoVFJBRkZJQ19UQUcpCisgICAgICAgICAgICAuYWRkR3JvdXBFeHRyYUh0dHBIZWFkZXJzKGV4dHJhSHR0cEhlYWRlcikKKyAgICAgICAgICAgIC5hZGRGaWxlKDAsIE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKFRFU1RfR1JPVVAsIDApKQorICAgICAgICAgICAgLmFkZEZpbGUoMSwgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoVEVTVF9HUk9VUCwgMSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZmlsZUdyb3VwKTsKKworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCh0ZXN0S2V5LCBEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCksIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAuZ2V0KCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBwZW5kaW5nIGtleSBpcyByZW1vdmVkIGlmIGRvd25sb2FkIGlzIGNvbXBsZXRlLgorICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzTnVsbCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgZG93bmxvYWRlZCBrZXkgaXMgd3JpdHRlbiBpbnRvIG1ldGFkYXRhIGlmIGRvd25sb2FkIGlzIGNvbXBsZXRlLgorICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleSkpLmlzTm90TnVsbCgpOworCisgICAgLy8gZXhpc3RzIG9ubHkgY2FsbGVkIG9uY2UgaW4gdHJ5VG9TaGFyZUJlZm9yZURvd25sb2FkCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5leGlzdHMoYW55KCkpOworICAgIC8vIG9wZW5Gb3JXcml0ZSBpcyBjYWxsZWQgaW4gdHJ5VG9TaGFyZUJlZm9yZURvd25sb2FkIGZvciBjb3B5aW5nIHRoZSBmaWxlIGFuZCBhY3F1aXJpbmcgdGhlCisgICAgLy8gbGVhc2UuCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5vcGVuRm9yV3JpdGUoYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkRmlsZUdyb3VwX3N1Y2Nlc3Nfb25lRmlsZUFuZHJvaWRTaGFyZWRBbmREb3dubG9hZGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV3JpdGUgMSBncm91cCB0byB0aGUgcGVuZGluZyBzaGFyZWQgcHJlZnMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFZhcmlhbnRJZCgidGVzdC12YXJpYW50IikKKyAgICAgICAgICAgIC5zZXRCdWlsZElkKDEwKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgTmV3RmlsZUtleVtdIGtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChmaWxlR3JvdXApOworICAgIEV4dHJhSHR0cEhlYWRlciBleHRyYUh0dHBIZWFkZXIgPQorICAgICAgICBFeHRyYUh0dHBIZWFkZXIubmV3QnVpbGRlcigpLnNldEtleSgidXNlci1hZ2VudCIpLnNldFZhbHVlKCJtZGQtZG93bmxvYWRlciIpLmJ1aWxkKCk7CisKKyAgICBmaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuc2V0VHJhZmZpY1RhZyhUUkFGRklDX1RBRykKKyAgICAgICAgICAgIC5hZGRHcm91cEV4dHJhSHR0cEhlYWRlcnMoZXh0cmFIdHRwSGVhZGVyKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cCk7CisKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSksCisgICAgICAgIC8qIGFuZHJvaWRTaGFyZWQgKi8gSW1tdXRhYmxlTGlzdC5vZih0cnVlLCBmYWxzZSkpOworCisgICAgU2hhcmVkRmlsZSBmaWxlMCA9IHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoa2V5c1swXSkuZ2V0KCk7CisgICAgU2hhcmVkRmlsZSBmaWxlMSA9IHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoa2V5c1sxXSkuZ2V0KCk7CisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgZmlsZTAuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpKTsKKyAgICBVcmkgbGVhc2VVcmkgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldEJsb2JTdG9yZUxlYXNlVXJpKGNvbnRleHQsIGZpbGUwLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwgMCk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCh0ZXN0S2V5LCBEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCksIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAuZ2V0KCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBwZW5kaW5nIGtleSBpcyByZW1vdmVkIGlmIGRvd25sb2FkIGlzIGNvbXBsZXRlLgorICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzTnVsbCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgZG93bmxvYWRlZCBrZXkgaXMgd3JpdHRlbiBpbnRvIG1ldGFkYXRhIGlmIGRvd25sb2FkIGlzIGNvbXBsZXRlLgorICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleSkpLmlzTm90TnVsbCgpOworCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5leGlzdHMoYmxvYlVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5vcGVuRm9yV3JpdGUoYmxvYlVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5vcGVuRm9yV3JpdGUobGVhc2VVcmkpOworCisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKGtleXNbMF0pLmdldCgpKS5pc0VxdWFsVG8oZmlsZTApOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShrZXlzWzFdKS5nZXQoKSkuaXNFcXVhbFRvKGZpbGUxKTsKKworICAgIEFyZ3VtZW50Q2FwdG9yPFZvaWQ+IG1kZEFuZHJvaWRTaGFyaW5nTG9nQXJndW1lbnRDYXB0b3IgPSBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhWb2lkLmNsYXNzKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REb3dubG9hZEZpbGVHcm91cF9wZW5kaW5nX29uZUJsb2JFeGlzdHNCZWZvcmVEb3dubG9hZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdyaXRlIDEgZ3JvdXAgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMCk7CisgICAgRXh0cmFIdHRwSGVhZGVyIGV4dHJhSHR0cEhlYWRlciA9CisgICAgICAgIEV4dHJhSHR0cEhlYWRlci5uZXdCdWlsZGVyKCkuc2V0S2V5KCJ1c2VyLWFnZW50Iikuc2V0VmFsdWUoIm1kZC1kb3dubG9hZGVyIikuYnVpbGQoKTsKKworICAgIGZpbGVHcm91cCA9CisgICAgICAgIGZpbGVHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5zZXRFeHBpcmF0aW9uRGF0ZVNlY3MoRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUykKKyAgICAgICAgICAgIC5zZXRUcmFmZmljVGFnKFRSQUZGSUNfVEFHKQorICAgICAgICAgICAgLmFkZEdyb3VwRXh0cmFIdHRwSGVhZGVycyhleHRyYUh0dHBIZWFkZXIpCisgICAgICAgICAgICAuYWRkRmlsZSgwLCBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZShURVNUX0dST1VQLCAwKSkKKyAgICAgICAgICAgIC5hZGRGaWxlKDEsIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKFRFU1RfR1JPVVAsIDEpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBOZXdGaWxlS2V5W10ga2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGZpbGVHcm91cCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cCk7CisKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUywgRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworCisgICAgLy8gRmlsZSB0aGF0IGNhbiBiZSBzaGFyZWQKKyAgICBEYXRhRmlsZSBmaWxlID0gZmlsZUdyb3VwLmdldEZpbGUoMCk7CisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCkpOworICAgIFVyaSBsZWFzZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0QmxvYlN0b3JlTGVhc2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyk7CisgICAgLy8gVGhlIGZpbGUgaXMgYXZhaWxhYmxlIGluIHRoZSBibG9iIHN0b3JhZ2UKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmV4aXN0cyhibG9iVXJpKSkudGhlblJldHVybih0cnVlKTsKKworICAgIC8vIEZpcnN0IGZpbGUncyBkb3dubG9hZCBzdWNjZWVkcworICAgIFVyaSBvbkRldmljZXVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAga2V5c1swXS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgZmlsZS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgIGtleXNbMF0uZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKyAgICBmaWxlRG93bmxvYWRTdWNjZWVkcyhrZXlzWzBdLCBvbkRldmljZXVyaSk7CisKKyAgICAvLyBTZWNvbmQgZmlsZSdzIGRvd25sb2FkIHN1Y2NlZWRzCisgICAgb25EZXZpY2V1cmkgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE9uRGV2aWNlVXJpKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIGtleXNbMV0uZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgIGZpbGVHcm91cC5nZXRGaWxlKDEpLmdldEZpbGVJZCgpLAorICAgICAgICAgICAga2V5c1sxXS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgLyogaW5zdGFuY2VJZD0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAvKiBhbmRyb2lkU2hhcmVkID0gKi8gZmFsc2UpOworICAgIGZpbGVEb3dubG9hZFN1Y2NlZWRzKGtleXNbMV0sIG9uRGV2aWNldXJpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKHRlc3RLZXksIERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBwZW5kaW5nIGdyb3VwIGlzIG5vdCBwYXJ0IG9mIHBlbmRpbmcgZ3JvdXBzIHByZWZzLgorICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzTnVsbCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGRvd25sb2FkZWQgZ3JvdXAgaXMgc3RpbGwgcGFydCBvZiBkb3dubG9hZGVkIGdyb3VwcyBwcmVmcy4KKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkpKS5pc05vdE51bGwoKTsKKworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZXhpc3RzKGJsb2JVcmkpOworICAgIC8vIG9wZW5Gb3JXcml0ZSBpcyBjYWxsZWQgb25seSBvbmNlIGluIHRyeVRvU2hhcmVCZWZvcmVEb3dubG9hZCBmb3IgYWNxdWlyaW5nIHRoZSBsZWFzZS4KKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLm9wZW5Gb3JXcml0ZShibG9iVXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLm9wZW5Gb3JXcml0ZShsZWFzZVVyaSk7CisKKyAgICBTaGFyZWRGaWxlIGV4cGVjdGVkU2hhcmVkRmlsZTAgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJhbmRyb2lkX3NoYXJlZF9zaGEyNTZfMTIzMCIpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyZWQodHJ1ZSkKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCJzaGEyNTZfMTIzMCIpCisgICAgICAgICAgICAuc2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBTaGFyZWRGaWxlIGV4cGVjdGVkU2hhcmVkRmlsZTEgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKGZpbGVHcm91cC5nZXRGaWxlKDEpLmdldEZpbGVJZCgpKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgIC5zZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUykKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShrZXlzWzBdKS5nZXQoKSkuaXNFcXVhbFRvKGV4cGVjdGVkU2hhcmVkRmlsZTApOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShrZXlzWzFdKS5nZXQoKSkuaXNFcXVhbFRvKGV4cGVjdGVkU2hhcmVkRmlsZTEpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkRmlsZUdyb3VwX3BlbmRpbmdfb25lQmxvYkV4aXN0c0FmdGVyRG93bmxvYWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSAxIGdyb3VwIHRvIHRoZSBwZW5kaW5nIHNoYXJlZCBwcmVmcy4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgdG1wRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDApOworICAgIEV4dHJhSHR0cEhlYWRlciBleHRyYUh0dHBIZWFkZXIgPQorICAgICAgICBFeHRyYUh0dHBIZWFkZXIubmV3QnVpbGRlcigpLnNldEtleSgidXNlci1hZ2VudCIpLnNldFZhbHVlKCJtZGQtZG93bmxvYWRlciIpLmJ1aWxkKCk7CisKKyAgICBmaW5hbCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgdG1wRmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLnNldEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLnNldFRyYWZmaWNUYWcoVFJBRkZJQ19UQUcpCisgICAgICAgICAgICAuYWRkR3JvdXBFeHRyYUh0dHBIZWFkZXJzKGV4dHJhSHR0cEhlYWRlcikKKyAgICAgICAgICAgIC5hZGRGaWxlKDAsIE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKFRFU1RfR1JPVVAsIDApKQorICAgICAgICAgICAgLmFkZEZpbGUoMSwgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoVEVTVF9HUk9VUCwgMSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIE5ld0ZpbGVLZXlbXSBrZXlzID0gTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwoZmlsZUdyb3VwKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZmlsZUdyb3VwKTsKKworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTLCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICAvLyBGaWxlIHRoYXQgY2FuIGJlIHNoYXJlZAorICAgIERhdGFGaWxlIGZpbGUgPSBmaWxlR3JvdXAuZ2V0RmlsZSgwKTsKKyAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSk7CisgICAgVXJpIGxlYXNlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRCbG9iU3RvcmVMZWFzZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsIGZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLCBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKTsKKworICAgIC8vIFRoZSBmaWxlIGlzbid0IGF2YWlsYWJsZSBpbiB0aGUgYmxvYiBzdG9yYWdlIHdoZW4gdHJ5VG9TaGFyZUJlZm9yZURvd25sb2FkIGlzIGNhbGxlZAorICAgIHdoZW4obW9ja0JhY2tlbmQuZXhpc3RzKGJsb2JVcmkpKS50aGVuUmV0dXJuKGZhbHNlKTsKKworICAgIHNpbXVsYXRlRG93bmxvYWQoZmlsZSwgZmlsZS5nZXRGaWxlSWQoKSk7CisgICAgVXJpIG9uRGV2aWNldXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBrZXlzWzBdLmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBmaWxlLmdldEZpbGVJZCgpLAorICAgICAgICAgICAga2V5c1swXS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgLyogaW5zdGFuY2VJZD0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICAvKiBhbmRyb2lkU2hhcmVkID0gKi8gZmFsc2UpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKG9uRGV2aWNldXJpKSkuaXNUcnVlKCk7CisKKyAgICB3aGVuKG1vY2tEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoCisgICAgICAgICAgICBhbnkoR3JvdXBLZXkuY2xhc3MpLAorICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICBhbnlMb25nKCksCisgICAgICAgICAgICBlcShvbkRldmljZXVyaSksCisgICAgICAgICAgICBhbnkoU3RyaW5nLmNsYXNzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55KERvd25sb2FkQ29uZGl0aW9ucy5jbGFzcyksCisgICAgICAgICAgICBpc0EoRG93bmxvYWRlckNhbGxiYWNrSW1wbC5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueUxpc3QoKSkpCisgICAgICAgIC50aGVuKAorICAgICAgICAgICAgbmV3IEFuc3dlcjxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PigpIHsKKyAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGFuc3dlcihJbnZvY2F0aW9uT25Nb2NrIGludm9jYXRpb24pIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgICAgIC8vIFRoZSBmaWxlIG5vdyBleGlzdHMgaW4gdGhlIHNoYXJlZCBzdG9yYWdlCisgICAgICAgICAgICAgICAgd2hlbihtb2NrQmFja2VuZC5leGlzdHMoYmxvYlVyaSkpLnRoZW5SZXR1cm4odHJ1ZSk7CisgICAgICAgICAgICAgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwLAorICAgICAgICAgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworCisgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAodGVzdEtleSwgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgcGVuZGluZyBrZXkgaXMgcmVtb3ZlZCBpZiBkb3dubG9hZCBpcyBjb21wbGV0ZS4KKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkpKS5pc051bGwoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IGRvd25sb2FkZWQga2V5IGlzIHdyaXR0ZW4gaW50byBtZXRhZGF0YSBpZiBkb3dubG9hZCBpcyBjb21wbGV0ZS4KKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkpKS5pc05vdE51bGwoKTsKKworICAgIC8vIGV4aXN0cyBjYWxsZWQgb25jZSBpbiB0cnlUb1NoYXJlQmVmb3JlRG93bmxvYWQgYW5kIG9uY2UgaW4gdHJ5VG9TaGFyZUFmdGVyRG93bmxvYWQKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIHRpbWVzKDIpKS5leGlzdHMoYmxvYlVyaSk7CisgICAgLy8gb3BlbkZvcldyaXRlIGlzIGNhbGxlZCBvbmx5IG9uY2UgaW4gdHJ5VG9TaGFyZUFmdGVyRG93bmxvYWQgZm9yIGFjcXVpcmluZyB0aGUgbGVhc2UuCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5vcGVuRm9yV3JpdGUoYmxvYlVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5vcGVuRm9yV3JpdGUobGVhc2VVcmkpOworCisgICAgU2hhcmVkRmlsZSBleHBlY3RlZFNoYXJlZEZpbGUwID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgiYW5kcm9pZF9zaGFyZWRfc2hhMjU2XzEyMzAiKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKHRydWUpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgic2hhMjU2XzEyMzAiKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgU2hhcmVkRmlsZSBleHBlY3RlZFNoYXJlZEZpbGUxID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZShmaWxlR3JvdXAuZ2V0RmlsZSgxKS5nZXRGaWxlSWQoKSkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoa2V5c1swXSkuZ2V0KCkpLmlzRXF1YWxUbyhleHBlY3RlZFNoYXJlZEZpbGUwKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoa2V5c1sxXSkuZ2V0KCkpLmlzRXF1YWxUbyhleHBlY3RlZFNoYXJlZEZpbGUxKTsKKworICAgIC8vIHRyeVRvU2hhcmVBZnRlckRvd25sb2FkIGRlbGV0ZXMgdGhlIGZpbGUKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzRmFsc2UoKTsKKworICAgIEFyZ3VtZW50Q2FwdG9yPFZvaWQ+IG1kZEFuZHJvaWRTaGFyaW5nTG9nQXJndW1lbnRDYXB0b3IgPSBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhWb2lkLmNsYXNzKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REb3dubG9hZEZpbGVHcm91cF9zdWNjZXNzX29uZUZpbGVDYW5CZUNvcGllZEJlZm9yZURvd25sb2FkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRmlsZSB0ZW1wRmlsZSA9IGZvbGRlci5uZXdGaWxlKCJibG9iRmlsZSIpOworICAgIC8vIFdyaXRlIDEgZ3JvdXAgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMCk7CisgICAgRXh0cmFIdHRwSGVhZGVyIGV4dHJhSHR0cEhlYWRlciA9CisgICAgICAgIEV4dHJhSHR0cEhlYWRlci5uZXdCdWlsZGVyKCkuc2V0S2V5KCJ1c2VyLWFnZW50Iikuc2V0VmFsdWUoIm1kZC1kb3dubG9hZGVyIikuYnVpbGQoKTsKKworICAgIGZpbGVHcm91cCA9CisgICAgICAgIGZpbGVHcm91cC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5zZXRUcmFmZmljVGFnKFRSQUZGSUNfVEFHKQorICAgICAgICAgICAgLmFkZEdyb3VwRXh0cmFIdHRwSGVhZGVycyhleHRyYUh0dHBIZWFkZXIpCisgICAgICAgICAgICAuYWRkRmlsZSgwLCBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZShURVNUX0dST1VQLCAwKSkKKyAgICAgICAgICAgIC5hZGRGaWxlKDEsIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKFRFU1RfR1JPVVAsIDEpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgTmV3RmlsZUtleVtdIGtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChmaWxlR3JvdXApOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5LCBmaWxlR3JvdXApOworCisgICAgLy8gQWxsIGZpbGVzIGFyZSBkb3dubG9hZGVkLgorICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICBEYXRhRmlsZSBmaWxlID0gZmlsZUdyb3VwLmdldEZpbGUoMCk7CisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCkpOworICAgIFVyaSBsZWFzZVVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlN0b3JlTGVhc2VVcmkoY29udGV4dCwgZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCksIDApOworICAgIC8vIFRoZSBmaWxlIGlzbid0IGF2YWlsYWJsZSB5ZXQgaW4gdGhlIGJsb2Igc3RvcmFnZQorICAgIHdoZW4obW9ja0JhY2tlbmQuZXhpc3RzKGJsb2JVcmkpKS50aGVuUmV0dXJuKGZhbHNlKTsKKyAgICAvLyBGaWxlIHRoYXQgY2FuIGJlIGNvcGllZCB0byB0aGUgYmxvYiBzdG9yYWdlCisgICAgd2hlbihtb2NrQmFja2VuZC5vcGVuRm9yV3JpdGUoYmxvYlVyaSkpLnRoZW5SZXR1cm4obmV3IEZpbGVPdXRwdXRTdHJlYW0odGVtcEZpbGUpKTsKKworICAgIEZpbGUgb25EZXZpY2VGaWxlID0gc2ltdWxhdGVEb3dubG9hZChmaWxlLCBmaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRGaWxlSWQoKSk7CisgICAgVXJpIG9uRGV2aWNldXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBrZXlzWzBdLmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBmaWxlR3JvdXAuZ2V0RmlsZSgwKS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgIGtleXNbMF0uZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzVHJ1ZSgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAodGVzdEtleSwgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgcGVuZGluZyBrZXkgaXMgcmVtb3ZlZCBpZiBkb3dubG9hZCBpcyBjb21wbGV0ZS4KKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkpKS5pc051bGwoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IGRvd25sb2FkZWQga2V5IGlzIHdyaXR0ZW4gaW50byBtZXRhZGF0YSBpZiBkb3dubG9hZCBpcyBjb21wbGV0ZS4KKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkpKS5pc05vdE51bGwoKTsKKworICAgIC8vIGV4aXN0cyBvbmx5IGNhbGxlZCBvbmNlIGluIHRyeVRvU2hhcmVCZWZvcmVEb3dubG9hZAorICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZXhpc3RzKGJsb2JVcmkpOworICAgIC8vIG9wZW5Gb3JXcml0ZSBpcyBjYWxsZWQgaW4gdHJ5VG9TaGFyZUJlZm9yZURvd25sb2FkIGZvciBjb3B5aW5nIHRoZSBmaWxlIGFuZCBhY3F1aXJpbmcgdGhlCisgICAgLy8gbGVhc2UuCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5vcGVuRm9yV3JpdGUoYmxvYlVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5vcGVuRm9yV3JpdGUobGVhc2VVcmkpOworCisgICAgU2hhcmVkRmlsZSBleHBlY3RlZFNoYXJlZEZpbGUwID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgiYW5kcm9pZF9zaGFyZWRfc2hhMjU2XzEyMzAiKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKHRydWUpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgic2hhMjU2XzEyMzAiKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcygwKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgU2hhcmVkRmlsZSBleHBlY3RlZFNoYXJlZEZpbGUxID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZShmaWxlR3JvdXAuZ2V0RmlsZSgxKS5nZXRGaWxlSWQoKSkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoa2V5c1swXSkuZ2V0KCkpLmlzRXF1YWxUbyhleHBlY3RlZFNoYXJlZEZpbGUwKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoa2V5c1sxXSkuZ2V0KCkpLmlzRXF1YWxUbyhleHBlY3RlZFNoYXJlZEZpbGUxKTsKKworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKG9uRGV2aWNldXJpKSkuaXNUcnVlKCk7CisgICAgb25EZXZpY2VGaWxlLmRlbGV0ZSgpOworCisgICAgQXJndW1lbnRDYXB0b3I8Vm9pZD4gbWRkQW5kcm9pZFNoYXJpbmdMb2dBcmd1bWVudENhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKFZvaWQuY2xhc3MpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkRmlsZUdyb3VwX29uZUZpbGVDYW5CZUNvcGllZEFmdGVyRG93bmxvYWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlIHRlbXBGaWxlID0gZm9sZGVyLm5ld0ZpbGUoImJsb2JGaWxlIik7CisgICAgLy8gV3JpdGUgMSBncm91cCB0byB0aGUgcGVuZGluZyBzaGFyZWQgcHJlZnMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHRtcEZmaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMCk7CisgICAgRXh0cmFIdHRwSGVhZGVyIGV4dHJhSHR0cEhlYWRlciA9CisgICAgICAgIEV4dHJhSHR0cEhlYWRlci5uZXdCdWlsZGVyKCkuc2V0S2V5KCJ1c2VyLWFnZW50Iikuc2V0VmFsdWUoIm1kZC1kb3dubG9hZGVyIikuYnVpbGQoKTsKKworICAgIGZpbmFsIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICB0bXBGZmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLnNldFRyYWZmaWNUYWcoVFJBRkZJQ19UQUcpCisgICAgICAgICAgICAuYWRkR3JvdXBFeHRyYUh0dHBIZWFkZXJzKGV4dHJhSHR0cEhlYWRlcikKKyAgICAgICAgICAgIC5hZGRGaWxlKDAsIE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKFRFU1RfR1JPVVAsIDApKQorICAgICAgICAgICAgLmFkZEZpbGUoMSwgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoVEVTVF9HUk9VUCwgMSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBOZXdGaWxlS2V5W10ga2V5cyA9IE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKGZpbGVHcm91cCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cCk7CisKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUywgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworCisgICAgLy8gRmlsZSB0aGF0IGNhbiBiZSBjb3BpZWQgdG8gdGhlIGJsb2Igc3RvcmFnZQorICAgIERhdGFGaWxlIGZpbGUgPSBmaWxlR3JvdXAuZ2V0RmlsZSgwKTsKKyAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSk7CisgICAgVXJpIGxlYXNlVXJpID0gRGlyZWN0b3J5VXRpbC5nZXRCbG9iU3RvcmVMZWFzZVVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwgMCk7CisgICAgLy8gVGhlIGZpbGUgaXMgYXZhaWxhYmxlIGluIHRoZSBibG9iIHN0b3JhZ2UKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmV4aXN0cyhibG9iVXJpKSkudGhlblJldHVybihmYWxzZSk7CisKKyAgICBzaW11bGF0ZURvd25sb2FkKGZpbGUsIGZpbGUuZ2V0RmlsZUlkKCkpOworICAgIFVyaSBvbkRldmljZXVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAga2V5c1swXS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgZmlsZS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgIGtleXNbMF0uZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzVHJ1ZSgpOworCisgICAgd2hlbihtb2NrRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKAorICAgICAgICAgICAgYW55KEdyb3VwS2V5LmNsYXNzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55TG9uZygpLAorICAgICAgICAgICAgZXEob25EZXZpY2V1cmkpLAorICAgICAgICAgICAgYW55KFN0cmluZy5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueShEb3dubG9hZENvbmRpdGlvbnMuY2xhc3MpLAorICAgICAgICAgICAgaXNBKERvd25sb2FkZXJDYWxsYmFja0ltcGwuY2xhc3MpLAorICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICBhbnlMaXN0KCkpKQorICAgICAgICAudGhlbigKKyAgICAgICAgICAgIG5ldyBBbnN3ZXI8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4oKSB7CisgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBhbnN3ZXIoSW52b2NhdGlvbk9uTW9jayBpbnZvY2F0aW9uKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgICAgICAgICAvLyBUaGUgZmlsZSB3aWxsIGJlIGNvcGllZCBpbiB0cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZAorICAgICAgICAgICAgICAgIHdoZW4obW9ja0JhY2tlbmQub3BlbkZvcldyaXRlKGJsb2JVcmkpKS50aGVuUmV0dXJuKG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRlbXBGaWxlKSk7CisgICAgICAgICAgICAgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgICAgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgZmlsZUdyb3VwLAorICAgICAgICAgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworCisgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAodGVzdEtleSwgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgcGVuZGluZyBrZXkgaXMgcmVtb3ZlZCBpZiBkb3dubG9hZCBpcyBjb21wbGV0ZS4KKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkpKS5pc051bGwoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IGRvd25sb2FkZWQga2V5IGlzIHdyaXR0ZW4gaW50byBtZXRhZGF0YSBpZiBkb3dubG9hZCBpcyBjb21wbGV0ZS4KKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkpKS5pc05vdE51bGwoKTsKKworICAgIC8vIGV4aXN0cyBvbmx5IGNhbGxlZCBvbmNlIGluIHRyeVRvU2hhcmVCZWZvcmVEb3dubG9hZCwgb25jZSBpbiB0cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZAorICAgIHZlcmlmeShtb2NrQmFja2VuZCwgdGltZXMoMikpLmV4aXN0cyhibG9iVXJpKTsKKyAgICAvLyAgRmlsZSBjb3BpZWQgb25jZSBpbiB0cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZAorICAgIHZlcmlmeShtb2NrQmFja2VuZCkub3BlbkZvcldyaXRlKGJsb2JVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkub3BlbkZvcldyaXRlKGxlYXNlVXJpKTsKKworICAgIFNoYXJlZEZpbGUgZXhwZWN0ZWRTaGFyZWRGaWxlMCA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImFuZHJvaWRfc2hhcmVkX3NoYTI1Nl8xMjMwIikKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJlZCh0cnVlKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oInNoYTI1Nl8xMjMwIikKKyAgICAgICAgICAgIC5zZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoMCkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFNoYXJlZEZpbGUgZXhwZWN0ZWRTaGFyZWRGaWxlMSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoZmlsZUdyb3VwLmdldEZpbGUoMSkuZ2V0RmlsZUlkKCkpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKGtleXNbMF0pLmdldCgpKS5pc0VxdWFsVG8oZXhwZWN0ZWRTaGFyZWRGaWxlMCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKGtleXNbMV0pLmdldCgpKS5pc0VxdWFsVG8oZXhwZWN0ZWRTaGFyZWRGaWxlMSk7CisKKyAgICAvLyBGaWxlIGRlbGV0ZWQgYWZ0ZXIgYmVpbmcgY29waWVkIHRvIHRoZSBibG9iIHN0b3JhZ2UuCisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMob25EZXZpY2V1cmkpKS5pc0ZhbHNlKCk7CisKKyAgICBBcmd1bWVudENhcHRvcjxWb2lkPiBtZGRBbmRyb2lkU2hhcmluZ0xvZ0FyZ3VtZW50Q2FwdG9yID0gQXJndW1lbnRDYXB0b3IuZm9yQ2xhc3MoVm9pZC5jbGFzcyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG93bmxvYWRGaWxlR3JvdXBfbm9uVG9CZVNoYXJlZEZpbGVfbmV2ZXJTaGFyZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSAxIGdyb3VwIHRvIHRoZSBwZW5kaW5nIHNoYXJlZCBwcmVmcy4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgdG1wRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIEV4dHJhSHR0cEhlYWRlciBleHRyYUh0dHBIZWFkZXIgPQorICAgICAgICBFeHRyYUh0dHBIZWFkZXIubmV3QnVpbGRlcigpLnNldEtleSgidXNlci1hZ2VudCIpLnNldFZhbHVlKCJtZGQtZG93bmxvYWRlciIpLmJ1aWxkKCk7CisKKyAgICBmaW5hbCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgdG1wRmlsZUdyb3VwLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLnNldEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLnNldFRyYWZmaWNUYWcoVFJBRkZJQ19UQUcpCisgICAgICAgICAgICAuYWRkR3JvdXBFeHRyYUh0dHBIZWFkZXJzKGV4dHJhSHR0cEhlYWRlcikKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXlbXSBrZXlzID0gTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwoZmlsZUdyb3VwKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZmlsZUdyb3VwKTsKKworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsIGZpbGVHcm91cCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisKKyAgICBEYXRhRmlsZSBmaWxlID0gZmlsZUdyb3VwLmdldEZpbGUoMCk7CisgICAgRmlsZSBvbkRldmljZUZpbGUgPSBzaW11bGF0ZURvd25sb2FkKGZpbGUsIGZpbGUuZ2V0RmlsZUlkKCkpOworICAgIFVyaSBvbkRldmljZXVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAga2V5c1swXS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgZmlsZS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgIGtleXNbMF0uZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzVHJ1ZSgpOworCisgICAgZmlsZURvd25sb2FkU3VjY2VlZHMoa2V5c1swXSwgb25EZXZpY2V1cmkpOworCisgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAodGVzdEtleSwgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgcGVuZGluZyBrZXkgaXMgcmVtb3ZlZCBpZiBkb3dubG9hZCBpcyBjb21wbGV0ZS4KKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkpKS5pc051bGwoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IGRvd25sb2FkZWQga2V5IGlzIHdyaXR0ZW4gaW50byBtZXRhZGF0YSBpZiBkb3dubG9hZCBpcyBjb21wbGV0ZS4KKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkpKS5pc05vdE51bGwoKTsKKworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZXhpc3RzKGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLm9wZW5Gb3JXcml0ZShhbnkoKSk7CisKKyAgICBTaGFyZWRGaWxlIGV4cGVjdGVkU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoZmlsZS5nZXRGaWxlSWQoKSkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoa2V5c1swXSkuZ2V0KCkpLmlzRXF1YWxUbyhleHBlY3RlZFNoYXJlZEZpbGUpOworCisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMob25EZXZpY2V1cmkpKS5pc1RydWUoKTsKKyAgICBvbkRldmljZUZpbGUuZGVsZXRlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG93bmxvYWRGaWxlR3JvdXBfYW5kcm9pZFNoYXJpbmdGYWlscygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdyaXRlIDEgZ3JvdXAgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCB0bXBGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMCk7CisgICAgRXh0cmFIdHRwSGVhZGVyIGV4dHJhSHR0cEhlYWRlciA9CisgICAgICAgIEV4dHJhSHR0cEhlYWRlci5uZXdCdWlsZGVyKCkuc2V0S2V5KCJ1c2VyLWFnZW50Iikuc2V0VmFsdWUoIm1kZC1kb3dubG9hZGVyIikuYnVpbGQoKTsKKworICAgIGZpbmFsIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICB0bXBGaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuc2V0VHJhZmZpY1RhZyhUUkFGRklDX1RBRykKKyAgICAgICAgICAgIC5hZGRHcm91cEV4dHJhSHR0cEhlYWRlcnMoZXh0cmFIdHRwSGVhZGVyKQorICAgICAgICAgICAgLmFkZEZpbGUoMCwgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoVEVTVF9HUk9VUCwgMCkpCisgICAgICAgICAgICAuYWRkRmlsZSgxLCBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZShURVNUX0dST1VQLCAxKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXlbXSBrZXlzID0gTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwoZmlsZUdyb3VwKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZmlsZUdyb3VwKTsKKworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICAvLyBTZWNvbmQgZmlsZSBmYWlscyB3aXRoIGZpbGUgc3RvcmFnZSBJL08gZXhjZXB0aW9uIHdoZW4gY2FsbGVkIGZyb20gdHJ5VG9TaGFyZUJlZm9yZURvd25sb2FkCisgICAgLy8gYW5kIHRyeVRvU2hhcmVBZnRlckRvd25sb2FkLgorICAgIERhdGFGaWxlIGZpbGUgPSBmaWxlR3JvdXAuZ2V0RmlsZSgxKTsKKyAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5leGlzdHMoYmxvYlVyaSkpLnRoZW5UaHJvdyhuZXcgSU9FeGNlcHRpb24oKSk7CisKKyAgICAvLyBBbnkgZXJyb3IgZHVyaW5nIHNoYXJpbmcgZG9lc24ndCBzdG9wIHRoZSBkb3dubG9hZDogdGhlIGZpbGUgd2lsbCBiZSBzdG9yZWQgbG9jYWxseS4KKyAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCh0ZXN0S2V5LCBEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCksIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAuZ2V0KCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBwZW5kaW5nIGtleSBpcyByZW1vdmVkIGlmIGRvd25sb2FkIGlzIGNvbXBsZXRlLgorICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzTnVsbCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgZG93bmxvYWRlZCBrZXkgaXMgd3JpdHRlbiBpbnRvIG1ldGFkYXRhIGlmIGRvd25sb2FkIGlzIGNvbXBsZXRlLgorICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleSkpLmlzTm90TnVsbCgpOworCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCB0aW1lcygyKSkuZXhpc3RzKGJsb2JVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkub3BlbkZvcldyaXRlKGFueSgpKTsKKworICAgIFNoYXJlZEZpbGUgZXhwZWN0ZWRTaGFyZWRGaWxlMCA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoZmlsZUdyb3VwLmdldEZpbGUoMCkuZ2V0RmlsZUlkKCkpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgU2hhcmVkRmlsZSBleHBlY3RlZFNoYXJlZEZpbGUxID0KKyAgICAgICAgZXhwZWN0ZWRTaGFyZWRGaWxlMC50b0J1aWxkZXIoKS5zZXRGaWxlTmFtZShmaWxlR3JvdXAuZ2V0RmlsZSgxKS5nZXRGaWxlSWQoKSkuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoa2V5c1swXSkuZ2V0KCkpLmlzRXF1YWxUbyhleHBlY3RlZFNoYXJlZEZpbGUwKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoa2V5c1sxXSkuZ2V0KCkpLmlzRXF1YWxUbyhleHBlY3RlZFNoYXJlZEZpbGUxKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REb3dubG9hZEZpbGVHcm91cF9za2lwc1NpZGVsb2FkZWRGaWxlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENyZWF0ZSBzaWRlbG9hZGVkIGdyb3VwIHdpdGggbm9ybWFsIGZpbGUKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgc2lkZWxvYWRlZEdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgRGF0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoInNpZGVsb2FkZWRfZmlsZSIpCisgICAgICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJmaWxlOi90ZXN0IikKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtVHlwZShEYXRhRmlsZS5DaGVja3N1bVR5cGUuTk9ORSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYWRkRmlsZSgKKyAgICAgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEZpbGVJZCgibm9ybWFsX2ZpbGUiKQorICAgICAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaHR0cHM6Ly91cmwudG8uZG93bmxvYWQiKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW1UeXBlKERhdGFGaWxlLkNoZWNrc3VtVHlwZS5OT05FKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXkgbm9ybWFsRmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgc2lkZWxvYWRlZEdyb3VwLmdldEZpbGUoMSksIHNpZGVsb2FkZWRHcm91cC5nZXRBbGxvd2VkUmVhZGVyc0VudW0oKSk7CisKKyAgICAvLyBXcml0ZSBncm91cCBhcyBwZW5kaW5nIHNpbmNlIHdlIGFyZSB3YWl0aW5nIG9uIG5vcm1hbCBmaWxlCisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIHNpZGVsb2FkZWRHcm91cCk7CisgICAgU2hhcmVkRmlsZSBub3JtYWxTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZShzaWRlbG9hZGVkR3JvdXAuZ2V0RmlsZSgxKS5nZXRGaWxlSWQoKSkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5vcm1hbEZpbGVLZXksIG5vcm1hbFNoYXJlZEZpbGUpLmdldCgpOworCisgICAgLy8gTW9jayB0aGF0IGRvd25sb2FkIG9mIG5vcm1hbCBmaWxlIHN1Y2NlZWRzCisgICAgVXJpIG5vcm1hbEZpbGVVcmkgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE9uRGV2aWNlVXJpKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG5vcm1hbEZpbGVLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgIHNpZGVsb2FkZWRHcm91cC5nZXRGaWxlKDEpLmdldEZpbGVJZCgpLAorICAgICAgICAgICAgc2lkZWxvYWRlZEdyb3VwLmdldEZpbGUoMSkuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZhbHNlKTsKKyAgICBmaWxlRG93bmxvYWRTdWNjZWVkcyhub3JtYWxGaWxlS2V5LCBub3JtYWxGaWxlVXJpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKHRlc3RLZXksIERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleSkpLmlzTm90TnVsbCgpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyKQorICAgICAgICAuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIGVxKHRlc3RLZXkpLAorICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICBhbnlMb25nKCksCisgICAgICAgICAgICBlcShub3JtYWxGaWxlVXJpKSwKKyAgICAgICAgICAgIGVxKHNpZGVsb2FkZWRHcm91cC5nZXRGaWxlKDEpLmdldFVybFRvRG93bmxvYWQoKSksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueSgpLAorICAgICAgICAgICAgYW55KCksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueUxpc3QoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG93bmxvYWRGaWxlR3JvdXBfd2hlbk11bHRpcGxlVmFyaWFudHNFeGlzdF9kb3dubG9hZHNTcGVjaWZpZWRWYXJpYW50KCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIEdyb3VwS2V5IGRlZmF1bHRHcm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBHcm91cEtleSBlbkdyb3VwS2V5ID0gZGVmYXVsdEdyb3VwS2V5LnRvQnVpbGRlcigpLnNldFZhcmlhbnRJZCgiZW4iKS5idWlsZCgpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRlZmF1bHRGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgLy8gQ3JlYXRlIEVOIHdpdGggY3VzdG9tIGZpbGUgaWRzIHNvIGl0IGRvZXNuJ3Qgb3ZlcmxhcCB3aXRoIHRoZSBkZWZhdWx0IGZpbGUgZ3JvdXAuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGVuRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuYWRkRmlsZShNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZW4iLCAwKSkKKyAgICAgICAgICAgIC5hZGRGaWxlKE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJlbiIsIDEpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAoZ2V0UGVuZGluZ0tleShkZWZhdWx0R3JvdXBLZXkpLCBkZWZhdWx0RmlsZUdyb3VwKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAoZ2V0UGVuZGluZ0tleShlbkdyb3VwS2V5KSwgZW5GaWxlR3JvdXApOworCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgZGVmYXVsdEZpbGVHcm91cCwgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIGRlZmF1bHRHcm91cEtleSwgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgY29ycmVjdCBncm91cCB3YXMgZG93bmxvYWRlZAorICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAoZGVmYXVsdEdyb3VwS2V5KSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cChkZWZhdWx0R3JvdXBLZXkpKS5pc05vdE51bGwoKTsKKworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAoZW5Hcm91cEtleSkpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAoZW5Hcm91cEtleSkpLmlzTnVsbCgpOworCisgICAgLy8gQXR0ZW1wdCB0byBkb3dubG9hZCBlbiBncm91cCBhbmQgY2hlY2sgdGhhdCBpdCBpcyBub3cgZG93bmxvYWRlZAorICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGVuRmlsZUdyb3VwLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKAorICAgICAgICAgICAgZW5Hcm91cEtleSwgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgY29ycmVjdCBncm91cCB3YXMgZG93bmxvYWRlZAorICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAoZGVmYXVsdEdyb3VwS2V5KSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cChkZWZhdWx0R3JvdXBLZXkpKS5pc05vdE51bGwoKTsKKworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAoZW5Hcm91cEtleSkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZERvd25sb2FkZWRGaWxlR3JvdXAoZW5Hcm91cEtleSkpLmlzTm90TnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkQWxsUGVuZGluZ0dyb3Vwc19vbldpZmkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSAzIGdyb3VwcyB0byB0aGUgcGVuZGluZyBzaGFyZWQgcHJlZnMuCisgICAgLy8gTUREIHN1Y2Nlc3NmdWxseSBkb3dubG9hZGVkIGZpbGVncm91cDEsIHBhcnRpYWxseSBkb3dubG9hZGVkIGZpbGVncm91cDIgYW5kIGZhaWxlZCB0bworICAgIC8vIGRvd25sb2FkIGZpbGVncm91cDMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDEgPQorICAgICAgICBjcmVhdGVEYXRhRmlsZUdyb3VwKAorICAgICAgICAgICAgVEVTVF9HUk9VUCwKKyAgICAgICAgICAgIC8qZmlsZUNvdW50PSovIDIsCisgICAgICAgICAgICAvKmRvd25sb2FkQXR0ZW1wdENvdW50PSovIDcsCisgICAgICAgICAgICAvKm5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXA9Ki8gdGVzdENsb2NrLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSA1MDBMKTsKKyAgICBmaWxlR3JvdXAxID0KKyAgICAgICAgZmlsZUdyb3VwMS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZmlsZUdyb3VwMSk7CisgICAgLy8gQWxsIGZpbGVzIGFyZSBkb3dubG9hZGVkLgorICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cDEsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDIgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAyKTsKKyAgICBmaWxlR3JvdXAyID0KKyAgICAgICAgZmlsZUdyb3VwMi50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleTIsIGZpbGVHcm91cDIpOworICAgIC8vIE5vdCBhbGwgZmlsZXMgYXJlIGRvd25sb2FkZWQuCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZmlsZUdyb3VwMiwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisKKyAgICBHcm91cEtleSBleHBlY3RlZEtleTIgPSB0ZXN0S2V5Mi50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworICAgIC8vIFRoZSBmaWxlIHN0YXR1cyBpc24ndCBjaGFuZ2VkIHRvIERPV05MT0FEX0NPTVBMRVRFLCBpdCByZW1haW5zIERPV05MT0FEX0lOX1BST0dSRVNTLgorICAgIC8vICBBbiBVTktOT1dOX0VSUk9SIGlzIGxvZ2dlZC4KKyAgICB3aGVuKG1vY2tEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoCisgICAgICAgICAgICBlcShleHBlY3RlZEtleTIpLAorICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICBhbnlMb25nKCksCisgICAgICAgICAgICBhbnkoVXJpLmNsYXNzKSwKKyAgICAgICAgICAgIGFueShTdHJpbmcuY2xhc3MpLAorICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICBhbnkoRG93bmxvYWRDb25kaXRpb25zLmNsYXNzKSwKKyAgICAgICAgICAgIGlzQShEb3dubG9hZGVyQ2FsbGJhY2tJbXBsLmNsYXNzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55TGlzdCgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHRtcEZpbGVHcm91cDMgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8zLCAyKTsKKyAgICBmaW5hbCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMyA9CisgICAgICAgIHRtcEZpbGVHcm91cDMudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoCisgICAgICAgICAgICAgICAgRG93bmxvYWRDb25kaXRpb25zLm5ld0J1aWxkZXIoKS5zZXREb3dubG9hZEZpcnN0T25XaWZpUGVyaW9kU2VjcygxMDAwMDAwKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5MywgZmlsZUdyb3VwMyk7CisgICAgLy8gTm90IGFsbCBmaWxlcyBhcmUgZG93bmxvYWRlZC4KKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAzLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKworICAgIEdyb3VwS2V5IGV4cGVjdGVkS2V5MyA9IHRlc3RLZXkzLnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisgICAgLy8gT25lIGZpbGUgZmFpbHMsIG5ldyBzdGF0dXMgaXMgRE9XTkxPQURfRkFJTEVEIGJ1dCB0aGUgZG93bmxvYWRlciByZXR1cm5zIGFuCisgICAgLy8gaW1tZWRpYXRlVm9pZEZ1dHVyZS4gQW4gVU5LTk9XTl9FUlJPUiBpcyBsb2dnZWQuCisgICAgd2hlbihtb2NrRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKAorICAgICAgICAgICAgZXEoZXhwZWN0ZWRLZXkzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55TG9uZygpLAorICAgICAgICAgICAgYW55KFVyaS5jbGFzcyksCisgICAgICAgICAgICBhbnkoU3RyaW5nLmNsYXNzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55KERvd25sb2FkQ29uZGl0aW9ucy5jbGFzcyksCisgICAgICAgICAgICBpc0EoRG93bmxvYWRlckNhbGxiYWNrSW1wbC5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueUxpc3QoKSkpCisgICAgICAgIC50aGVuKAorICAgICAgICAgICAgbmV3IEFuc3dlcjxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PigpIHsKKyAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGFuc3dlcihJbnZvY2F0aW9uT25Nb2NrIGludm9jYXRpb24pIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgICAgICAgICAgICAgIGZpbGVHcm91cDMsCisgICAgICAgICAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9GQUlMRUQpKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworCisgICAgZmlsZUdyb3VwTWFuYWdlci5zY2hlZHVsZUFsbFBlbmRpbmdHcm91cHNGb3JEb3dubG9hZCh0cnVlLCBub0N1c3RvbVZhbGlkYXRpb24oKSkuZ2V0KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG93bmxvYWRBbGxQZW5kaW5nR3JvdXBzX3dpdGhvdXRXaWZpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV3JpdGUgMiBncm91cHMgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAxID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIGZpbGVHcm91cDEgPQorICAgICAgICBmaWxlR3JvdXAxLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKAorICAgICAgICAgICAgICAgIERvd25sb2FkQ29uZGl0aW9ucy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldERldmljZU5ldHdvcmtQb2xpY3koRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSykpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZmlsZUdyb3VwMSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZmlsZUdyb3VwMSwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTLCBGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMiA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzIsIDMpOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5MiwgZmlsZUdyb3VwMik7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZmlsZUdyb3VwMiwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgIEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MsCisgICAgICAgICAgICBGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTLAorICAgICAgICAgICAgRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci5zY2hlZHVsZUFsbFBlbmRpbmdHcm91cHNGb3JEb3dubG9hZChmYWxzZSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpLmdldCgpOworCisgICAgLy8gT25seSB0aGUgZmlsZXMgaW4gdGhlIGZpcnN0IGdyb3VwIHdpbGwgYmUgZG93bmxvYWRlZC4KKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkZXIsIHRpbWVzKDIpKQorICAgICAgICAuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIGVxKGdldFBlbmRpbmdLZXkodGVzdEtleSkpLAorICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICBhbnlMb25nKCksCisgICAgICAgICAgICBhbnkoVXJpLmNsYXNzKSwKKyAgICAgICAgICAgIGFueShTdHJpbmcuY2xhc3MpLAorICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICBhbnkoRG93bmxvYWRDb25kaXRpb25zLmNsYXNzKSwKKyAgICAgICAgICAgIGlzQShEb3dubG9hZGVyQ2FsbGJhY2tJbXBsLmNsYXNzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55TGlzdCgpKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja0Rvd25sb2FkZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkQWxsUGVuZGluZ0dyb3Vwc193aWZpRmlyc3Rfd2l0aG91dF9XaWZpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoCisgICAgICAgICAgICAgICAgRG93bmxvYWRDb25kaXRpb25zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RGV2aWNlTmV0d29ya1BvbGljeSgKKyAgICAgICAgICAgICAgICAgICAgICAgIERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfRklSU1RfT05fV0lGSV9USEVOX09OX0FOWV9ORVRXT1JLKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRGaXJzdE9uV2lmaVBlcmlvZFNlY3MoMTApKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICB0ZXN0Q2xvY2suc2V0KDEwMDApOworCisgICAgeworICAgICAgLy8gQ2hlY2sgdGhhdCBwZW5kaW5nIGdyb3VwcyBjb250YWluIHRoZSBhZGRlZCBmaWxlIGdyb3VwLgorICAgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQodGVzdEtleSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgICAgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKHRlc3RLZXksIGRhdGFGaWxlR3JvdXAsIDEwMDApOworICAgIH0KKworICAgIHsKKyAgICAgIC8vIFNldCB0aW1lIHNvIHRoYXQgaXQgaGFzIG5vdCBwYXNzZWQgdGhlIHdpZmkgb25seSBwZXJpb2QuCisgICAgICB0ZXN0Q2xvY2suc2V0KDIwMDApOworICAgICAgZmlsZUdyb3VwTWFuYWdlci5zY2hlZHVsZUFsbFBlbmRpbmdHcm91cHNGb3JEb3dubG9hZChmYWxzZSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpLmdldCgpOworICAgIH0KKworICAgIHsKKyAgICAgIC8vIFNldCB0aW1lIHNvIHRoYXQgaXQgaGFzIHBhc3NlZCB0aGUgd2lmaSBvbmx5IHBlcmlvZC4KKyAgICAgIHRlc3RDbG9jay5zZXQoMjAwMCArIDEwICogMTAwMCk7CisgICAgICBBcmd1bWVudENhcHRvcjxEb3dubG9hZENvbmRpdGlvbnM+IGRvd25sb2FkQ29uZGl0aW9uQ2FwdG9yID0KKyAgICAgICAgICBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhEb3dubG9hZENvbmRpdGlvbnMuY2xhc3MpOworICAgICAgd2hlbihtb2NrRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKAorICAgICAgICAgICAgICBhbnkoR3JvdXBLZXkuY2xhc3MpLAorICAgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgICAgYW55TG9uZygpLAorICAgICAgICAgICAgICBhbnkoVXJpLmNsYXNzKSwKKyAgICAgICAgICAgICAgYW55KFN0cmluZy5jbGFzcyksCisgICAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgICBkb3dubG9hZENvbmRpdGlvbkNhcHRvci5jYXB0dXJlKCksCisgICAgICAgICAgICAgIGlzQShEb3dubG9hZGVyQ2FsbGJhY2tJbXBsLmNsYXNzKSwKKyAgICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICAgIGFueUxpc3QoKSkpCisgICAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworCisgICAgICBmaWxlR3JvdXBNYW5hZ2VyLnNjaGVkdWxlQWxsUGVuZGluZ0dyb3Vwc0ZvckRvd25sb2FkKGZhbHNlLCBub0N1c3RvbVZhbGlkYXRpb24oKSkuZ2V0KCk7CisKKyAgICAgIC8vIHZlcmlmeSB0aGF0IHRoZSBncm91cCdzIERldmljZU5ldHdvcmtQb2xpY3kgY2hhbmdlcyB0bworICAgICAgLy8gRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSworICAgICAgYXNzZXJ0VGhhdChkb3dubG9hZENvbmRpdGlvbkNhcHRvci5nZXRWYWx1ZSgpLmdldERldmljZU5ldHdvcmtQb2xpY3koKSkKKyAgICAgICAgICAuaXNFcXVhbFRvKERldmljZU5ldHdvcmtQb2xpY3kuRE9XTkxPQURfT05fQU5ZX05FVFdPUkspOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REb3dubG9hZEFsbFBlbmRpbmdHcm91cHNfc3RhcnREb3dubG9hZEZhaWxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gV3JpdGUgMiBncm91cHMgdG8gdGhlIHBlbmRpbmcgc2hhcmVkIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAxID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5LCBmaWxlR3JvdXAxKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAxLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKyAgICBOZXdGaWxlS2V5W10ga2V5czEgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChmaWxlR3JvdXAxKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAyID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMSk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkyLCBmaWxlR3JvdXAyKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLCBmaWxlR3JvdXAyLCBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIC8vIE1ha2UgdGhlIGRvd25sb2FkIGNhbGwgZmFpbCBmb3Igb25lIG9mIHRoZSBmaWxlcyBpbiBmaXJzdCBncm91cC4KKyAgICBVcmkgZmFpbGluZ0ZpbGVVcmkgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE9uRGV2aWNlVXJpKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIGtleXMxWzFdLmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBmaWxlR3JvdXAxLmdldEZpbGUoMSkuZ2V0RmlsZUlkKCksCisgICAgICAgICAgICBmaWxlR3JvdXAxLmdldEZpbGUoMSkuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgZmFsc2UpOworICAgIGZpbGVEb3dubG9hZEZhaWxzKGtleXMxWzFdLCBmYWlsaW5nRmlsZVVyaSwgRG93bmxvYWRSZXN1bHRDb2RlLkxPV19ESVNLX0VSUk9SKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIuc2NoZWR1bGVBbGxQZW5kaW5nR3JvdXBzRm9yRG93bmxvYWQodHJ1ZSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpLmdldCgpOworICB9CisKKyAgLy8gY2FzZSAxOiB0aGUgZmlsZSBpcyBhbHJlYWR5IHNoYXJlZCBpbiB0aGUgYmxvYiBzdG9yYWdlLgorICBAVGVzdAorICBwdWJsaWMgdm9pZCB0cnlUb1NoYXJlQmVmb3JlRG93bmxvYWRfYWxyZWFkeVNoYXJlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBEYXRhRmlsZSBmaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlU2hhcmVkRGF0YUZpbGUoImZpbGVJZCIsIDApOworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgLy8gU2V0IHRoZSBmaWxlIG1ldGFkYXRhIGFzIGFscmVhZHkgZG93bmxvYWRlZCBhbmQgc2hhcmVkCisgICAgU2hhcmVkRmlsZSBleGlzdGluZ0Rvd25sb2FkZWRTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoIiIpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJlZCh0cnVlKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCkpCisgICAgICAgICAgICAuc2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIGV4aXN0aW5nRG93bmxvYWRlZFNoYXJlZEZpbGUpLmdldCgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQmVmb3JlRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZXhpc3RzKGFueSgpKTsKKyAgICAvLyBvcGVuRm9yV3JpdGUgaXNuJ3QgY2FsbGVkIHRvIHVwZGF0ZSB0aGUgbGVhc2UgYmVjYXVzZSB0aGUgY3VycmVudCBmaWxlR3JvdXAncyBleHBpcmF0aW9uIGRhdGUKKyAgICAvLyBpcyA8IG1heEV4cGlyYXRpb25EYXRlLgorICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkub3BlbkZvcldyaXRlKGFueSgpKTsKKworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KS5nZXQoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhleGlzdGluZ0Rvd25sb2FkZWRTaGFyZWRGaWxlKTsKKyAgfQorCisgIC8vIGNhc2UgMmE6IHRoZSB0by1iZS1zaGFyZWQgZmlsZSBpcyBhdmFpbGFibGUgaW4gdGhlIGJsb2Igc3RvcmFnZS4KKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdHJ5VG9TaGFyZUJlZm9yZURvd25sb2FkX3RvQmVTaGFyZWRGaWxlX2Jsb2JFeGlzdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgYSBmaWxlIGdyb3VwIHdpdGggZXhwaXJhdGlvbiBkYXRlIHNtYWxsZXIgdGhhbiB0aGUgZXhwaXJhdGlvbiBkYXRlIG9mIHRoZSBleGlzdGluZworICAgIC8vIFNoYXJlZEZpbGUuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MgLSAxKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBDcmVhdGUgYSB0by1iZS1zaGFyZWQgZmlsZQorICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICAvLyBTZXQgdGhlIGZpbGUgbWV0YWRhdGEgYXMgZG93bmxvYWQgcGVuZGluZyBhbmQgbm9uIHNoYXJlZAorICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIGV4aXN0aW5nU2hhcmVkRmlsZSkuZ2V0KCk7CisKKyAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSk7CisgICAgVXJpIGxlYXNlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRCbG9iU3RvcmVMZWFzZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsIGZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLCBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKTsKKyAgICAvLyBUaGUgZmlsZSBpcyBhdmFpbGFibGUgaW4gdGhlIGJsb2Igc3RvcmFnZQorICAgIHdoZW4obW9ja0JhY2tlbmQuZXhpc3RzKGJsb2JVcmkpKS50aGVuUmV0dXJuKHRydWUpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQmVmb3JlRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KS5nZXQoKTsKKworICAgIC8vIG9wZW5Gb3JXcml0ZSBpcyBjYWxsZWQgb25seSBvbmNlIGZvciBhY3F1aXJpbmcgdGhlIGxlYXNlLgorICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkub3BlbkZvcldyaXRlKGJsb2JVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkub3BlbkZvcldyaXRlKGxlYXNlVXJpKTsKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPSBzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKG5ld0ZpbGVLZXkpLmdldCgpOworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBTaGFyZWRGaWxlIHJldGFpbnMgdGhlIGxvbmdlc3QgZXhwaXJhdGlvbiBkYXRlIGFmdGVyIHRoZSBkb3dubG9hZC4KKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUuZ2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUuZ2V0QW5kcm9pZFNoYXJlZCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKG5ld0ZpbGVLZXkpLmdldCgpKS5pc0VxdWFsVG8oYmxvYlVyaSk7CisKKyAgICBBcmd1bWVudENhcHRvcjxWb2lkPiBtZGRBbmRyb2lkU2hhcmluZ0xvZ0FyZ3VtZW50Q2FwdG9yID0gQXJndW1lbnRDYXB0b3IuZm9yQ2xhc3MoVm9pZC5jbGFzcyk7CisgIH0KKworICAvLyBjYXNlIDM6IHRoZSB0by1iZS1zaGFyZWQgZmlsZSBpcyBhdmFpbGFibGUgaW4gdGhlIGxvY2FsIHN0b3JhZ2UuCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRyeVRvU2hhcmVCZWZvcmVEb3dubG9hZF90b0JlU2hhcmVkRmlsZV9jYW5CZUNvcGllZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGUgdGVtcEZpbGUgPSBmb2xkZXIubmV3RmlsZSgiYmxvYkZpbGUiKTsKKyAgICAvLyBDcmVhdGUgYSBmaWxlIGdyb3VwIHdpdGggZXhwaXJhdGlvbiBkYXRlIGJpZ2dlciB0aGFuIHRoZSBleHBpcmF0aW9uIGRhdGUgb2YgdGhlIGV4aXN0aW5nCisgICAgLy8gU2hhcmVkRmlsZS4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5zZXRFeHBpcmF0aW9uRGF0ZVNlY3MoRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyArIDEpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIENyZWF0ZSBhIHRvLWJlLXNoYXJlZCBmaWxlCisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIC8vIFNldCB0aGUgZmlsZSBtZXRhZGF0YSBhcyBkb3dubG9hZGVkIGFuZCBub24gc2hhcmVkCisgICAgU2hhcmVkRmlsZSBleGlzdGluZ1NoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgiZmlsZU5hbWUiKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyZWQoZmFsc2UpCisgICAgICAgICAgICAuc2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIGV4aXN0aW5nU2hhcmVkRmlsZSkuZ2V0KCk7CisKKyAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSk7CisgICAgVXJpIGxlYXNlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRCbG9iU3RvcmVMZWFzZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsIGZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLCBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTICsgMSk7CisgICAgLy8gVGhlIGZpbGUgaXNuJ3QgYXZhaWxhYmxlIGluIHRoZSBibG9iIHN0b3JhZ2UKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmV4aXN0cyhibG9iVXJpKSkudGhlblJldHVybihmYWxzZSk7CisgICAgd2hlbihtb2NrQmFja2VuZC5vcGVuRm9yV3JpdGUoYmxvYlVyaSkpLnRoZW5SZXR1cm4obmV3IEZpbGVPdXRwdXRTdHJlYW0odGVtcEZpbGUpKTsKKworICAgIEZpbGUgb25EZXZpY2VGaWxlID0gc2ltdWxhdGVEb3dubG9hZChmaWxlLCBleGlzdGluZ1NoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSk7CisgICAgVXJpIG9uRGV2aWNldXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBleGlzdGluZ1NoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSwKKyAgICAgICAgICAgIG5ld0ZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzVHJ1ZSgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQmVmb3JlRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KS5nZXQoKTsKKworICAgIC8vIG9wZW5Gb3JXcml0ZSBpcyBjYWxsZWQgb25jZSBmb3Igd3JpdGluZyB0aGUgYmxvYiwgb25jZSBmb3IgYWNxdWlyaW5nIHRoZSBsZWFzZS4KKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLm9wZW5Gb3JXcml0ZShibG9iVXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLm9wZW5Gb3JXcml0ZShsZWFzZVVyaSk7CisKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPSBzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKG5ld0ZpbGVLZXkpLmdldCgpOworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBTaGFyZWRGaWxlIGhhcyB1cGRhdGVkIGl0cyBleHBpcmF0aW9uIGRhdGUgYWZ0ZXIgdGhlIGRvd25sb2FkLgorICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZS5nZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTICsgMSk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlLmdldEFuZHJvaWRTaGFyZWQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlTWFuYWdlci5nZXRPbkRldmljZVVyaShuZXdGaWxlS2V5KS5nZXQoKSkuaXNFcXVhbFRvKGJsb2JVcmkpOworCisgICAgLy8gVGhlIGxvY2FsIGNvcHkgd2lsbCBiZSBkZWxldGVkIGluIGRhaWx5IG1haW50YW5jZQorICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKG9uRGV2aWNldXJpKSkuaXNUcnVlKCk7CisgICAgb25EZXZpY2VGaWxlLmRlbGV0ZSgpOworCisgICAgQXJndW1lbnRDYXB0b3I8Vm9pZD4gbWRkQW5kcm9pZFNoYXJpbmdMb2dBcmd1bWVudENhcHRvciA9IEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKFZvaWQuY2xhc3MpOworICB9CisKKyAgLy8gVGhlIGZpbGUgY2FuJ3QgYmUgc2hhcmVkIGFuZCBpc24ndCBhdmFpbGFibGUgbG9jYWxseS4KKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdHJ5VG9TaGFyZUJlZm9yZURvd25sb2FkX3RvQmVTaGFyZWRGaWxlX2Nhbm5vdEJlU2hhcmVkX25ldmVyRG93bmxvYWRlZCgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBleGlzdGluZ1NoYXJlZEZpbGUpLmdldCgpOworCisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCkpOworICAgIC8vIFRoZSBmaWxlIGlzbid0IGF2YWlsYWJsZSBpbiB0aGUgYmxvYiBzdG9yYWdlCisgICAgd2hlbihtb2NrQmFja2VuZC5leGlzdHMoYmxvYlVyaSkpLnRoZW5SZXR1cm4oZmFsc2UpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQmVmb3JlRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KS5nZXQoKTsKKworICAgIC8vIFdlIG5ldmVyIGFjcXVpcmUgdGhlIGxlYXNlIG5vciB1cGRhdGUgdGhlIG1heCBleHBpcmF0aW9uIGRhdGUuCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmxvYlVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5vcGVuRm9yV3JpdGUoYW55KCkpOworCisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0gc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUpLmlzRXF1YWxUbyhleGlzdGluZ1NoYXJlZEZpbGUpOworICB9CisKKyAgLy8gY2FzZSA0OiB0aGUgbm9uLXRvLWJlLXNoYXJlZCBmaWxlIGNhbid0IGJlIHNoYXJlZCBhbmQgaXMgYXZhaWxhYmxlIGluIHRoZSBsb2NhbCBzdG9yYWdlLgorICBAVGVzdAorICBwdWJsaWMgdm9pZCB0cnlUb1NoYXJlQmVmb3JlRG93bmxvYWRfbm9uVG9CZVNoYXJlZEZpbGVfYWxyZWFkeURvd25sb2FkZWRfY2Fubm90QmVTaGFyZWQoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICAvLyBub24tdG8tYmUtc2hhcmVkIGZpbGUgd2l0aCBDaGVja3N1bVR5cGUgU0hBMQorICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICAvLyBTZXQgdGhlIGZpbGUgbWV0YWRhdGEgZG93bmxvYWRlZCBhbmQgbm9uIHNoYXJlZAorICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBleGlzdGluZ1NoYXJlZEZpbGUpLmdldCgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQmVmb3JlRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZXhpc3RzKGFueSgpKTsKKyAgICAvLyBXZSBuZXZlciBhY3F1aXJlIHRoZSBsZWFzZSBzaW5jZSB0aGUgZmlsZSBjYW4ndCBiZSBzaGFyZWQuCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5vcGVuRm9yV3JpdGUoYW55KCkpOworCisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0gc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUpLmlzRXF1YWxUbyhleGlzdGluZ1NoYXJlZEZpbGUpOworCisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlciwgbmV2ZXIoKSkKKyAgICAgICAgLnNldEFuZHJvaWRTaGFyZWREb3dubG9hZGVkRmlsZUVudHJ5KGFueSgpLCBhbnkoKSwgYW55TG9uZygpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRyeVRvU2hhcmVCZWZvcmVEb3dubG9hZF9ibG9iVXJpTm90U3VwcG9ydGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gRmlsZVN0b3JhZ2Ugd2l0aG91dCBCbG9iU3RvcmVCYWNrZW5kCisgICAgZmlsZVN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZShBcnJheXMuYXNMaXN0KEFuZHJvaWRGaWxlQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLmJ1aWxkKCkpKTsKKyAgICBmaWxlR3JvdXBNYW5hZ2VyID0KKyAgICAgICAgbmV3IEZpbGVHcm91cE1hbmFnZXIoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0xvZ2dlciwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YSwKKyAgICAgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyLAorICAgICAgICAgICAgdGVzdENsb2NrLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0FjY291bnRTb3VyY2UpLAorICAgICAgICAgICAgU0VRVUVOVElBTF9DT05UUk9MX0VYRUNVVE9SLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIGRvd25sb2FkU3RhZ2VNYW5hZ2VyLAorICAgICAgICAgICAgZmxhZ3MpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIENyZWF0ZSBhIHRvLWJlLXNoYXJlZCBmaWxlCisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIC8vIFNldCB0aGUgZmlsZSBtZXRhZGF0YSBhcyBkb3dubG9hZCBjb21wbGV0ZWQgYW5kIG5vbiBzaGFyZWQKKyAgICBTaGFyZWRGaWxlIGV4aXN0aW5nU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJmaWxlTmFtZSIpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJlZChmYWxzZSkKKyAgICAgICAgICAgIC5zZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUykKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBleGlzdGluZ1NoYXJlZEZpbGUpLmdldCgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQmVmb3JlRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkub3BlbkZvcldyaXRlKGFueSgpKTsKKworICAgIFNoYXJlZEZpbGUgc2hhcmVkRmlsZSA9IHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUobmV3RmlsZUtleSkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlKS5pc0VxdWFsVG8oZXhpc3RpbmdTaGFyZWRGaWxlKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRyeVRvU2hhcmVCZWZvcmVEb3dubG9hZF9zZXRBbmRyb2lkU2hhcmVkRG93bmxvYWRlZEZpbGVFbnRyeVJldHVybnNGYWxzZSgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNb2NrIFNoYXJlZEZpbGVNYW5hZ2VyIHRvIHRlc3QgZmFpbHVyZSBzY2VuYXJpby4KKyAgICByZXNldEZpbGVHcm91cE1hbmFnZXIoZmlsZUdyb3Vwc01ldGFkYXRhLCBtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBDcmVhdGUgYSB0by1iZS1zaGFyZWQgZmlsZQorICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKG5ld0ZpbGVLZXkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShleGlzdGluZ1NoYXJlZEZpbGUpKTsKKyAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSk7CisgICAgVXJpIGxlYXNlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRCbG9iU3RvcmVMZWFzZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsIGZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLCBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKTsKKyAgICAvLyBUaGUgZmlsZSBpcyBhdmFpbGFibGUgaW4gdGhlIGJsb2Igc3RvcmFnZQorICAgIHdoZW4obW9ja0JhY2tlbmQuZXhpc3RzKGJsb2JVcmkpKS50aGVuUmV0dXJuKHRydWUpOworCisgICAgLy8gTGFzdCBvcGVyYXRpb24gZmFpbHMKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5zZXRBbmRyb2lkU2hhcmVkRG93bmxvYWRlZEZpbGVFbnRyeSgKKyAgICAgICAgICAgIG5ld0ZpbGVLZXksIGZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLCBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmFsc2UpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIudHJ5VG9TaGFyZUJlZm9yZURvd25sb2FkKGZpbGVHcm91cCwgZmlsZSwgbmV3RmlsZUtleSkuZ2V0KCk7CisKKyAgICAvLyBvcGVuRm9yV3JpdGUgaXMgY2FsbGVkIG9ubHkgb25jZSBmb3IgYWNxdWlyaW5nIHRoZSBsZWFzZS4KKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLm9wZW5Gb3JXcml0ZShibG9iVXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLm9wZW5Gb3JXcml0ZShsZWFzZVVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0cnlUb1NoYXJlQmVmb3JlRG93bmxvYWRfYmxvYkV4aXN0c1Rocm93c0lPRXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIENyZWF0ZSBhIHRvLWJlLXNoYXJlZCBmaWxlCisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgU2hhcmVkRmlsZSBleGlzdGluZ1NoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgiZmlsZU5hbWUiKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyZWQoZmFsc2UpCisgICAgICAgICAgICAuc2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIGV4aXN0aW5nU2hhcmVkRmlsZSkuZ2V0KCk7CisKKyAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSk7CisgICAgVXJpIGxlYXNlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRCbG9iU3RvcmVMZWFzZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsIGZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLCBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKTsKKworICAgIHdoZW4obW9ja0JhY2tlbmQuZXhpc3RzKGJsb2JVcmkpKS50aGVuUmV0dXJuKHRydWUpOworICAgIHdoZW4obW9ja0JhY2tlbmQub3BlbkZvcldyaXRlKGxlYXNlVXJpKSkudGhlblRocm93KG5ldyBJT0V4Y2VwdGlvbigpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIudHJ5VG9TaGFyZUJlZm9yZURvd25sb2FkKGZpbGVHcm91cCwgZmlsZSwgbmV3RmlsZUtleSkuZ2V0KCk7CisKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPSBzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKG5ld0ZpbGVLZXkpLmdldCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZSkuaXNFcXVhbFRvKGV4aXN0aW5nU2hhcmVkRmlsZSk7CisKKyAgICBBcmd1bWVudENhcHRvcjxWb2lkPiBtZGRBbmRyb2lkU2hhcmluZ0xvZ0FyZ3VtZW50Q2FwdG9yID0gQXJndW1lbnRDYXB0b3IuZm9yQ2xhc3MoVm9pZC5jbGFzcyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0cnlUb1NoYXJlQmVmb3JlRG93bmxvYWRfZmlsZVN0b3JhZ2VUaHJvd3NMaW1pdEV4Y2VlZGVkRXhjZXB0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQ3JlYXRlIGEgZmlsZSBncm91cCB3aXRoIGV4cGlyYXRpb24gZGF0ZSBiaWdnZXIgdGhhbiB0aGUgZXhwaXJhdGlvbiBkYXRlIG9mIHRoZSBleGlzdGluZworICAgIC8vIFNoYXJlZEZpbGUuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MgKyAxKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBDcmVhdGUgYSB0by1iZS1zaGFyZWQgZmlsZQorICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBleGlzdGluZ1NoYXJlZEZpbGUpLmdldCgpOworCisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCkpOworICAgIFVyaSBsZWFzZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0QmxvYlN0b3JlTGVhc2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyArIDEpOworICAgIC8vIFRoZSBmaWxlIGlzIGF2YWlsYWJsZSBpbiB0aGUgYmxvYiBzdG9yYWdlCisgICAgd2hlbihtb2NrQmFja2VuZC5leGlzdHMoYmxvYlVyaSkpLnRoZW5SZXR1cm4odHJ1ZSk7CisgICAgLy8gV3JpdGluZyB0aGUgbGVhc2UgdGhyb3dzIGFuIGV4Y2VwdGlvbgorICAgIHdoZW4obW9ja0JhY2tlbmQub3BlbkZvcldyaXRlKGxlYXNlVXJpKSkudGhlblRocm93KG5ldyBMaW1pdEV4Y2VlZGVkRXhjZXB0aW9uKCkpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQmVmb3JlRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkub3BlbkZvcldyaXRlKGJsb2JVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkub3BlbkZvcldyaXRlKGxlYXNlVXJpKTsKKworICAgIFNoYXJlZEZpbGUgc2hhcmVkRmlsZSA9IHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUobmV3RmlsZUtleSkuZ2V0KCk7CisgICAgLy8gU2luY2UgdGhlcmUgd2FzIGFuIGV4Y2VwdGlvbiwgdGhlIGV4aXN0aW5nIHNoYXJlZCBmaWxlIGRpZG4ndCB1cGRhdGUgdGhlIGV4cGlyYXRpb24gZGF0ZS4KKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUpLmlzRXF1YWxUbyhleGlzdGluZ1NoYXJlZEZpbGUpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdHJ5VG9TaGFyZUFmdGVyRG93bmxvYWRfYWxyZWFkeVNoYXJlZF9zYW1lRmlsZUdyb3VwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBTaGFyZWRGaWxlIGV4aXN0aW5nU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJmaWxlTmFtZSIpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJlZCh0cnVlKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCkpCisgICAgICAgICAgICAuc2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIGV4aXN0aW5nU2hhcmVkRmlsZSkuZ2V0KCk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyLnRyeVRvU2hhcmVBZnRlckRvd25sb2FkKGZpbGVHcm91cCwgZmlsZSwgbmV3RmlsZUtleSkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmV4aXN0cyhhbnkoKSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5vcGVuRm9yV3JpdGUoYW55KCkpOworCisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0gc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUpLmlzRXF1YWxUbyhleGlzdGluZ1NoYXJlZEZpbGUpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdHJ5VG9TaGFyZUFmdGVyRG93bmxvYWRfYWxyZWFkeVNoYXJlZF9kaWZmZXJlbnRGaWxlR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgYSBmaWxlIGdyb3VwIHdpdGggZXhwaXJhdGlvbiBkYXRlIGJpZ2dlciB0aGFuIHRoZSBleHBpcmF0aW9uIGRhdGUgb2YgdGhlIGV4aXN0aW5nCisgICAgLy8gU2hhcmVkRmlsZS4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKHRydWUpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bShmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSkKKyAgICAgICAgICAgIC5zZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyAtIDEpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIGV4aXN0aW5nU2hhcmVkRmlsZSkuZ2V0KCk7CisKKyAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSk7CisgICAgVXJpIGxlYXNlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRCbG9iU3RvcmVMZWFzZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsIGZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLCBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIudHJ5VG9TaGFyZUFmdGVyRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KS5nZXQoKTsKKworICAgIC8vIG9wZW5Gb3JXcml0ZSBpcyBjYWxsZWQgb25seSBvbmNlIGZvciBhY3F1aXJpbmcgdGhlIGxlYXNlLgorICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkuZXhpc3RzKGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLm9wZW5Gb3JXcml0ZShsZWFzZVVyaSk7CisKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPSBzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKG5ld0ZpbGVLZXkpLmdldCgpOworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBTaGFyZWRGaWxlIGhhcyB1cGRhdGVkIGl0cyBleHBpcmF0aW9uIGRhdGUgYWZ0ZXIgdGhlIGRvd25sb2FkLgorICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZS5nZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZS5nZXRBbmRyb2lkU2hhcmVkKCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkobmV3RmlsZUtleSkuZ2V0KCkpLmlzRXF1YWxUbyhibG9iVXJpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRyeVRvU2hhcmVBZnRlckRvd25sb2FkX3RvQmVTaGFyZWRGaWxlX2Jsb2JFeGlzdHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgYSBmaWxlIGdyb3VwIHdpdGggZXhwaXJhdGlvbiBkYXRlIGJpZ2dlciB0aGFuIHRoZSBleHBpcmF0aW9uIGRhdGUgb2YgdGhlIGV4aXN0aW5nCisgICAgLy8gU2hhcmVkRmlsZS4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBleGlzdGluZ1NoYXJlZEZpbGUpLmdldCgpOworCisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCkpOworICAgIFVyaSBsZWFzZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0QmxvYlN0b3JlTGVhc2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyk7CisgICAgLy8gVGhlIGZpbGUgaXMgYXZhaWxhYmxlIGluIHRoZSBibG9iIHN0b3JhZ2UKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmV4aXN0cyhibG9iVXJpKSkudGhlblJldHVybih0cnVlKTsKKworICAgIHNpbXVsYXRlRG93bmxvYWQoZmlsZSwgZXhpc3RpbmdTaGFyZWRGaWxlLmdldEZpbGVOYW1lKCkpOworICAgIFVyaSBvbkRldmljZXVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbmV3RmlsZUtleS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgZXhpc3RpbmdTaGFyZWRGaWxlLmdldEZpbGVOYW1lKCksCisgICAgICAgICAgICBuZXdGaWxlS2V5LmdldENoZWNrc3VtKCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAvKiBpbnN0YW5jZUlkPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZhbHNlKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzVHJ1ZSgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZChmaWxlR3JvdXAsIGZpbGUsIG5ld0ZpbGVLZXkpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5leGlzdHMoYmxvYlVyaSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kKS5vcGVuRm9yV3JpdGUobGVhc2VVcmkpOworCisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0gc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgU2hhcmVkRmlsZSBoYXMgdXBkYXRlZCBpdHMgZXhwaXJhdGlvbiBkYXRlIGFmdGVyIHRoZSBkb3dubG9hZC4KKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUuZ2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKCkpLmlzRXF1YWxUbyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUuZ2V0QW5kcm9pZFNoYXJlZCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKG5ld0ZpbGVLZXkpLmdldCgpKS5pc0VxdWFsVG8oYmxvYlVyaSk7CisKKyAgICAvLyBMb2NhbCBjb3B5IGhhcyBiZWVuIGRlbGV0ZWQuCisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMob25EZXZpY2V1cmkpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZF90b0JlU2hhcmVkRmlsZV9jYW5CZUNvcGllZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENyZWF0ZSBhIGZpbGUgZ3JvdXAgd2l0aCBleHBpcmF0aW9uIGRhdGUgYmlnZ2VyIHRoYW4gdGhlIGV4cGlyYXRpb24gZGF0ZSBvZiB0aGUgZXhpc3RpbmcKKyAgICAvLyBTaGFyZWRGaWxlLgorICAgIEZpbGUgdGVtcEZpbGUgPSBmb2xkZXIubmV3RmlsZSgiYmxvYkZpbGUiKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBleGlzdGluZ1NoYXJlZEZpbGUpLmdldCgpOworCisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCkpOworICAgIFVyaSBsZWFzZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0QmxvYlN0b3JlTGVhc2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyk7CisgICAgLy8gVGhlIGZpbGUgaXNuJ3QgYXZhaWxhYmxlIHlldCBpbiB0aGUgYmxvYiBzdG9yYWdlCisgICAgd2hlbihtb2NrQmFja2VuZC5leGlzdHMoYmxvYlVyaSkpLnRoZW5SZXR1cm4oZmFsc2UpOworICAgIHdoZW4obW9ja0JhY2tlbmQub3BlbkZvcldyaXRlKGJsb2JVcmkpKS50aGVuUmV0dXJuKG5ldyBGaWxlT3V0cHV0U3RyZWFtKHRlbXBGaWxlKSk7CisKKyAgICBzaW11bGF0ZURvd25sb2FkKGZpbGUsIGV4aXN0aW5nU2hhcmVkRmlsZS5nZXRGaWxlTmFtZSgpKTsKKyAgICBVcmkgb25EZXZpY2V1cmkgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE9uRGV2aWNlVXJpKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG5ld0ZpbGVLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgIGV4aXN0aW5nU2hhcmVkRmlsZS5nZXRGaWxlTmFtZSgpLAorICAgICAgICAgICAgbmV3RmlsZUtleS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgLyogaW5zdGFuY2VJZD0gKi8gT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBmYWxzZSk7CisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMob25EZXZpY2V1cmkpKS5pc1RydWUoKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIudHJ5VG9TaGFyZUFmdGVyRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KS5nZXQoKTsKKworICAgIC8vIG9wZW5Gb3JXcml0ZSBpcyBjYWxsZWQgb25jZSBmb3Igd3JpdGluZyB0aGUgYmxvYiwgb25jZSBmb3IgYWNxdWlyaW5nIHRoZSBsZWFzZS4KKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLm9wZW5Gb3JXcml0ZShibG9iVXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLm9wZW5Gb3JXcml0ZShsZWFzZVVyaSk7CisKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPSBzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKG5ld0ZpbGVLZXkpLmdldCgpOworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBTaGFyZWRGaWxlIGhhcyB1cGRhdGVkIGl0cyBleHBpcmF0aW9uIGRhdGUgYWZ0ZXIgdGhlIGRvd25sb2FkLgorICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZS5nZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoKSkuaXNFcXVhbFRvKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZS5nZXRBbmRyb2lkU2hhcmVkKCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZU1hbmFnZXIuZ2V0T25EZXZpY2VVcmkobmV3RmlsZUtleSkuZ2V0KCkpLmlzRXF1YWxUbyhibG9iVXJpKTsKKworICAgIC8vIExvY2FsIGNvcHkgaGFzIGJlZW4gZGVsZXRlZC4KKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRyeVRvU2hhcmVBZnRlckRvd25sb2FkX25vblRvQmVTaGFyZWRGaWxlX25ldmVyU2hhcmVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gQ3JlYXRlIGEgZmlsZSBncm91cCB3aXRoIGV4cGlyYXRpb24gZGF0ZSBiaWdnZXIgdGhhbiB0aGUgZXhwaXJhdGlvbiBkYXRlIG9mIHRoZSBleGlzdGluZworICAgIC8vIFNoYXJlZEZpbGUuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBTaGFyZWRGaWxlIGV4aXN0aW5nU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJmaWxlTmFtZSIpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJlZChmYWxzZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEud3JpdGUobmV3RmlsZUtleSwgZXhpc3RpbmdTaGFyZWRGaWxlKS5nZXQoKTsKKworICAgIEZpbGUgb25EZXZpY2VGaWxlID0gc2ltdWxhdGVEb3dubG9hZChmaWxlLCBleGlzdGluZ1NoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSk7CisgICAgVXJpIG9uRGV2aWNldXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBleGlzdGluZ1NoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSwKKyAgICAgICAgICAgIG5ld0ZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgZmFsc2UpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKG9uRGV2aWNldXJpKSkuaXNUcnVlKCk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyLnRyeVRvU2hhcmVBZnRlckRvd25sb2FkKGZpbGVHcm91cCwgZmlsZSwgbmV3RmlsZUtleSkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmV4aXN0cyhhbnkoKSk7CisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5vcGVuRm9yV3JpdGUoYW55KCkpOworCisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0gc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgU2hhcmVkRmlsZSBoYXMgdXBkYXRlZCBpdHMgZXhwaXJhdGlvbiBkYXRlIGFmdGVyIHRoZSBkb3dubG9hZC4KKyAgICBTaGFyZWRGaWxlIGV4cGVjdGVkU2hhcmVkRmlsZSA9CisgICAgICAgIGV4aXN0aW5nU2hhcmVkRmlsZS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlKS5pc0VxdWFsVG8oZXhwZWN0ZWRTaGFyZWRGaWxlKTsKKworICAgIC8vIExvY2FsIGNvcHkgc3RpbGwgYXZhaWxhYmxlLgorICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKG9uRGV2aWNldXJpKSkuaXNUcnVlKCk7CisgICAgb25EZXZpY2VGaWxlLmRlbGV0ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdHJ5VG9TaGFyZUFmdGVyRG93bmxvYWRfdG9CZVNoYXJlZEZpbGVfbmV2ZXJTaGFyZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgYSBmaWxlIGdyb3VwIHdpdGggZXhwaXJhdGlvbiBkYXRlIGJpZ2dlciB0aGFuIHRoZSBleHBpcmF0aW9uIGRhdGUgb2YgdGhlIGV4aXN0aW5nCisgICAgLy8gU2hhcmVkRmlsZS4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW5lZCBpbiBhIHJlYWwgc2NlbmFyaW8uCisgICAgZmlsZSA9IGZpbGUudG9CdWlsZGVyKCkuc2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgiIikuYnVpbGQoKTsKKworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgU2hhcmVkRmlsZSBleGlzdGluZ1NoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgiZmlsZU5hbWUiKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyZWQoZmFsc2UpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIGV4aXN0aW5nU2hhcmVkRmlsZSkuZ2V0KCk7CisKKyAgICBGaWxlIG9uRGV2aWNlRmlsZSA9IHNpbXVsYXRlRG93bmxvYWQoZmlsZSwgZXhpc3RpbmdTaGFyZWRGaWxlLmdldEZpbGVOYW1lKCkpOworICAgIFVyaSBvbkRldmljZXVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbmV3RmlsZUtleS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgZXhpc3RpbmdTaGFyZWRGaWxlLmdldEZpbGVOYW1lKCksCisgICAgICAgICAgICBuZXdGaWxlS2V5LmdldENoZWNrc3VtKCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAvKiBpbnN0YW5jZUlkPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZhbHNlKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzVHJ1ZSgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZChmaWxlR3JvdXAsIGZpbGUsIG5ld0ZpbGVLZXkpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5leGlzdHMoYW55KCkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkub3BlbkZvcldyaXRlKGFueSgpKTsKKworICAgIFNoYXJlZEZpbGUgc2hhcmVkRmlsZSA9IHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUobmV3RmlsZUtleSkuZ2V0KCk7CisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIFNoYXJlZEZpbGUgaGFzIHVwZGF0ZWQgaXRzIGV4cGlyYXRpb24gZGF0ZSBhZnRlciB0aGUgZG93bmxvYWQuCisgICAgU2hhcmVkRmlsZSBleHBlY3RlZFNoYXJlZEZpbGUgPQorICAgICAgICBleGlzdGluZ1NoYXJlZEZpbGUudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUykKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZSkuaXNFcXVhbFRvKGV4cGVjdGVkU2hhcmVkRmlsZSk7CisKKyAgICAvLyBMb2NhbCBjb3B5IHN0aWxsIGF2YWlsYWJsZS4KKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzVHJ1ZSgpOworICAgIG9uRGV2aWNlRmlsZS5kZWxldGUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRyeVRvU2hhcmVBZnRlckRvd25sb2FkX2Jsb2JVcmlOb3RTdXBwb3J0ZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBGaWxlU3RvcmFnZSB3aXRob3V0IEJsb2JTdG9yZUJhY2tlbmQKKyAgICBmaWxlU3RvcmFnZSA9CisgICAgICAgIG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEFycmF5cy5hc0xpc3QoQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuYnVpbGQoKSkpOworICAgIGZpbGVHcm91cE1hbmFnZXIgPQorICAgICAgICBuZXcgRmlsZUdyb3VwTWFuYWdlcigKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrTG9nZ2VyLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLAorICAgICAgICAgICAgc2hhcmVkRmlsZU1hbmFnZXIsCisgICAgICAgICAgICB0ZXN0Q2xvY2ssCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrQWNjb3VudFNvdXJjZSksCisgICAgICAgICAgICBTRVFVRU5USUFMX0NPTlRST0xfRVhFQ1VUT1IsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZpbGVTdG9yYWdlLAorICAgICAgICAgICAgZG93bmxvYWRTdGFnZU1hbmFnZXIsCisgICAgICAgICAgICBmbGFncyk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gQ3JlYXRlIGEgdG8tYmUtc2hhcmVkIGZpbGUKKyAgICBEYXRhRmlsZSBmaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlU2hhcmVkRGF0YUZpbGUoImZpbGVJZCIsIDApOworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgLy8gU2V0IHRoZSBmaWxlIG1ldGFkYXRhIGFzIGRvd25sb2FkIGNvbXBsZXRlZCBhbmQgbm9uIHNoYXJlZAorICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBleGlzdGluZ1NoYXJlZEZpbGUpLmdldCgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZChmaWxlR3JvdXAsIGZpbGUsIG5ld0ZpbGVLZXkpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5vcGVuRm9yV3JpdGUoYW55KCkpOworCisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0gc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUpLmlzRXF1YWxUbyhleGlzdGluZ1NoYXJlZEZpbGUpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdHJ5VG9TaGFyZUFmdGVyRG93bmxvYWRfbm9uRXhpc3RlbnRGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gdHJ5VG9TaGFyZUZ1dHVyZSA9CisgICAgICAgIGZpbGVHcm91cE1hbmFnZXIudHJ5VG9TaGFyZUFmdGVyRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleGNlcHRpb24gPSBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCB0cnlUb1NoYXJlRnV0dXJlOjpnZXQpOworICAgIGFzc2VydFRoYXQoZXhjZXB0aW9uKS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24uY2xhc3MpOworCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5leGlzdHMoYW55KCkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkub3BlbkZvcldyaXRlKGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyLCBuZXZlcigpKQorICAgICAgICAuc2V0QW5kcm9pZFNoYXJlZERvd25sb2FkZWRGaWxlRW50cnkoYW55KCksIGFueSgpLCBhbnlMb25nKCkpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIsIG5ldmVyKCkpLnVwZGF0ZU1heEV4cGlyYXRpb25EYXRlU2VjcyhuZXdGaWxlS2V5LCAwKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRyeVRvU2hhcmVBZnRlckRvd25sb2FkX3VwZGF0ZU1heEV4cGlyYXRpb25EYXRlU2Vjc1JldHVybnNGYWxzZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIE1vY2sgU2hhcmVkRmlsZU1hbmFnZXIgdG8gdGVzdCBmYWlsdXJlIHNjZW5hcmlvLgorICAgIHJlc2V0RmlsZUdyb3VwTWFuYWdlcihmaWxlR3JvdXBzTWV0YWRhdGEsIG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisgICAgLy8gQ3JlYXRlIGEgZmlsZSBncm91cCB3aXRoIGV4cGlyYXRpb24gZGF0ZSBiaWdnZXIgdGhhbiB0aGUgZXhwaXJhdGlvbiBkYXRlIG9mIHRoZSBleGlzdGluZworICAgIC8vIFNoYXJlZEZpbGUuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uZGl0aW9ucyhEb3dubG9hZENvbmRpdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBTaGFyZWRGaWxlIGV4aXN0aW5nU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJmaWxlTmFtZSIpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJlZChmYWxzZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZXhpc3RpbmdTaGFyZWRGaWxlKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIudXBkYXRlTWF4RXhwaXJhdGlvbkRhdGVTZWNzKAorICAgICAgICAgICAgbmV3RmlsZUtleSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUykpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKSk7CisKKyAgICBGaWxlIG9uRGV2aWNlRmlsZSA9IHNpbXVsYXRlRG93bmxvYWQoZmlsZSwgZXhpc3RpbmdTaGFyZWRGaWxlLmdldEZpbGVOYW1lKCkpOworICAgIFVyaSBvbkRldmljZXVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbmV3RmlsZUtleS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgZXhpc3RpbmdTaGFyZWRGaWxlLmdldEZpbGVOYW1lKCksCisgICAgICAgICAgICBuZXdGaWxlS2V5LmdldENoZWNrc3VtKCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAvKiBpbnN0YW5jZUlkPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZhbHNlKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzVHJ1ZSgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZChmaWxlR3JvdXAsIGZpbGUsIG5ld0ZpbGVLZXkpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5leGlzdHMoYW55KCkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCwgbmV2ZXIoKSkub3BlbkZvcldyaXRlKGFueSgpKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyLCBuZXZlcigpKQorICAgICAgICAuc2V0QW5kcm9pZFNoYXJlZERvd25sb2FkZWRGaWxlRW50cnkoYW55KCksIGFueSgpLCBhbnlMb25nKCkpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpCisgICAgICAgIC51cGRhdGVNYXhFeHBpcmF0aW9uRGF0ZVNlY3MobmV3RmlsZUtleSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyk7CisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMob25EZXZpY2V1cmkpKS5pc1RydWUoKTsKKyAgICBvbkRldmljZUZpbGUuZGVsZXRlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZF9zZXRBbmRyb2lkU2hhcmVkRG93bmxvYWRlZEZpbGVFbnRyeVJldHVybnNGYWxzZSgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBNb2NrIFNoYXJlZEZpbGVNYW5hZ2VyIHRvIHRlc3QgZmFpbHVyZSBzY2VuYXJpby4KKyAgICByZXNldEZpbGVHcm91cE1hbmFnZXIoZmlsZUdyb3Vwc01ldGFkYXRhLCBtb2NrU2hhcmVkRmlsZU1hbmFnZXIpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBDcmVhdGUgYSB0by1iZS1zaGFyZWQgZmlsZQorICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKG5ld0ZpbGVLZXkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShleGlzdGluZ1NoYXJlZEZpbGUpKTsKKyAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSk7CisgICAgVXJpIGxlYXNlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRCbG9iU3RvcmVMZWFzZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsIGZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLCBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKTsKKyAgICAvLyBUaGUgZmlsZSBpcyBhdmFpbGFibGUgaW4gdGhlIGJsb2Igc3RvcmFnZQorICAgIHdoZW4obW9ja0JhY2tlbmQuZXhpc3RzKGJsb2JVcmkpKS50aGVuUmV0dXJuKHRydWUpOworCisgICAgLy8gTGFzdCBvcGVyYXRpb24gZmFpbHMKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5zZXRBbmRyb2lkU2hhcmVkRG93bmxvYWRlZEZpbGVFbnRyeSgKKyAgICAgICAgICAgIG5ld0ZpbGVLZXksIGZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLCBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmFsc2UpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci51cGRhdGVNYXhFeHBpcmF0aW9uRGF0ZVNlY3MobmV3RmlsZUtleSwgMCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKworICAgIEZpbGUgb25EZXZpY2VGaWxlID0gc2ltdWxhdGVEb3dubG9hZChmaWxlLCBleGlzdGluZ1NoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSk7CisgICAgVXJpIG9uRGV2aWNldXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBleGlzdGluZ1NoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSwKKyAgICAgICAgICAgIG5ld0ZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgZmFsc2UpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKG9uRGV2aWNldXJpKSkuaXNUcnVlKCk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyLnRyeVRvU2hhcmVBZnRlckRvd25sb2FkKGZpbGVHcm91cCwgZmlsZSwgbmV3RmlsZUtleSkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLmV4aXN0cyhibG9iVXJpKTsKKyAgICAvLyBvcGVuRm9yV3JpdGUgaXMgY2FsbGVkIG9ubHkgb25jZSBmb3IgYWNxdWlyaW5nIHRoZSBsZWFzZS4KKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLm9wZW5Gb3JXcml0ZShibG9iVXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLm9wZW5Gb3JXcml0ZShsZWFzZVVyaSk7CisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikudXBkYXRlTWF4RXhwaXJhdGlvbkRhdGVTZWNzKG5ld0ZpbGVLZXksIDApOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKG9uRGV2aWNldXJpKSkuaXNUcnVlKCk7CisgICAgb25EZXZpY2VGaWxlLmRlbGV0ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdHJ5VG9TaGFyZUFmdGVyRG93bmxvYWRfY29weUJsb2JUaHJvd3NJT0V4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMikudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBDcmVhdGUgYSB0by1iZS1zaGFyZWQgZmlsZQorICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVTaGFyZWREYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBleGlzdGluZ1NoYXJlZEZpbGUpLmdldCgpOworCisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCkpOworICAgIFVyaSBsZWFzZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0QmxvYlN0b3JlTGVhc2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyk7CisgICAgLy8gVGhlIGZpbGUgaXNuJ3QgYXZhaWxhYmxlIGluIHRoZSBibG9iIHN0b3JhZ2UKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmV4aXN0cyhibG9iVXJpKSkudGhlblJldHVybihmYWxzZSk7CisgICAgLy8gQ29weWluZyB0aGUgYmxvYiB0aHJvd3MgYW4gZXhjZXB0aW9uCisgICAgd2hlbihtb2NrQmFja2VuZC5vcGVuRm9yV3JpdGUoYmxvYlVyaSkpLnRoZW5UaHJvdyhuZXcgSU9FeGNlcHRpb24oKSk7CisKKyAgICBGaWxlIG9uRGV2aWNlRmlsZSA9IHNpbXVsYXRlRG93bmxvYWQoZmlsZSwgZXhpc3RpbmdTaGFyZWRGaWxlLmdldEZpbGVOYW1lKCkpOworICAgIFVyaSBvbkRldmljZXVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0T25EZXZpY2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbmV3RmlsZUtleS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgZXhpc3RpbmdTaGFyZWRGaWxlLmdldEZpbGVOYW1lKCksCisgICAgICAgICAgICBuZXdGaWxlS2V5LmdldENoZWNrc3VtKCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAvKiBpbnN0YW5jZUlkPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZhbHNlKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzVHJ1ZSgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci50cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZChmaWxlR3JvdXAsIGZpbGUsIG5ld0ZpbGVLZXkpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tCYWNrZW5kLCBuZXZlcigpKS5vcGVuRm9yV3JpdGUobGVhc2VVcmkpOworCisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0gc2hhcmVkRmlsZU1hbmFnZXIuZ2V0U2hhcmVkRmlsZShuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUpLmlzRXF1YWxUbyhleGlzdGluZ1NoYXJlZEZpbGUpOworCisgICAgLy8gTG9jYWwgY29weSBzdGlsbCBhdmFpbGFibGUuCisgICAgYXNzZXJ0VGhhdChmaWxlU3RvcmFnZS5leGlzdHMob25EZXZpY2V1cmkpKS5pc1RydWUoKTsKKyAgICBvbkRldmljZUZpbGUuZGVsZXRlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0cnlUb1NoYXJlQWZ0ZXJEb3dubG9hZF9maWxlU3RvcmFnZVRocm93c0xpbWl0RXhjZWVkZWRFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgYSBmaWxlIGdyb3VwIHdpdGggZXhwaXJhdGlvbiBkYXRlIGJpZ2dlciB0aGFuIHRoZSBleHBpcmF0aW9uIGRhdGUgb2YgdGhlIGV4aXN0aW5nCisgICAgLy8gU2hhcmVkRmlsZS4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5zZXRFeHBpcmF0aW9uRGF0ZVNlY3MoRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyArIDEpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIENyZWF0ZSBhIHRvLWJlLXNoYXJlZCBmaWxlCisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgU2hhcmVkRmlsZSBleGlzdGluZ1NoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgiZmlsZU5hbWUiKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyZWQoZmFsc2UpCisgICAgICAgICAgICAuc2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIGV4aXN0aW5nU2hhcmVkRmlsZSkuZ2V0KCk7CisKKyAgICBVcmkgYmxvYlVyaSA9IERpcmVjdG9yeVV0aWwuZ2V0QmxvYlVyaShjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSk7CisgICAgVXJpIGxlYXNlVXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRCbG9iU3RvcmVMZWFzZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsIGZpbGUuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpLCBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTICsgMSk7CisgICAgLy8gVGhlIGZpbGUgaXMgYXZhaWxhYmxlIGluIHRoZSBibG9iIHN0b3JhZ2UKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmV4aXN0cyhibG9iVXJpKSkudGhlblJldHVybih0cnVlKTsKKworICAgIEZpbGUgb25EZXZpY2VGaWxlID0gc2ltdWxhdGVEb3dubG9hZChmaWxlLCBleGlzdGluZ1NoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSk7CisgICAgVXJpIG9uRGV2aWNldXJpID0KKyAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBuZXdGaWxlS2V5LmdldEFsbG93ZWRSZWFkZXJzKCksCisgICAgICAgICAgICBleGlzdGluZ1NoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSwKKyAgICAgICAgICAgIG5ld0ZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIC8qIGluc3RhbmNlSWQ9ICovIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgZmFsc2UpOworICAgIGFzc2VydFRoYXQoZmlsZVN0b3JhZ2UuZXhpc3RzKG9uRGV2aWNldXJpKSkuaXNUcnVlKCk7CisKKyAgICAvLyBXcml0aW5nIHRoZSBsZWFzZSB0aHJvd3MgYW4gZXhjZXB0aW9uCisgICAgd2hlbihtb2NrQmFja2VuZC5vcGVuRm9yV3JpdGUobGVhc2VVcmkpKS50aGVuVGhyb3cobmV3IExpbWl0RXhjZWVkZWRFeGNlcHRpb24oKSk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyLnRyeVRvU2hhcmVBZnRlckRvd25sb2FkKGZpbGVHcm91cCwgZmlsZSwgbmV3RmlsZUtleSkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLm9wZW5Gb3JXcml0ZShibG9iVXJpKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQpLm9wZW5Gb3JXcml0ZShsZWFzZVVyaSk7CisKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPSBzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKG5ld0ZpbGVLZXkpLmdldCgpOworICAgIC8vIEV2ZW4gaWYgdGhlcmUgd2FzIGFuIGV4Y2VwdGlvbiwgdGhlIFNoYXJlZEZpbGUgaGFzIHVwZGF0ZWQgaXRzIGV4cGlyYXRpb24gZGF0ZSBhZnRlciB0aGUKKyAgICAvLyBkb3dubG9hZC4KKyAgICBTaGFyZWRGaWxlIGV4cGVjdGVkU2hhcmVkRmlsZSA9CisgICAgICAgIGV4aXN0aW5nU2hhcmVkRmlsZS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE1heEV4cGlyYXRpb25EYXRlU2VjcyhGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTICsgMSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZSkuaXNFcXVhbFRvKGV4cGVjdGVkU2hhcmVkRmlsZSk7CisKKyAgICAvLyBMb2NhbCBjb3B5IHN0aWxsIGF2YWlsYWJsZS4KKyAgICBhc3NlcnRUaGF0KGZpbGVTdG9yYWdlLmV4aXN0cyhvbkRldmljZXVyaSkpLmlzVHJ1ZSgpOworICAgIG9uRGV2aWNlRmlsZS5kZWxldGUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRyeVRvU2hhcmVBZnRlckRvd25sb2FkX2Jsb2JFeGlzdHNfZGVsZXRlTG9jYWxDb3B5RmFpbHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgYSBmaWxlIGdyb3VwIHdpdGggZXhwaXJhdGlvbiBkYXRlIGJpZ2dlciB0aGFuIHRoZSBleHBpcmF0aW9uIGRhdGUgb2YgdGhlIGV4aXN0aW5nCisgICAgLy8gU2hhcmVkRmlsZS4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25kaXRpb25zKERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIFNoYXJlZEZpbGUgZXhpc3RpbmdTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGVOYW1lIikKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKGZhbHNlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBleGlzdGluZ1NoYXJlZEZpbGUpLmdldCgpOworCisgICAgVXJpIGJsb2JVcmkgPSBEaXJlY3RvcnlVdGlsLmdldEJsb2JVcmkoY29udGV4dCwgZmlsZS5nZXRBbmRyb2lkU2hhcmluZ0NoZWNrc3VtKCkpOworICAgIFVyaSBsZWFzZVVyaSA9CisgICAgICAgIERpcmVjdG9yeVV0aWwuZ2V0QmxvYlN0b3JlTGVhc2VVcmkoCisgICAgICAgICAgICBjb250ZXh0LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyk7CisgICAgLy8gVGhlIGZpbGUgaXMgYXZhaWxhYmxlIGluIHRoZSBibG9iIHN0b3JhZ2UKKyAgICB3aGVuKG1vY2tCYWNrZW5kLmV4aXN0cyhibG9iVXJpKSkudGhlblJldHVybih0cnVlKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIudHJ5VG9TaGFyZUFmdGVyRG93bmxvYWQoZmlsZUdyb3VwLCBmaWxlLCBuZXdGaWxlS2V5KS5nZXQoKTsKKworICAgIC8vIG9wZW5Gb3JXcml0ZSBpcyBjYWxsZWQgb25seSBvbmNlIGZvciBhY3F1aXJpbmcgdGhlIGxlYXNlLgorICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZXhpc3RzKGJsb2JVcmkpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkub3BlbkZvcldyaXRlKGxlYXNlVXJpKTsKKworICAgIFNoYXJlZEZpbGUgc2hhcmVkRmlsZSA9IHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUobmV3RmlsZUtleSkuZ2V0KCk7CisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIFNoYXJlZEZpbGUgaGFzIHVwZGF0ZWQgaXRzIGV4cGlyYXRpb24gZGF0ZSBhZnRlciB0aGUgZG93bmxvYWQuCisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlLmdldE1heEV4cGlyYXRpb25EYXRlU2VjcygpKS5pc0VxdWFsVG8oRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlLmdldEFuZHJvaWRTaGFyZWQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlTWFuYWdlci5nZXRPbkRldmljZVVyaShuZXdGaWxlS2V5KS5nZXQoKSkuaXNFcXVhbFRvKGJsb2JVcmkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFZlcmlmeVBlbmRpbmdHcm91cERvd25sb2FkZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSAyIGdyb3VwcyB0byB0aGUgcGVuZGluZyBzaGFyZWQgcHJlZnMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDEgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cDEpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAyID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMik7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkyLCBmaWxlR3JvdXAyKTsKKworICAgIC8vIE1ha2UgdGhlIHZlcmlmeSBkb3dubG9hZCBjYWxsIGZhaWwgZm9yIG9uZSBmaWxlIGluIHRoZSBmaXJzdCBncm91cC4KKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAxLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfSU5fUFJPR1JFU1MpKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAyLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIHRlc3RDbG9jay5zZXQoLyogbWlsbGlzICovIDEwMDApOworCisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgICAgICAgICAudmVyaWZ5UGVuZGluZ0dyb3VwRG93bmxvYWRlZCh0ZXN0S2V5LCBmaWxlR3JvdXAxLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc0VxdWFsVG8oR3JvdXBEb3dubG9hZFN0YXR1cy5QRU5ESU5HKTsKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgIC52ZXJpZnlQZW5kaW5nR3JvdXBEb3dubG9hZGVkKHRlc3RLZXkyLCBmaWxlR3JvdXAyLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc0VxdWFsVG8oR3JvdXBEb3dubG9hZFN0YXR1cy5ET1dOTE9BREVEKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBwZW5kaW5nIGdyb3VwIGlzIHN0aWxsIHBhcnQgb2YgcGVuZGluZyBncm91cHMgcHJlZnMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBlbmRpbmdHcm91cDEgPSByZWFkUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5KTsKKyAgICBhc3NlcnRUaGF0KHBlbmRpbmdHcm91cDEpLmlzRXF1YWxUbyhmaWxlR3JvdXAxKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBwZW5kaW5nIGdyb3VwIGlzIG5vdCB3cml0dGVuIGludG8gbWV0YWRhdGEuCisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOdWxsKCk7CisKKyAgICBmaWxlR3JvdXAyID0gRmlsZUdyb3VwVXRpbC5zZXREb3dubG9hZGVkVGltZXN0YW1wSW5NaWxsaXMoZmlsZUdyb3VwMiwgMTAwMCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgY29tcGxldGVseSBkb3dubG9hZGVkIGdyb3VwIGlzIHdyaXR0ZW4gaW50byBtZXRhZGF0YS4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZEdyb3VwMiA9IHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkyKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRHcm91cDIpLmlzRXF1YWxUbyhmaWxlR3JvdXAyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RWZXJpZnlBbGxQZW5kaW5nR3JvdXBzRG93bmxvYWRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdyaXRlIDIgZ3JvdXBzIHRvIHRoZSBwZW5kaW5nIHNoYXJlZCBwcmVmcy4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZmlsZUdyb3VwMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDIgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAyKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleTIsIGZpbGVHcm91cDIpOworCisgICAgLy8gTWFrZSB0aGUgdmVyaWZ5IGRvd25sb2FkIGNhbGwgZmFpbCBmb3Igb25lIGZpbGUgaW4gdGhlIGZpcnN0IGdyb3VwLgorICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cDEsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUykpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cDIsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkpOworCisgICAgdGVzdENsb2NrLnNldCgvKiBtaWxsaXMgKi8gMTAwMCk7CisgICAgZmlsZUdyb3VwTWFuYWdlci52ZXJpZnlBbGxQZW5kaW5nR3JvdXBzRG93bmxvYWRlZChub0N1c3RvbVZhbGlkYXRpb24oKSkuZ2V0KCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgcGVuZGluZyBncm91cCBpcyBzdGlsbCBwYXJ0IG9mIHBlbmRpbmcgZ3JvdXBzIHByZWZzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXAxID0gcmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSk7CisgICAgTWRkVGVzdFV0aWwuYXNzZXJ0TWVzc2FnZUVxdWFscyhmaWxlR3JvdXAxLCBwZW5kaW5nR3JvdXAxKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBwZW5kaW5nIGdyb3VwIGlzIG5vdCB3cml0dGVuIGludG8gbWV0YWRhdGEuCisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOdWxsKCk7CisKKyAgICBmaWxlR3JvdXAyID0gRmlsZUdyb3VwVXRpbC5zZXREb3dubG9hZGVkVGltZXN0YW1wSW5NaWxsaXMoZmlsZUdyb3VwMiwgMTAwMCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgY29tcGxldGVseSBkb3dubG9hZGVkIGdyb3VwIGlzIHdyaXR0ZW4gaW50byBtZXRhZGF0YS4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZEdyb3VwMiA9IHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkyKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRHcm91cDIpLmlzRXF1YWxUbyhmaWxlR3JvdXAyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RWZXJpZnlBbGxQZW5kaW5nR3JvdXBzRG93bmxvYWRlZF9leGlzdGluZ0Rvd25sb2FkZWRHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFdyaXRlIDIgZ3JvdXBzIHRvIHRoZSBwZW5kaW5nIHNoYXJlZCBwcmVmcy4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSwgZmlsZUdyb3VwMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDIgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAyKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAodGVzdEtleTIsIGZpbGVHcm91cDIpOworCisgICAgLy8gQWxzbyB3cml0ZSAyIGdyb3VwcyB0byB0aGUgZG93bmxvYWRlZCBzaGFyZWQgcHJlZnMuCisgICAgLy8gZmlsZUdyb3VwMyBpcyB0aGUgZG93bmxvYWRlZCB2ZXJzaW9uIGlmIGZpbGVHcm91cDEuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDMgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEb3dubG9hZGVkRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5LCBmaWxlR3JvdXAzKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwNCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURvd25sb2FkZWREYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8zLCAyKTsKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleTMsIGZpbGVHcm91cDQpOworCisgICAgLy8gQWxsIGZpbGUgYXJlIGRvd25sb2FkZWQuCisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZmlsZUdyb3VwMSwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZmlsZUdyb3VwMiwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwgZmlsZUdyb3VwMywgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisgICAgd3JpdGVTaGFyZWRGaWxlcygKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSwKKyAgICAgICAgZmlsZUdyb3VwNCwKKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZihGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFLCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKSk7CisKKyAgICB0ZXN0Q2xvY2suc2V0KC8qIG1pbGxpcyAqLyAxMDAwKTsKKyAgICBmaWxlR3JvdXBNYW5hZ2VyLnZlcmlmeUFsbFBlbmRpbmdHcm91cHNEb3dubG9hZGVkKG5vQ3VzdG9tVmFsaWRhdGlvbigpKS5nZXQoKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHBlbmRpbmcga2V5IGlzIHJlbW92ZWQgaWYgdGhlIGdyb3VwIGlzIGRvd25sb2FkZWQuCisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5KSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5MikpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleTMpKS5pc051bGwoKTsKKworICAgIGZpbGVHcm91cDEgPSBGaWxlR3JvdXBVdGlsLnNldERvd25sb2FkZWRUaW1lc3RhbXBJbk1pbGxpcyhmaWxlR3JvdXAxLCAxMDAwKTsKKyAgICBmaWxlR3JvdXAyID0gRmlsZUdyb3VwVXRpbC5zZXREb3dubG9hZGVkVGltZXN0YW1wSW5NaWxsaXMoZmlsZUdyb3VwMiwgMTAwMCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBwZW5kaW5nIGdyb3VwIGlzIG1hcmtlZCBhcyBkb3dubG9hZGVkIGdyb3VwLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkb3dubG9hZGVkR3JvdXAxID0gcmVhZERvd25sb2FkZWRGaWxlR3JvdXAodGVzdEtleSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkR3JvdXAxKS5pc0VxdWFsVG8oZmlsZUdyb3VwMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRHcm91cDIgPSByZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5Mik7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkR3JvdXAyKS5pc0VxdWFsVG8oZmlsZUdyb3VwMik7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRvd25sb2FkZWRHcm91cDQgPSByZWFkRG93bmxvYWRlZEZpbGVHcm91cCh0ZXN0S2V5Myk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVkR3JvdXA0KS5pc0VxdWFsVG8oZmlsZUdyb3VwNCk7CisKKyAgICAvLyBmaWxlR3JvdXAzIHNob3VsZCBoYXZlIGJlZW4gc2NoZWR1bGVkIGZvciBkZWxldGlvbi4KKyAgICBmaWxlR3JvdXAzID0KKyAgICAgICAgZmlsZUdyb3VwMy50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEJvb2trZWVwaW5nKERhdGFGaWxlR3JvdXBCb29ra2VlcGluZy5uZXdCdWlsZGVyKCkuc2V0U3RhbGVFeHBpcmF0aW9uRGF0ZSgxKS5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKS5nZXQoKSkuY29udGFpbnNFeGFjdGx5KGZpbGVHcm91cDMpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEdyb3VwRG93bmxvYWRGYWlsZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBXcml0ZSAyIGdyb3VwcyB0byB0aGUgcGVuZGluZyBzaGFyZWQgcHJlZnMuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDEgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cDEpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAyID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMik7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkyLCBmaWxlR3JvdXAyKTsKKworICAgIC8vIE1ha2UgdGhlIHNlY29uZCBmaWxlIG9mIHRoZSBmaXJzdCBncm91cCBmYWlsLgorICAgIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgIGZpbGVHcm91cDEsCisgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9GQUlMRUQpKTsKKyAgICB3cml0ZVNoYXJlZEZpbGVzKAorICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICBmaWxlR3JvdXAyLAorICAgICAgICBJbW11dGFibGVMaXN0Lm9mKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUsIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIudmVyaWZ5QWxsUGVuZGluZ0dyb3Vwc0Rvd25sb2FkZWQobm9DdXN0b21WYWxpZGF0aW9uKCkpLmdldCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgcGVuZGluZyBrZXkgaXMgcmVtb3ZlZCBpZiBkb3dubG9hZCBpcyBjb21wbGV0ZS4KKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkpKS5pc0VxdWFsVG8oZmlsZUdyb3VwMSk7CisgICAgYXNzZXJ0VGhhdChyZWFkUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5MikpLmlzTnVsbCgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgZG93bmxvYWRlZCBrZXkgaXMgd3JpdHRlbiBpbnRvIG1ldGFkYXRhIGlmIGRvd25sb2FkIGlzIGNvbXBsZXRlLgorICAgIGZpbGVHcm91cDIgPSBGaWxlR3JvdXBVdGlsLnNldERvd25sb2FkZWRUaW1lc3RhbXBJbk1pbGxpcyhmaWxlR3JvdXAyLCAxMDAwKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZG93bmxvYWRlZEdyb3VwMiA9IHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHRlc3RLZXkyKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZWRHcm91cDIpLmlzRXF1YWxUbyhmaWxlR3JvdXAyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVVbmluc3RhbGxlZEFwcEdyb3Vwc19ub1VuaW5zdGFsbGVkQXBwcygpIHRocm93cyBFeGNlcHRpb24geworICAgIFBhY2thZ2VNYW5hZ2VyIHBhY2thZ2VNYW5hZ2VyID0gY29udGV4dC5nZXRQYWNrYWdlTWFuYWdlcigpOworICAgIGZpbmFsIFBhY2thZ2VJbmZvIHBhY2thZ2VJbmZvID0gbmV3IFBhY2thZ2VJbmZvKCk7CisgICAgcGFja2FnZUluZm8ucGFja2FnZU5hbWUgPSBjb250ZXh0LmdldFBhY2thZ2VOYW1lKCk7CisgICAgcGFja2FnZUluZm8ubGFzdFVwZGF0ZVRpbWUgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKKyAgICBTaGFkb3dzLnNoYWRvd09mKHBhY2thZ2VNYW5hZ2VyKS5hZGRQYWNrYWdlKHBhY2thZ2VJbmZvKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAxID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cCh0ZXN0S2V5LCBmaWxlR3JvdXAxKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAyID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMik7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkyLCBmaWxlR3JvdXAyKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIuZGVsZXRlVW5pbnN0YWxsZWRBcHBHcm91cHMoKS5nZXQoKTsKKworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzRXF1YWxUbyhmaWxlR3JvdXAxKTsKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkyKSkuaXNFcXVhbFRvKGZpbGVHcm91cDIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERlbGV0ZVVuaW5zdGFsbGVkQXBwR3JvdXBzX3VuaW5zdGFsbGVkQXBwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgUGFja2FnZU1hbmFnZXIgcGFja2FnZU1hbmFnZXIgPSBjb250ZXh0LmdldFBhY2thZ2VNYW5hZ2VyKCk7CisgICAgZmluYWwgUGFja2FnZUluZm8gcGFja2FnZUluZm8gPSBuZXcgUGFja2FnZUluZm8oKTsKKyAgICBwYWNrYWdlSW5mby5wYWNrYWdlTmFtZSA9IGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKTsKKyAgICBwYWNrYWdlSW5mby5sYXN0VXBkYXRlVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIFNoYWRvd3Muc2hhZG93T2YocGFja2FnZU1hbmFnZXIpLmFkZFBhY2thZ2UocGFja2FnZUluZm8pOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDEgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXksIGZpbGVHcm91cDEpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAyID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMik7CisgICAgR3JvdXBLZXkgdW5pbnN0YWxsZWRBcHBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikuc2V0T3duZXJQYWNrYWdlKCJ1bmluc3RhbGxlZC5hcHAiKS5idWlsZCgpOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cCh1bmluc3RhbGxlZEFwcEtleSwgZmlsZUdyb3VwMik7CisKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwKHRlc3RLZXkpKS5pc0VxdWFsVG8oZmlsZUdyb3VwMSk7CisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cCh1bmluc3RhbGxlZEFwcEtleSkpLmlzRXF1YWxUbyhmaWxlR3JvdXAyKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIuZGVsZXRlVW5pbnN0YWxsZWRBcHBHcm91cHMoKS5nZXQoKTsKKworICAgIGFzc2VydFRoYXQocmVhZFBlbmRpbmdGaWxlR3JvdXAodGVzdEtleSkpLmlzRXF1YWxUbyhmaWxlR3JvdXAxKTsKKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwKHVuaW5zdGFsbGVkQXBwS2V5KSkuaXNOdWxsKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RGVsZXRlUmVtb3ZlZEFjY291bnRHcm91cHNfbm9SZW1vdmVkQWNjb3VudHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBBY2NvdW50IGFjY291bnQxID0gbmV3IEFjY291bnQoIm5hbWUxIiwgInR5cGUxIik7CisgICAgQWNjb3VudCBhY2NvdW50MiA9IG5ldyBBY2NvdW50KCJuYW1lMiIsICJ0eXBlMiIpOworCisgICAgd2hlbihtb2NrQWNjb3VudFNvdXJjZS5nZXRBbGxBY2NvdW50cygpKS50aGVuUmV0dXJuKEltbXV0YWJsZUxpc3Qub2YoYWNjb3VudDEsIGFjY291bnQyKSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICBHcm91cEtleSBrZXkxID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXRBY2NvdW50KEFjY291bnRVdGlsLnNlcmlhbGl6ZShhY2NvdW50MSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAyID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMik7CisgICAgR3JvdXBLZXkga2V5MiA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzIpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXRBY2NvdW50KEFjY291bnRVdGlsLnNlcmlhbGl6ZShhY2NvdW50MikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAzID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMywgMik7CisgICAgR3JvdXBLZXkga2V5MyA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzMpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGtleTEsIGZpbGVHcm91cDEpOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChrZXkyLCBmaWxlR3JvdXAyKTsKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAoa2V5MywgZmlsZUdyb3VwMyk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyLmRlbGV0ZVJlbW92ZWRBY2NvdW50R3JvdXBzKCkuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxHcm91cEtleXMoKS5nZXQoKSkKKyAgICAgICAgLmNvbnRhaW5zRXhhY3RseShnZXREb3dubG9hZGVkS2V5KGtleTEpLCBnZXREb3dubG9hZGVkS2V5KGtleTIpLCBnZXREb3dubG9hZGVkS2V5KGtleTMpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REZWxldGVSZW1vdmVkQWNjb3VudEdyb3Vwc19yZW1vdmVkQWNjb3VudHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBBY2NvdW50IGFjY291bnQxID0gbmV3IEFjY291bnQoIm5hbWUxIiwgInR5cGUxIik7CisgICAgQWNjb3VudCBhY2NvdW50MiA9IG5ldyBBY2NvdW50KCJuYW1lMiIsICJ0eXBlMiIpOworCisgICAgd2hlbihtb2NrQWNjb3VudFNvdXJjZS5nZXRBbGxBY2NvdW50cygpKS50aGVuUmV0dXJuKEltbXV0YWJsZUxpc3Qub2YoYWNjb3VudDEpKTsKKworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAxID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIEdyb3VwS2V5IGtleTEgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldEFjY291bnQoQWNjb3VudFV0aWwuc2VyaWFsaXplKGFjY291bnQxKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDIgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAyKTsKKyAgICBHcm91cEtleSBrZXkyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldEFjY291bnQoQWNjb3VudFV0aWwuc2VyaWFsaXplKGFjY291bnQyKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDMgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8zLCAyKTsKKyAgICBHcm91cEtleSBrZXkzID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMykKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAoa2V5MSwgZmlsZUdyb3VwMSk7CisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwKGtleTIsIGZpbGVHcm91cDIpOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChrZXkzLCBmaWxlR3JvdXAzKTsKKworICAgIGZpbGVHcm91cE1hbmFnZXIuZGVsZXRlUmVtb3ZlZEFjY291bnRHcm91cHMoKS5nZXQoKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEdyb3VwS2V5cygpLmdldCgpKQorICAgICAgICAuY29udGFpbnNFeGFjdGx5KGdldERvd25sb2FkZWRLZXkoa2V5MSksIGdldERvd25sb2FkZWRLZXkoa2V5MykpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdExvZ0FuZERlbGV0ZUZvck1pc3NpbmdTaGFyZWRGaWxlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIHJlc2V0RmlsZUdyb3VwTWFuYWdlcihmaWxlR3JvdXBzTWV0YWRhdGEsIG1vY2tTaGFyZWRGaWxlTWFuYWdlcik7CisKKyAgICBHcm91cEtleSBkb3dubG9hZGVkR3JvdXBLZXlXaXRoRmlsZU1pc3NpbmcgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkZWQodHJ1ZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAxID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cChkb3dubG9hZGVkR3JvdXBLZXlXaXRoRmlsZU1pc3NpbmcsIGZpbGVHcm91cDEpOworICAgIE5ld0ZpbGVLZXlbXSBrZXlzID0gTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwoZmlsZUdyb3VwMSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIucmVWZXJpZnlGaWxlKGVxKGtleXNbMF0pLCBlcShmaWxlR3JvdXAxLmdldEZpbGUoMCkpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUobmV3IFNoYXJlZEZpbGVNaXNzaW5nRXhjZXB0aW9uKCkpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5yZVZlcmlmeUZpbGUoZXEoa2V5c1sxXSksIGVxKGZpbGVHcm91cDEuZ2V0RmlsZSgxKSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZShuZXcgU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24oKSkpOworCisgICAgR3JvdXBLZXkgcGVuZGluZ0dyb3VwS2V5V2l0aEZpbGVNaXNzaW5nID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkZWQoZmFsc2UpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMiA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzIsIDIpOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChwZW5kaW5nR3JvdXBLZXlXaXRoRmlsZU1pc3NpbmcsIGZpbGVHcm91cDIpOworICAgIC8vIFdyaXRlIG9ubHkgdGhlIGZpcnN0IGZpbGUgbWV0YWRhdGEuCisgICAgTmV3RmlsZUtleVtdIGtleXMyID0gTWRkVGVzdFV0aWwuY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwoZmlsZUdyb3VwMik7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIucmVWZXJpZnlGaWxlKGVxKGtleXMyWzBdKSwgZXEoZmlsZUdyb3VwMi5nZXRGaWxlKDApKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKG5ldyBTaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbigpKSk7CisgICAgLy8gbW9ja1NoYXJlZEZpbGVNYW5hZ2VyIHJldHVybnMgIk9LIiB3aGVuIHZlcmlmeWluZyBzZWNvbmQgZmlsZS4KKworICAgIEdyb3VwS2V5IGdyb3VwS2V5V2l0aE5vRmlsZU1pc3NpbmcgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8zKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRlZCh0cnVlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDMgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8zLCAyKTsKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAoZ3JvdXBLZXlXaXRoTm9GaWxlTWlzc2luZywgZmlsZUdyb3VwMyk7CisgICAgLy8gbW9ja1NoYXJlZEZpbGVNYW5hZ2VyIGFsd2F5cyByZXR1cm5zICJPSyIgd2hlbiB2ZXJpZnlpbmcgZmlsZXMuCisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyLmxvZ0FuZERlbGV0ZUZvck1pc3NpbmdTaGFyZWRGaWxlcygpLmdldCgpOworCisgICAgaWYgKGZsYWdzLmRlbGV0ZUZpbGVHcm91cHNXaXRoRmlsZXNNaXNzaW5nKCkpIHsKKyAgICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEdyb3VwS2V5cygpLmdldCgpKQorICAgICAgICAgIC5jb250YWluc0V4YWN0bHkoZ3JvdXBLZXlXaXRoTm9GaWxlTWlzc2luZyk7CisgICAgfSBlbHNlIHsKKyAgICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbEdyb3VwS2V5cygpLmdldCgpKQorICAgICAgICAgIC5jb250YWluc0V4YWN0bHkoCisgICAgICAgICAgICAgIGRvd25sb2FkZWRHcm91cEtleVdpdGhGaWxlTWlzc2luZywKKyAgICAgICAgICAgICAgcGVuZGluZ0dyb3VwS2V5V2l0aEZpbGVNaXNzaW5nLAorICAgICAgICAgICAgICBncm91cEtleVdpdGhOb0ZpbGVNaXNzaW5nKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRPbkRldmljZVVyaV9zaG9ydGN1dHNGb3JTaWRlbG9hZGVkRmlsZXNfZGVsZWdhdGVzVG9TaGFyZWRGaWxlTWFuYWdlck90aGVyd2lzZSgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBFbnN1cmUgdGhhdCBzaWRlbG9hZGluZyBpcyB0dXJuZWQgb2ZmCisgICAgZmxhZ3MuZW5hYmxlU2lkZWxvYWRpbmcgPSBPcHRpb25hbC5vZih0cnVlKTsKKworICAgIC8vIENyZWF0ZSBtaXhlZCBncm91cAorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBzaWRlbG9hZGVkR3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuYWRkRmlsZSgKKyAgICAgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEZpbGVJZCgic2lkZWxvYWRlZF9maWxlIikKKyAgICAgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImZpbGU6L3Rlc3QiKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW1UeXBlKERhdGFGaWxlLkNoZWNrc3VtVHlwZS5OT05FKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5hZGRGaWxlKAorICAgICAgICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCJzdGFuZGFyZF9maWxlIikKKyAgICAgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImh0dHBzOi8vdXJsLnRvLmRvd25sb2FkIikKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtVHlwZShEYXRhRmlsZS5DaGVja3N1bVR5cGUuTk9ORSkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYWRkRmlsZSgKKyAgICAgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldEZpbGVJZCgiaW5saW5lX2ZpbGUiKQorICAgICAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZTpzaGExOmNoZWNrc3VtIikKKyAgICAgICAgICAgICAgICAgICAgLnNldENoZWNrc3VtKCJjaGVja3N1bSIpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBXcml0ZSBzaGFyZWQgZmlsZXMgc28gc2hhcmVkIGZpbGUgbWFuYWdlciBjYW4gZ2V0IHVyaXMKKyAgICBOZXdGaWxlS2V5W10gbmV3RmlsZUtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChzaWRlbG9hZGVkR3JvdXApOworCisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YQorICAgICAgICAud3JpdGUoCisgICAgICAgICAgICBuZXdGaWxlS2V5c1sxXSwKKyAgICAgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVOYW1lKHNpZGVsb2FkZWRHcm91cC5nZXRGaWxlKDEpLmdldEZpbGVJZCgpKQorICAgICAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgIC5nZXQoKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhCisgICAgICAgIC53cml0ZSgKKyAgICAgICAgICAgIG5ld0ZpbGVLZXlzWzJdLAorICAgICAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAuc2V0RmlsZU5hbWUoc2lkZWxvYWRlZEdyb3VwLmdldEZpbGUoMikuZ2V0RmlsZUlkKCkpCisgICAgICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmdldCgpOworCisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIGZpbGVHcm91cE1hbmFnZXIKKyAgICAgICAgICAgICAgICAuZ2V0T25EZXZpY2VVcmkoc2lkZWxvYWRlZEdyb3VwLmdldEZpbGUoMCksIHNpZGVsb2FkZWRHcm91cCkKKyAgICAgICAgICAgICAgICAuZ2V0KCkKKyAgICAgICAgICAgICAgICAuZ2V0U2NoZW1lKCkpCisgICAgICAgIC5pc0VxdWFsVG8oImZpbGUiKTsKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAgICAgICAgIC5nZXRPbkRldmljZVVyaShzaWRlbG9hZGVkR3JvdXAuZ2V0RmlsZSgxKSwgc2lkZWxvYWRlZEdyb3VwKQorICAgICAgICAgICAgICAgIC5nZXQoKQorICAgICAgICAgICAgICAgIC5nZXRTY2hlbWUoKSkKKyAgICAgICAgLmlzRXF1YWxUbygiYW5kcm9pZCIpOworICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgICAgICAgICAgLmdldE9uRGV2aWNlVXJpKHNpZGVsb2FkZWRHcm91cC5nZXRGaWxlKDIpLCBzaWRlbG9hZGVkR3JvdXApCisgICAgICAgICAgICAgICAgLmdldCgpCisgICAgICAgICAgICAgICAgLmdldFNjaGVtZSgpKQorICAgICAgICAuaXNFcXVhbFRvKCJhbmRyb2lkIik7CisgIH0KKworICAvKioKKyAgICogUmUtaW5zdGFudGlhdGVzIHtAY29kZSBmaWxlR3JvdXBNYW5hZ2VyfSB3aXRoIHRoZSBpbmplY3RlZCBwYXJhbWV0ZXJzLgorICAgKgorICAgKiA8cD5JdCBjYW4gYmUgdXNlZCB0byB3b3JrIHdpdGggdGhlIG1vY2tzIGZvciBGaWxlR3JvdXBzTWV0YWRhdGEgYW5kL29yIFNoYXJlZEZpbGVNYW5hZ2VyLgorICAgKi8KKyAgcHJpdmF0ZSB2b2lkIHJlc2V0RmlsZUdyb3VwTWFuYWdlcigKKyAgICAgIEZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGEsIFNoYXJlZEZpbGVNYW5hZ2VyIHNoYXJlZEZpbGVNYW5hZ2VyKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBmaWxlR3JvdXBNYW5hZ2VyID0KKyAgICAgICAgbmV3IEZpbGVHcm91cE1hbmFnZXIoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0xvZ2dlciwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YSwKKyAgICAgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyLAorICAgICAgICAgICAgdGVzdENsb2NrLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0FjY291bnRTb3VyY2UpLAorICAgICAgICAgICAgU0VRVUVOVElBTF9DT05UUk9MX0VYRUNVVE9SLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIGRvd25sb2FkU3RhZ2VNYW5hZ2VyLAorICAgICAgICAgICAgZmxhZ3MpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgVm9pZCBjcmVhdGVGaWxlR3JvdXBEZXRhaWxzKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXApIHsKKyAgICByZXR1cm4gbnVsbDsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIFZvaWQgY3JlYXRlTWRkRG93bmxvYWRMYXRlbmN5KAorICAgICAgaW50IGRvd25sb2FkQXR0ZW1wdENvdW50LCBsb25nIGRvd25sb2FkTGF0ZW5jeU1zLCBsb25nIHRvdGFsTGF0ZW5jeU1zKSB7CisgICAgcmV0dXJuIG51bGw7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgY3JlYXRlRGF0YUZpbGVHcm91cCgKKyAgICAgIFN0cmluZyBncm91cE5hbWUsIGludCBmaWxlQ291bnQsIGludCBkb3dubG9hZEF0dGVtcHRDb3VudCwgbG9uZyBuZXdGaWxlc1JlY2VpdmVkVGltZXN0YW1wKSB7CisgICAgcmV0dXJuIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChncm91cE5hbWUsIGZpbGVDb3VudCkudG9CdWlsZGVyKCkKKyAgICAgICAgLnNldEJvb2trZWVwaW5nKAorICAgICAgICAgICAgRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFN0YXJ0ZWRDb3VudChkb3dubG9hZEF0dGVtcHRDb3VudCkKKyAgICAgICAgICAgICAgICAuc2V0R3JvdXBOZXdGaWxlc1JlY2VpdmVkVGltZXN0YW1wKG5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXApKQorICAgICAgICAuYnVpbGQoKTsKKyAgfQorCisgIC8qKiBUaGUgZmlsZSBkb3dubG9hZCBzdWNjZWVkcyBzbyB0aGUgbmV3IGZpbGUgc3RhdHVzIGlzIERPV05MT0FEX0NPTVBMRVRFLiAqLworICBwcml2YXRlIHZvaWQgZmlsZURvd25sb2FkU3VjY2VlZHMoTmV3RmlsZUtleSBrZXksIFVyaSBmaWxlVXJpKSB7CisgICAgd2hlbihtb2NrRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKAorICAgICAgICAgICAgYW55KEdyb3VwS2V5LmNsYXNzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55TG9uZygpLAorICAgICAgICAgICAgZXEoZmlsZVVyaSksCisgICAgICAgICAgICBhbnkoU3RyaW5nLmNsYXNzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55KERvd25sb2FkQ29uZGl0aW9ucy5jbGFzcyksCisgICAgICAgICAgICBpc0EoRG93bmxvYWRlckNhbGxiYWNrSW1wbC5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueUxpc3QoKSkpCisgICAgICAgIC50aGVuKAorICAgICAgICAgICAgbmV3IEFuc3dlcjxMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PigpIHsKKyAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGFuc3dlcihJbnZvY2F0aW9uT25Nb2NrIGludm9jYXRpb24pIHRocm93cyBUaHJvd2FibGUgeworICAgICAgICAgICAgICAgIFNoYXJlZEZpbGUgc2hhcmVkRmlsZSA9CisgICAgICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyLmdldFNoYXJlZEZpbGUoa2V5KS5nZXQoKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpOworICAgICAgICAgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEud3JpdGUoa2V5LCBzaGFyZWRGaWxlKS5nZXQoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICB9CisKKyAgLyoqCisgICAqIFRoZSBmaWxlIGRvd25sb2FkIGZhaWxzIHNvIHRoZSBuZXcgZmlsZSBzdGF0dXMgaXMgRE9XTkxPQURfRkFJTEVELiBJZiBmYWlsdXJlQ29kZSBpcyBub3QgbnVsbCwKKyAgICogdGhlIGRvd25sb2FkZXIgcmV0dXJucyBhIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZTsgb3RoZXJ3aXNlIGl0IHJldHVybnMgYW4gaW1tZWRpYXRlVm9pZEZ1dHVyZS4KKyAgICovCisgIHByaXZhdGUgdm9pZCBmaWxlRG93bmxvYWRGYWlscyhOZXdGaWxlS2V5IGtleSwgVXJpIGZpbGVVcmksIERvd25sb2FkUmVzdWx0Q29kZSBmYWlsdXJlQ29kZSkgeworICAgIHdoZW4obW9ja0Rvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIGFueShHcm91cEtleS5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueUxvbmcoKSwKKyAgICAgICAgICAgIGVxKGZpbGVVcmkpLAorICAgICAgICAgICAgYW55KFN0cmluZy5jbGFzcyksCisgICAgICAgICAgICBhbnlJbnQoKSwKKyAgICAgICAgICAgIGFueShEb3dubG9hZENvbmRpdGlvbnMuY2xhc3MpLAorICAgICAgICAgICAgaXNBKERvd25sb2FkZXJDYWxsYmFja0ltcGwuY2xhc3MpLAorICAgICAgICAgICAgYW55SW50KCksCisgICAgICAgICAgICBhbnlMaXN0KCkpKQorICAgICAgICAudGhlbigKKyAgICAgICAgICAgIG5ldyBBbnN3ZXI8TGlzdGVuYWJsZUZ1dHVyZTxWb2lkPj4oKSB7CisgICAgICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgICAgICBwdWJsaWMgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBhbnN3ZXIoSW52b2NhdGlvbk9uTW9jayBpbnZvY2F0aW9uKSB0aHJvd3MgVGhyb3dhYmxlIHsKKyAgICAgICAgICAgICAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPQorICAgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlTWFuYWdlci5nZXRTaGFyZWRGaWxlKGtleSkuZ2V0KCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfRkFJTEVEKQorICAgICAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgICAgICAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShrZXksIHNoYXJlZEZpbGUpLmdldCgpOworICAgICAgICAgICAgICAgIGlmIChmYWlsdXJlQ29kZSA9PSBudWxsKSB7CisgICAgICAgICAgICAgICAgICByZXR1cm4gRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZSgKKyAgICAgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpLnNldERvd25sb2FkUmVzdWx0Q29kZShmYWlsdXJlQ29kZSkuYnVpbGQoKSk7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICB9CisKKyAgcHJpdmF0ZSBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcmVhZFBlbmRpbmdGaWxlR3JvdXAoR3JvdXBLZXkga2V5KSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBHcm91cEtleSBkdXBsaWNhdGVHcm91cEtleSA9IGtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworICAgIHJldHVybiBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChkdXBsaWNhdGVHcm91cEtleSkuZ2V0KCk7CisgIH0KKworICBwcml2YXRlIERhdGFGaWxlR3JvdXBJbnRlcm5hbCByZWFkRG93bmxvYWRlZEZpbGVHcm91cChHcm91cEtleSBrZXkpIHRocm93cyBFeGNlcHRpb24geworICAgIEdyb3VwS2V5IGR1cGxpY2F0ZUdyb3VwS2V5ID0ga2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKyAgICByZXR1cm4gZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZHVwbGljYXRlR3JvdXBLZXkpLmdldCgpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChHcm91cEtleSBrZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBncm91cCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgR3JvdXBLZXkgZHVwbGljYXRlR3JvdXBLZXkgPSBrZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKyAgICBmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUoZHVwbGljYXRlR3JvdXBLZXksIGdyb3VwKS5nZXQoKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXAoR3JvdXBLZXkga2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZ3JvdXApCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBHcm91cEtleSBkdXBsaWNhdGVHcm91cEtleSA9IGtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKHRydWUpLmJ1aWxkKCk7CisgICAgZmlsZUdyb3Vwc01ldGFkYXRhLndyaXRlKGR1cGxpY2F0ZUdyb3VwS2V5LCBncm91cCkuZ2V0KCk7CisgIH0KKworICBwcml2YXRlIHZvaWQgdmVyaWZ5QWRkR3JvdXBGb3JEb3dubG9hZFdyaXRlc01ldGFkYXRhKAorICAgICAgR3JvdXBLZXkga2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZ3JvdXAsIGxvbmcgZXhwZWN0ZWRUaW1lc3RhbXApIHRocm93cyBFeGNlcHRpb24geworICAgIEdyb3VwS2V5IGR1cGxpY2F0ZUdyb3VwS2V5ID0ga2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQoZmFsc2UpLmJ1aWxkKCk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgdXBkYXRlZEZpbGVHcm91cCA9CisgICAgICAgIHNldFJlY2VpdmVkVGltZVN0YW1wV2l0aEZlYXR1cmVPbihncm91cCwgZXhwZWN0ZWRUaW1lc3RhbXApOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoZHVwbGljYXRlR3JvdXBLZXkpLmdldCgpKS5pc0VxdWFsVG8odXBkYXRlZEZpbGVHcm91cCk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBHcm91cEtleSBnZXRQZW5kaW5nS2V5KEdyb3VwS2V5IGtleSkgeworICAgIHJldHVybiBrZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIEdyb3VwS2V5IGdldERvd25sb2FkZWRLZXkoR3JvdXBLZXkga2V5KSB7CisgICAgcmV0dXJuIGtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKHRydWUpLmJ1aWxkKCk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgc2V0UmVjZWl2ZWRUaW1lU3RhbXBXaXRoRmVhdHVyZU9uKAorICAgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAsIGxvbmcgZWxhcHNlZFRpbWUpIHsKKyAgICBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcgYm9va2tlZXBpbmcgPQorICAgICAgICBkYXRhRmlsZUdyb3VwLmdldEJvb2trZWVwaW5nKCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXAoZWxhcHNlZFRpbWUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICByZXR1cm4gZGF0YUZpbGVHcm91cC50b0J1aWxkZXIoKS5zZXRCb29ra2VlcGluZyhib29ra2VlcGluZykuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBTaW11bGF0ZXMgdGhlIGRvd25sb2FkIG9mIHRoZSBmaWxlIHtAY29kZSBkYXRhRmlsZX0gYnkgd3JpdGluZyBhIGZpbGUgd2l0aCBuYW1lIHtAY29kZQorICAgKiBmaWxlTmFtZX0uCisgICAqLworICBwcml2YXRlIEZpbGUgc2ltdWxhdGVEb3dubG9hZChEYXRhRmlsZSBkYXRhRmlsZSwgU3RyaW5nIGZpbGVOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIEZpbGUgb25EZXZpY2VGaWxlID0gbmV3IEZpbGUocHVibGljRGlyZWN0b3J5LCBmaWxlTmFtZSk7CisgICAgYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbZGF0YUZpbGUuZ2V0Qnl0ZVNpemUoKV07CisgICAgdHJ5IChGaWxlT3V0cHV0U3RyZWFtIHdyaXRlciA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKG9uRGV2aWNlRmlsZSkpIHsKKyAgICAgIHdyaXRlci53cml0ZShieXRlcyk7CisgICAgfQorICAgIHJldHVybiBvbkRldmljZUZpbGU7CisgIH0KKworICBwcml2YXRlIExpc3Q8VXJpPiBnZXRPbkRldmljZVVyaXNGb3JGaWxlR3JvdXAoRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCkgeworICAgIEFycmF5TGlzdDxVcmk+IHVyaUxpc3QgPSBuZXcgQXJyYXlMaXN0PD4oZmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKTsKKyAgICBOZXdGaWxlS2V5W10gbmV3RmlsZUtleXMgPSBNZGRUZXN0VXRpbC5jcmVhdGVGaWxlS2V5c0ZvckRhdGFGaWxlR3JvdXBJbnRlcm5hbChmaWxlR3JvdXApOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuZXdGaWxlS2V5cy5sZW5ndGg7IGkrKykgeworICAgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0gbmV3RmlsZUtleXNbaV07CisgICAgICBEYXRhRmlsZSBkYXRhRmlsZSA9IGZpbGVHcm91cC5nZXRGaWxlKGkpOworICAgICAgdXJpTGlzdC5hZGQoCisgICAgICAgICAgRGlyZWN0b3J5VXRpbC5nZXRPbkRldmljZVVyaSgKKyAgICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgICAgbmV3RmlsZUtleS5nZXRBbGxvd2VkUmVhZGVycygpLAorICAgICAgICAgICAgICBkYXRhRmlsZS5nZXRGaWxlSWQoKSwKKyAgICAgICAgICAgICAgbmV3RmlsZUtleS5nZXRDaGVja3N1bSgpLAorICAgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAgIC8qIGluc3RhbmNlSWQgPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgLyogYW5kcm9pZFNoYXJlZCA9ICovIGZhbHNlKSk7CisgICAgfQorICAgIHJldHVybiB1cmlMaXN0OworICB9CisKKyAgcHJpdmF0ZSBBc3luY0Z1bmN0aW9uPERhdGFGaWxlR3JvdXBJbnRlcm5hbCwgQm9vbGVhbj4gbm9DdXN0b21WYWxpZGF0aW9uKCkgeworICAgIHJldHVybiB1bnVzZWQgLT4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9GaWxlR3JvdXBzTWV0YWRhdGFUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvRmlsZUdyb3Vwc01ldGFkYXRhVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBmZTRmMjgKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvRmlsZUdyb3Vwc01ldGFkYXRhVGVzdC5qYXZhCkBAIC0wLDAgKzEsNjQwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRXaXRoTWVzc2FnZTsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5TaGFyZWRQcmVmZXJlbmNlczsKK2ltcG9ydCBhbmRyb2lkLnV0aWwuUGFpcjsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuU2lsZW50RmVlZGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuQW5kcm9pZEZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuRXZlbnRMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5EaXJlY3RvcnlVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuRmlsZUdyb3VwVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLkZpbGVHcm91cHNNZXRhZGF0YVV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5Qcm90b0NvbnZlcnNpb25VdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuU2hhcmVkUHJlZmVyZW5jZXNVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRlc3RpbmcuRmFrZVRpbWVTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5UZXN0RmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZUdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uR3JvdXBLZXk7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleVByb3BlcnRpZXM7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IGphdmEudGltZS5EdXJhdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OworaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IG9yZy5qdW5pdC5BZnRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Nb2NrOworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9KVW5pdDsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvUnVsZTsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUGFyYW1ldGVyaXplZFJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUGFyYW1ldGVyaXplZFJvYm9sZWN0cmljVGVzdFJ1bm5lci5QYXJhbWV0ZXI7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlBhcmFtZXRlcml6ZWRSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuUGFyYW1ldGVyczsKKworQFJ1bldpdGgoUGFyYW1ldGVyaXplZFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBGaWxlR3JvdXBzTWV0YWRhdGFUZXN0IHsKKworICAvLyBUT0RPKGIvMjYxMTA5NTEpOiB1c2UgUGFyYW1ldGVyaXplZCBydW5uZXIgb25jZSBhbmRyb2lkX3Rlc3Qgc3VwcG9ydHMgaXQKKyAgcHJpdmF0ZSBlbnVtIE1ldGFkYXRhU3RvcmVJbXBsIHsKKyAgICBTUF9JTVBMLAorICB9CisKKyAgLy8gV2hldGhlciB0byB1c2UgUERTIG1ldGFkYXRhIHN0b3JlIG9yIFNoYXJlZFByZWZlcmVuY2VzIG1ldGFkYXRhIHN0b3JlLgorICBAUGFyYW1ldGVyKHZhbHVlID0gMCkKKyAgcHVibGljIE1ldGFkYXRhU3RvcmVJbXBsIG1ldGFkYXRhU3RvcmVJbXBsOworCisgIEBQYXJhbWV0ZXIodmFsdWUgPSAxKQorICBwdWJsaWMgT3B0aW9uYWw8U3RyaW5nPiBpbnN0YW5jZUlkOworCisgIEBQYXJhbWV0ZXJzKG5hbWUgPSAibWV0YWRhdGFTdG9yZUltcGwgPSB7MH0gaW5zdGFuY2VJZCA9IHsxfSIpCisgIHB1YmxpYyBzdGF0aWMgQ29sbGVjdGlvbjxPYmplY3RbXT4gcGFyYW1ldGVycygpIHsKKyAgICByZXR1cm4gQXJyYXlzLmFzTGlzdCgKKyAgICAgICAgbmV3IE9iamVjdFtdW10geworICAgICAgICAgIHtNZXRhZGF0YVN0b3JlSW1wbC5TUF9JTVBMLCBPcHRpb25hbC5hYnNlbnQoKX0sCisgICAgICAgICAge01ldGFkYXRhU3RvcmVJbXBsLlNQX0lNUEwsIE9wdGlvbmFsLm9mKCJpZCIpfSwKKyAgICAgICAgfSk7CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVTVF9HUk9VUCA9ICJ0ZXN0LWdyb3VwIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfR1JPVVBfMiA9ICJ0ZXN0LWdyb3VwLTIiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVTVF9HUk9VUF8zID0gInRlc3QtZ3JvdXAtMyI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEV4ZWN1dG9yIENPTlRST0xfRVhFQ1VUT1IgPQorICAgICAgTW9yZUV4ZWN1dG9ycy5uZXdTZXF1ZW50aWFsRXhlY3V0b3IoRXhlY3V0b3JzLm5ld0NhY2hlZFRocmVhZFBvb2woKSk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgR3JvdXBLZXkgdGVzdEtleTsKKyAgcHJpdmF0ZSBzdGF0aWMgR3JvdXBLZXkgdGVzdEtleTI7CisgIHByaXZhdGUgc3RhdGljIEdyb3VwS2V5IHRlc3RLZXkzOworCisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHJpdmF0ZSBDb250ZXh0IGNvbnRleHQ7CisgIHByaXZhdGUgRmFrZVRpbWVTb3VyY2UgdGVzdENsb2NrOworICBwcml2YXRlIEZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGE7CisgIHByaXZhdGUgZmluYWwgVGVzdEZsYWdzIGZsYWdzID0gbmV3IFRlc3RGbGFncygpOworICBATW9jayBFdmVudExvZ2dlciBtb2NrTG9nZ2VyOworICBATW9jayBTaWxlbnRGZWVkYmFjayBtb2NrU2lsZW50RmVlZGJhY2s7CisKKyAgQFJ1bGUgcHVibGljIGZpbmFsIE1vY2tpdG9SdWxlIG1vY2tzID0gTW9ja2l0b0pVbml0LnJ1bGUoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKworICAgIHRlc3RLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkZWQoZmFsc2UpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHRlc3RLZXkyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMikKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkZWQoZmFsc2UpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHRlc3RLZXkzID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVBfMykKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkZWQoZmFsc2UpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGZpbGVTdG9yYWdlID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoQXJyYXlzLmFzTGlzdChBbmRyb2lkRmlsZUJhY2tlbmQuYnVpbGRlcihjb250ZXh0KS5idWlsZCgpKSk7CisKKyAgICB0ZXN0Q2xvY2sgPSBuZXcgRmFrZVRpbWVTb3VyY2UoKTsKKyAgICBTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YSBzaGFyZWRQcmVmZXJlbmNlc0ltcGwgPQorICAgICAgICBuZXcgU2hhcmVkUHJlZmVyZW5jZXNGaWxlR3JvdXBzTWV0YWRhdGEoCisgICAgICAgICAgICBjb250ZXh0LCB0ZXN0Q2xvY2ssIG1vY2tTaWxlbnRGZWVkYmFjaywgaW5zdGFuY2VJZCwgQ09OVFJPTF9FWEVDVVRPUik7CisgICAgc3dpdGNoIChtZXRhZGF0YVN0b3JlSW1wbCkgeworICAgICAgY2FzZSBTUF9JTVBMOgorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEgPSBzaGFyZWRQcmVmZXJlbmNlc0ltcGw7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgIEBBZnRlcgorICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgIGZpbGVHcm91cHNNZXRhZGF0YS5jbGVhcigpLmdldCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc2VyaWFsaXplQW5kRGVzZXJpYWxpemVGaWxlR3JvdXBLZXkoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTdHJpbmcgc2VyaWFsaXplZEdyb3VwS2V5ID0gRmlsZUdyb3Vwc01ldGFkYXRhVXRpbC5nZXRTZXJpYWxpemVkR3JvdXBLZXkodGVzdEtleSwgY29udGV4dCk7CisgICAgR3JvdXBLZXkgZGVzZXJpYWxpemVkR3JvdXBLZXkgPSBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLmRlc2VyaWFsaXplR3JvdXBLZXkoc2VyaWFsaXplZEdyb3VwS2V5KTsKKworICAgIGFzc2VydFRoYXQoZGVzZXJpYWxpemVkR3JvdXBLZXkuZ2V0R3JvdXBOYW1lKCkpLmlzRXF1YWxUbyhURVNUX0dST1VQKTsKKyAgICBhc3NlcnRUaGF0KGRlc2VyaWFsaXplZEdyb3VwS2V5LmdldE93bmVyUGFja2FnZSgpKS5pc0VxdWFsVG8oY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKTsKKyAgICBhc3NlcnRUaGF0KGRlc2VyaWFsaXplZEdyb3VwS2V5LmdldERvd25sb2FkZWQoKSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVhZEFuZFdyaXRlRmlsZUdyb3VwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHdyaXRlRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCB3cml0ZUZpbGVHcm91cDIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAxKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgd3JpdGVGaWxlR3JvdXAzID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMywgNSk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKHRlc3RLZXkpLmdldCgpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZSh0ZXN0S2V5LCB3cml0ZUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEucmVhZCh0ZXN0S2V5MikuZ2V0KCkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLndyaXRlKHRlc3RLZXkyLCB3cml0ZUZpbGVHcm91cDIpLmdldCgpKS5pc1RydWUoKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQodGVzdEtleTMpLmdldCgpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZSh0ZXN0S2V5Mywgd3JpdGVGaWxlR3JvdXAzKS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcmVhZEZpbGVHcm91cCA9IGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKHRlc3RLZXkpLmdldCgpOworICAgIE1kZFRlc3RVdGlsLmFzc2VydE1lc3NhZ2VFcXVhbHMocmVhZEZpbGVHcm91cCwgd3JpdGVGaWxlR3JvdXApOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHJlYWRGaWxlR3JvdXAyID0gZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQodGVzdEtleTIpLmdldCgpOworICAgIE1kZFRlc3RVdGlsLmFzc2VydE1lc3NhZ2VFcXVhbHMocmVhZEZpbGVHcm91cDIsIHdyaXRlRmlsZUdyb3VwMik7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcmVhZEZpbGVHcm91cDMgPSBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZCh0ZXN0S2V5MykuZ2V0KCk7CisgICAgTWRkVGVzdFV0aWwuYXNzZXJ0TWVzc2FnZUVxdWFscyhyZWFkRmlsZUdyb3VwMywgd3JpdGVGaWxlR3JvdXAzKTsKKworICAgIHZlcmlmeU5vRXJyb3JJblBkc01pZ3JhdGlvbigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVhZEFuZFdyaXRlRmlsZUdyb3VwX3dpdGhFeHRlbnNpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgd3JpdGVGaWxlR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKHRlc3RLZXkpLmdldCgpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZSh0ZXN0S2V5LCB3cml0ZUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHJlYWRGaWxlR3JvdXAgPSBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZCh0ZXN0S2V5KS5nZXQoKTsKKyAgICBNZGRUZXN0VXRpbC5hc3NlcnRNZXNzYWdlRXF1YWxzKHJlYWRGaWxlR3JvdXAsIHdyaXRlRmlsZUdyb3VwKTsKKworICAgIHdyaXRlRmlsZUdyb3VwID0gRmlsZUdyb3VwVXRpbC5zZXRTdGFsZUV4cGlyYXRpb25EYXRlKHdyaXRlRmlsZUdyb3VwLCAxMDAwKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZSh0ZXN0S2V5LCB3cml0ZUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgcmVhZEZpbGVHcm91cCA9IGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKHRlc3RLZXkpLmdldCgpOworICAgIE1kZFRlc3RVdGlsLmFzc2VydE1lc3NhZ2VFcXVhbHMocmVhZEZpbGVHcm91cCwgd3JpdGVGaWxlR3JvdXApOworCisgICAgdmVyaWZ5Tm9FcnJvckluUGRzTWlncmF0aW9uKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZW1vdmVGaWxlR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAyID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMiwgMSk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDMgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8zLCA1KTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLndyaXRlKHRlc3RLZXksIGZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlbW92ZSh0ZXN0S2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEucmVhZCh0ZXN0S2V5KS5nZXQoKSkuaXNOdWxsKCk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZSh0ZXN0S2V5MiwgZmlsZUdyb3VwMikuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlbW92ZSh0ZXN0S2V5MikuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQodGVzdEtleTIpLmdldCgpKS5pc051bGwoKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLndyaXRlKHRlc3RLZXkzLCBmaWxlR3JvdXAzKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlKHRlc3RLZXkzKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEucmVhZCh0ZXN0S2V5MykuZ2V0KCkpLmlzTnVsbCgpOworCisgICAgdmVyaWZ5Tm9FcnJvckluUGRzTWlncmF0aW9uKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZWFkQW5kV3JpdGVGaWxlR3JvdXBLZXlQcm9wZXJ0aWVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgR3JvdXBLZXlQcm9wZXJ0aWVzIHdyaXRlR3JvdXBLZXlQcm9wZXJ0aWVzID0KKyAgICAgICAgR3JvdXBLZXlQcm9wZXJ0aWVzLm5ld0J1aWxkZXIoKS5zZXRBY3RpdmF0ZWRPbkRldmljZSh0cnVlKS5idWlsZCgpOworICAgIEdyb3VwS2V5UHJvcGVydGllcyB3cml0ZUdyb3VwS2V5UHJvcGVydGllczIgPQorICAgICAgICBHcm91cEtleVByb3BlcnRpZXMubmV3QnVpbGRlcigpLnNldEFjdGl2YXRlZE9uRGV2aWNlKGZhbHNlKS5idWlsZCgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEucmVhZEdyb3VwS2V5UHJvcGVydGllcyh0ZXN0S2V5KS5nZXQoKSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGVHcm91cEtleVByb3BlcnRpZXModGVzdEtleSwgd3JpdGVHcm91cEtleVByb3BlcnRpZXMpLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkR3JvdXBLZXlQcm9wZXJ0aWVzKHRlc3RLZXkyKS5nZXQoKSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGVHcm91cEtleVByb3BlcnRpZXModGVzdEtleTIsIHdyaXRlR3JvdXBLZXlQcm9wZXJ0aWVzMikuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKworICAgIEdyb3VwS2V5UHJvcGVydGllcyByZWFkR3JvdXBLZXlQcm9wZXJ0aWVzID0KKyAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWRHcm91cEtleVByb3BlcnRpZXModGVzdEtleSkuZ2V0KCk7CisgICAgTWRkVGVzdFV0aWwuYXNzZXJ0TWVzc2FnZUVxdWFscyh3cml0ZUdyb3VwS2V5UHJvcGVydGllcywgcmVhZEdyb3VwS2V5UHJvcGVydGllcyk7CisKKyAgICBHcm91cEtleVByb3BlcnRpZXMgcmVhZEdyb3VwS2V5UHJvcGVydGllczIgPQorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEucmVhZEdyb3VwS2V5UHJvcGVydGllcyh0ZXN0S2V5MikuZ2V0KCk7CisgICAgTWRkVGVzdFV0aWwuYXNzZXJ0TWVzc2FnZUVxdWFscyh3cml0ZUdyb3VwS2V5UHJvcGVydGllczIsIHJlYWRHcm91cEtleVByb3BlcnRpZXMyKTsKKworICAgIHZlcmlmeU5vRXJyb3JJblBkc01pZ3JhdGlvbigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY2xlYXJfcmVtb3Zlc0FsbE1ldGFkYXRhKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMiA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQXzIsIDEpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAzID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVBfMywgNSk7CisKKyAgICBGaWxlIHBhcmVudERpciA9CisgICAgICAgIG5ldyBGaWxlKGNvbnRleHQuZ2V0RmlsZXNEaXIoKSwgRGlyZWN0b3J5VXRpbC5NRERfU1RPUkFHRV9NT0RVTEUgKyAiLyIgKyAic2hhcmVkIik7CisgICAgYXNzZXJ0VGhhdChwYXJlbnREaXIubWtkaXJzKCkpLmlzVHJ1ZSgpOworICAgIEZpbGUgZ2FyYmFnZUZpbGUgPSBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLmdldEdhcmJhZ2VDb2xsZWN0b3JGaWxlKGNvbnRleHQsIGluc3RhbmNlSWQpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHN0YWxlRmlsZUdyb3VwID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKCJzdGFsZS1ncm91cCIsIDIpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0U3RhbGVMaWZldGltZVNlY3MoRHVyYXRpb24ub2ZEYXlzKDEpLmdldFNlY29uZHMoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUodGVzdEtleSwgZmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUodGVzdEtleTIsIGZpbGVHcm91cDIpLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZSh0ZXN0S2V5MywgZmlsZUdyb3VwMykuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmFkZFN0YWxlR3JvdXAoc3RhbGVGaWxlR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKworICAgIGZpbGVHcm91cHNNZXRhZGF0YS5jbGVhcigpLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEucmVhZCh0ZXN0S2V5KS5nZXQoKSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEucmVhZCh0ZXN0S2V5MikuZ2V0KCkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQodGVzdEtleTMpLmdldCgpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KGdhcmJhZ2VGaWxlLmV4aXN0cygpKS5pc0ZhbHNlKCk7CisKKyAgICBmb3IgKEZpbGUgZmlsZSA6IHBhcmVudERpci5saXN0RmlsZXMoKSkgeworICAgICAgYm9vbGVhbiB1bnVzZWQgPSBmaWxlLmRlbGV0ZSgpOworICAgIH0KKworICAgIHZlcmlmeU5vRXJyb3JJblBkc01pZ3JhdGlvbigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmV0cmlldmVBbGxHcm91cHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBHcm91cEtleSBub3RTZXREb3dubG9hZGVkR3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZShub3RTZXREb3dubG9hZGVkR3JvdXBLZXksIGZpbGVHcm91cDEpLmdldCgpKS5pc1RydWUoKTsKKworICAgIEdyb3VwS2V5IHNldFRydWVEb3dubG9hZGVkR3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUF8yKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRlZCh0cnVlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDIgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8yLCAyKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZShzZXRUcnVlRG93bmxvYWRlZEdyb3VwS2V5LCBmaWxlR3JvdXAyKS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBHcm91cEtleSBzZXRGYWxzZURvd25sb2FkZWRHcm91cEtleSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQXzMpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZGVkKGZhbHNlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDMgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUF8zLCAyKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZShzZXRGYWxzZURvd25sb2FkZWRHcm91cEtleSwgZmlsZUdyb3VwMykuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgaWYgKG1ldGFkYXRhU3RvcmVJbXBsID09IE1ldGFkYXRhU3RvcmVJbXBsLlNQX0lNUEwpIHsKKyAgICAgIC8vIEdhcmJhZ2UgZW50cnkgdGhhdCB3aWxsIGNyZWF0ZSBudWxsIEdyb3VwS2V5CisgICAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKAorICAgICAgICAgICAgICBjb250ZXh0LCBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLk1ERF9GSUxFX0dST1VQUywgaW5zdGFuY2VJZCk7CisgICAgICBwcmVmcy5lZGl0KCkucHV0U3RyaW5nKCJnYXJiYWdlLWtleSIsICJnYXJiYWdlLXZhbHVlIikuY29tbWl0KCk7CisgICAgfQorCisgICAgTGlzdDxQYWlyPEdyb3VwS2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+PiBhbGxHcm91cHMgPQorICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsRnJlc2hHcm91cHMoKS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGFsbEdyb3VwcykuaGFzU2l6ZSgzKTsKKworICAgIHZlcmlmeU5vRXJyb3JJblBkc01pZ3JhdGlvbigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlR3JvdXBzX25vR3JvdXBzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gTmV3ZXIgcGVuZGluZyB2ZXJzaW9uIG9mIHRoaXMgZ3JvdXAuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDEgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMik7CisgICAgR3JvdXBLZXkga2V5MSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRlZChmYWxzZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cFRvU2hhcmVkUHJlZnMoa2V5MSwgZmlsZUdyb3VwMSk7CisKKyAgICAvLyBPbGRlciBkb3dubG9hZGVkIHZlcnNpb24gb2YgdGhlIHNhbWUgZ3JvdXAKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMiA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKTsKKyAgICBHcm91cEtleSBrZXkyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZGVkKHRydWUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3cml0ZURvd25sb2FkZWRGaWxlR3JvdXBUb1NoYXJlZFByZWZzKGtleTIsIGZpbGVHcm91cDIpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEucmVtb3ZlQWxsR3JvdXBzV2l0aEtleXMoSW1tdXRhYmxlTGlzdC5vZigpKS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwRnJvbVNoYXJlZFByZWZzKGtleTEsIHRydWUgLypzaG91bGRFeGlzdCovKSkKKyAgICAgICAgLmlzRXF1YWxUbyhmaWxlR3JvdXAxKTsKKyAgICBhc3NlcnRUaGF0KHJlYWREb3dubG9hZGVkRmlsZUdyb3VwRnJvbVNoYXJlZFByZWZzKGtleTIsIHRydWUgLypzaG91bGRFeGlzdCovKSkKKyAgICAgICAgLmlzRXF1YWxUbyhmaWxlR3JvdXAyKTsKKworICAgIHZlcmlmeU5vRXJyb3JJblBkc01pZ3JhdGlvbigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlR3JvdXBzX3JlbW92ZVBlbmRpbmdHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIE5ld2VyIHBlbmRpbmcgdmVyc2lvbiBvZiB0aGlzIGdyb3VwLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAxID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworICAgIEdyb3VwS2V5IGtleTEgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkZWQoZmFsc2UpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXBUb1NoYXJlZFByZWZzKGtleTEsIGZpbGVHcm91cDEpOworCisgICAgLy8gT2xkZXIgZG93bmxvYWRlZCB2ZXJzaW9uIG9mIHRoZSBzYW1lIGdyb3VwCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDIgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisgICAgR3JvdXBLZXkga2V5MiA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRlZCh0cnVlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd3JpdGVEb3dubG9hZGVkRmlsZUdyb3VwVG9TaGFyZWRQcmVmcyhrZXkyLCBmaWxlR3JvdXAyKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlbW92ZUFsbEdyb3Vwc1dpdGhLZXlzKEFycmF5cy5hc0xpc3Qoa2V5MSkpLmdldCgpKS5pc1RydWUoKTsKKworICAgIHJlYWRQZW5kaW5nRmlsZUdyb3VwRnJvbVNoYXJlZFByZWZzKGtleTEsIGZhbHNlIC8qc2hvdWxkRXhpc3QqLyk7CisgICAgYXNzZXJ0VGhhdChyZWFkRG93bmxvYWRlZEZpbGVHcm91cEZyb21TaGFyZWRQcmVmcyhrZXkyLCB0cnVlIC8qc2hvdWxkRXhpc3QqLykpCisgICAgICAgIC5pc0VxdWFsVG8oZmlsZUdyb3VwMik7CisKKyAgICB2ZXJpZnlOb0Vycm9ySW5QZHNNaWdyYXRpb24oKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlbW92ZUdyb3Vwc19yZW1vdmVEb3dubG9hZGVkR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBOZXdlciBwZW5kaW5nIHZlcnNpb24gb2YgdGhpcyBncm91cC4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAyKTsKKyAgICBHcm91cEtleSBrZXkxID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZGVkKGZhbHNlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwVG9TaGFyZWRQcmVmcyhrZXkxLCBmaWxlR3JvdXAxKTsKKworICAgIC8vIE9sZGVyIGRvd25sb2FkZWQgdmVyc2lvbiBvZiB0aGUgc2FtZSBncm91cAorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAyID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIEdyb3VwS2V5IGtleTIgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLnNldERvd25sb2FkZWQodHJ1ZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cFRvU2hhcmVkUHJlZnMoa2V5MiwgZmlsZUdyb3VwMik7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5yZW1vdmVBbGxHcm91cHNXaXRoS2V5cyhBcnJheXMuYXNMaXN0KGtleTIpKS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBhc3NlcnRUaGF0KHJlYWRQZW5kaW5nRmlsZUdyb3VwRnJvbVNoYXJlZFByZWZzKGtleTEsIHRydWUgLypzaG91bGRFeGlzdCovKSkKKyAgICAgICAgLmlzRXF1YWxUbyhmaWxlR3JvdXAxKTsKKyAgICByZWFkRG93bmxvYWRlZEZpbGVHcm91cEZyb21TaGFyZWRQcmVmcyhrZXkyLCBmYWxzZSAvKnNob3VsZEV4aXN0Ki8pOworCisgICAgdmVyaWZ5Tm9FcnJvckluUGRzTWlncmF0aW9uKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBhZGRTdGFsZUdyb3VwX211bHRpcGxlR3JvdXBzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgbG9uZyBzdGFsZUV4cGlyYXRpb25MaWZldGltZVNlY3MgPSAxMDAwOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGZpbGVHcm91cDEgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRTdGFsZUxpZmV0aW1lU2VjcyhzdGFsZUV4cGlyYXRpb25MaWZldGltZVNlY3MpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMiA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAzKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFN0YWxlTGlmZXRpbWVTZWNzKHN0YWxlRXhwaXJhdGlvbkxpZmV0aW1lU2VjcykKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKS5nZXQoKSkuaXNFbXB0eSgpOworCisgICAgdGVzdENsb2NrLnNldCgxNTAwMCAvKiAxNSBzZWNvbmRzICovKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5hZGRTdGFsZUdyb3VwKGZpbGVHcm91cDEpLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5hZGRTdGFsZUdyb3VwKGZpbGVHcm91cDIpLmdldCgpKS5pc1RydWUoKTsKKworICAgIExpc3Q8RGF0YUZpbGVHcm91cEludGVybmFsPiBzdGFsZUdyb3VwcyA9IGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxTdGFsZUdyb3VwcygpLmdldCgpOworICAgIGFzc2VydFRoYXQoc3RhbGVHcm91cHMpLmhhc1NpemUoMik7CisKKyAgICBmaWxlR3JvdXAxID0gRmlsZUdyb3VwVXRpbC5zZXRTdGFsZUV4cGlyYXRpb25EYXRlKGZpbGVHcm91cDEsIHN0YWxlRXhwaXJhdGlvbkxpZmV0aW1lU2VjcyArIDE1KTsKKyAgICBmaWxlR3JvdXAyID0gRmlsZUdyb3VwVXRpbC5zZXRTdGFsZUV4cGlyYXRpb25EYXRlKGZpbGVHcm91cDIsIHN0YWxlRXhwaXJhdGlvbkxpZmV0aW1lU2VjcyArIDE1KTsKKworICAgIGFzc2VydFRoYXQoc3RhbGVHcm91cHMuZ2V0KDApKS5pc0VxdWFsVG8oZmlsZUdyb3VwMSk7CisgICAgYXNzZXJ0VGhhdChzdGFsZUdyb3Vwcy5nZXQoMSkpLmlzRXF1YWxUbyhmaWxlR3JvdXAyKTsKKworICAgIHZlcmlmeU5vRXJyb3JJblBkc01pZ3JhdGlvbigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVtb3ZlQWxsU3RhbGVHcm91cHNfbXVsdGlwbGVHcm91cHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBsb25nIHN0YWxlRXhwaXJhdGlvbkxpZmV0aW1lU2VjcyA9IDEwMDA7CisKKyAgICBMaXN0PERhdGFGaWxlR3JvdXBJbnRlcm5hbD4gZmlsZUdyb3VwcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBmaWxlR3JvdXAxID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0U3RhbGVMaWZldGltZVNlY3Moc3RhbGVFeHBpcmF0aW9uTGlmZXRpbWVTZWNzKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgZmlsZUdyb3Vwcy5hZGQoZmlsZUdyb3VwMSk7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwMiA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAzKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFN0YWxlTGlmZXRpbWVTZWNzKHN0YWxlRXhwaXJhdGlvbkxpZmV0aW1lU2VjcykKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGZpbGVHcm91cHMuYWRkKGZpbGVHcm91cDIpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKS5nZXQoKSkuaXNFbXB0eSgpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGVTdGFsZUdyb3VwcyhmaWxlR3JvdXBzKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEuZ2V0QWxsU3RhbGVHcm91cHMoKS5nZXQoKSkuaGFzU2l6ZSgyKTsKKworICAgIGZpbGVHcm91cHNNZXRhZGF0YS5yZW1vdmVBbGxTdGFsZUdyb3VwcygpLmdldCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbFN0YWxlR3JvdXBzKCkuZ2V0KCkpLmlzRW1wdHkoKTsKKworICAgIHZlcmlmeU5vRXJyb3JJblBkc01pZ3JhdGlvbigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgd3JpdGVTdGFsZUdyb3Vwc19ub0dyb3VwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTGlzdDxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGZpbGVHcm91cHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZVN0YWxlR3JvdXBzKGZpbGVHcm91cHMpLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5nZXRBbGxTdGFsZUdyb3VwcygpLmdldCgpKS5pc0VtcHR5KCk7CisgICAgdmVyaWZ5Tm9FcnJvckluUGRzTWlncmF0aW9uKCk7CisgIH0KKworICAvKioKKyAgICogVGhpcyB0ZXN0IG1haW5seSBleGlzdHMgdG8gZW5zdXJlIHRoYXQgdGhlIGdhcmJhZ2UgY29sbGVjdG9yIGhhbmRsZXMgSU8gb3BlcmF0aW9ucyBjb3JyZWN0bHkKKyAgICogZm9yIGxhcmdlIGlucHV0cy4KKyAgICovCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHdyaXRlQW5kUmVhZFN0YWxlR3JvdXBzX29uTG90c09mRmlsZUdyb3VwcygpIHRocm93cyBFeGNlcHRpb24geworICAgIGxvbmcgc3RhbGVFeHBpcmF0aW9uRGF0ZSA9IDEwMDA7CisKKyAgICAvLyBDcmVhdGUgZmlsZXMgb24gZGV2aWNlIHNvIHRoYXQgdGhlIGdhcmJhZ2UgY29sbGVjdG9yIGNhbiBkZWxldGUgdGhlbQorICAgIExpc3Q8RGF0YUZpbGVHcm91cEludGVybmFsPiBmaWxlR3JvdXBzID0gbmV3IEFycmF5TGlzdDw+KCk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA1OyArK2kpIHsKKyAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKCJncm91cCIgKyBpLCAxKTsKKyAgICAgIGRhdGFGaWxlR3JvdXAgPSBGaWxlR3JvdXBVdGlsLnNldFN0YWxlRXhwaXJhdGlvbkRhdGUoZGF0YUZpbGVHcm91cCwgc3RhbGVFeHBpcmF0aW9uRGF0ZSk7CisgICAgICBmaWxlR3JvdXBzLmFkZChkYXRhRmlsZUdyb3VwKTsKKyAgICB9CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS53cml0ZVN0YWxlR3JvdXBzKGZpbGVHcm91cHMpLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhCisgICAgICAgICAgICAgICAgLmdldEFsbFN0YWxlR3JvdXBzKCkKKyAgICAgICAgICAgICAgICAuZ2V0KCkKKyAgICAgICAgICAgICAgICAuZ2V0KDApCisgICAgICAgICAgICAgICAgLmdldEJvb2trZWVwaW5nKCkKKyAgICAgICAgICAgICAgICAuZ2V0U3RhbGVFeHBpcmF0aW9uRGF0ZSgpKQorICAgICAgICAuaXNFcXVhbFRvKDEwMDApOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLmdldEFsbFN0YWxlR3JvdXBzKCkuZ2V0KCkpLmNvbnRhaW5zRXhhY3RseUVsZW1lbnRzSW4oZmlsZUdyb3Vwcyk7CisKKyAgICB2ZXJpZnlOb0Vycm9ySW5QZHNNaWdyYXRpb24oKTsKKyAgfQorCisgIC8qKgorICAgKiBUaGlzIHRlc3QgbWFpbmx5IGV4aXN0cyB0byBlbnN1cmUgdGhhdCBhZnRlciBtaWdyYXRpbmcgdGhlIGdyb3VwIG1ldGFkYXRhIHN0b3JhZ2UgcHJvdG8gZnJvbQorICAgKiB7QGxpbmsgRGF0YUZpbGVHcm91cH0gdG8ge0BsaW5rIERhdGFGaWxlR3JvdXBJbnRlcm5hbH0sIE1ERCBpcyBzdGlsbCBhYmxlIHRvIHBhcnNlIHRoZSBncm91cAorICAgKiBtZXRhZGF0YSB3aGljaCB3YXMgcHJldmlvdXNseSB3cml0dGVuIHRvIGRpc2sgYmVmb3JlIHRoZSBtaWdyYXRpb24uCisgICAqLworICBAVGVzdAorICBwdWJsaWMgdm9pZCB3cml0ZUFuZFJlYWRHcm91cHNfbWlncmF0aW9uX2Zyb21EYXRhRmlsZUdyb3VwX3RvRGF0YUZpbGVHcm91cEludGVybmFsKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXAgZmlsZUdyb3VwMSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXAoVEVTVF9HUk9VUCwgMik7CisgICAgR3JvdXBLZXkga2V5MSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRlZChmYWxzZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQod3JpdGVEYXRhRmlsZUdyb3VwKGtleTEsIGZpbGVHcm91cDEsIGluc3RhbmNlSWQpKS5pc1RydWUoKTsKKworICAgIC8vIE9sZGVyIGRvd25sb2FkZWQgdmVyc2lvbiBvZiB0aGUgc2FtZSBncm91cAorICAgIERhdGFGaWxlR3JvdXAgZmlsZUdyb3VwMiA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXAoVEVTVF9HUk9VUCwgMSk7CisgICAgR3JvdXBLZXkga2V5MiA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRlZCh0cnVlKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdCh3cml0ZURhdGFGaWxlR3JvdXAoa2V5MiwgZmlsZUdyb3VwMiwgaW5zdGFuY2VJZCkpLmlzVHJ1ZSgpOworCisgICAgLy8gTWFrZSBzdXJlIHRoYXQgcGFyc2luZyBEYXRhRmlsZUdyb3VwIHRvIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwcm9kdWNlcyBpZGVudGljYWwgcmVzdWx0IGFzCisgICAgLy8gY2FsbGluZyBwcm90byBjb252ZXJ0LgorICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLnJlYWQoa2V5MSkuZ2V0KCkpCisgICAgICAgIC5pc0VxdWFsVG8oUHJvdG9Db252ZXJzaW9uVXRpbC5jb252ZXJ0KGZpbGVHcm91cDEpKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGtleTIpLmdldCgpKQorICAgICAgICAuaXNFcXVhbFRvKFByb3RvQ29udmVyc2lvblV0aWwuY29udmVydChmaWxlR3JvdXAyKSk7CisKKyAgICB2ZXJpZnlOb0Vycm9ySW5QZHNNaWdyYXRpb24oKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdhcmJhZ2VDb2xsZWN0b3JGaWxlU2VwYXJhdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIFNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhIGZpbGVHcm91cHNNZXRhZGF0YUFic2VudCA9CisgICAgICAgIG5ldyBTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YSgKKyAgICAgICAgICAgIGNvbnRleHQsIHRlc3RDbG9jaywgbW9ja1NpbGVudEZlZWRiYWNrLCBPcHRpb25hbC5hYnNlbnQoKSwgQ09OVFJPTF9FWEVDVVRPUik7CisKKyAgICBTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGEyID0KKyAgICAgICAgbmV3IFNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhKAorICAgICAgICAgICAgY29udGV4dCwgdGVzdENsb2NrLCBtb2NrU2lsZW50RmVlZGJhY2ssIE9wdGlvbmFsLm9mKCJpbnN0YW5jZTIiKSwgQ09OVFJPTF9FWEVDVVRPUik7CisKKyAgICBTaGFyZWRQcmVmZXJlbmNlc0ZpbGVHcm91cHNNZXRhZGF0YSBmaWxlR3JvdXBzTWV0YWRhdGEzID0KKyAgICAgICAgbmV3IFNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhKAorICAgICAgICAgICAgY29udGV4dCwgdGVzdENsb2NrLCBtb2NrU2lsZW50RmVlZGJhY2ssIE9wdGlvbmFsLm9mKCJpbnN0YW5jZTMiKSwgQ09OVFJPTF9FWEVDVVRPUik7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YUFic2VudC5nZXRHYXJiYWdlQ29sbGVjdG9yRmlsZSgpLmdldEFic29sdXRlUGF0aCgpKQorICAgICAgICAuaXNOb3RFcXVhbFRvKGZpbGVHcm91cHNNZXRhZGF0YTIuZ2V0R2FyYmFnZUNvbGxlY3RvckZpbGUoKS5nZXRBYnNvbHV0ZVBhdGgoKSk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cHNNZXRhZGF0YTIuZ2V0R2FyYmFnZUNvbGxlY3RvckZpbGUoKS5nZXRBYnNvbHV0ZVBhdGgoKSkKKyAgICAgICAgLmlzTm90RXF1YWxUbyhmaWxlR3JvdXBzTWV0YWRhdGEzLmdldEdhcmJhZ2VDb2xsZWN0b3JGaWxlKCkuZ2V0QWJzb2x1dGVQYXRoKCkpOworICB9CisKKyAgLyoqCisgICAqIFdyaXRlcyB7QGxpbmsgRGF0YUZpbGVHcm91cH0gaW50byBkaXNrLiBUaGUgbWFpbiBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIGZvciB0aGUgY29udmVuaWVuY2UKKyAgICogb2YgbWlncmF0aW9uIHRlc3RzLiBQcmV2aW91c2x5LCB0aGUgZmlsZSBncm91cCBtZXRhZGF0YSBpcyBzdG9yZWQgaW4gRGF0YUZpbGVHcm91cCB3aXRoCisgICAqIGV4dGVuc2lvbnMuIFdlIHdhbnRlZCB0byBtYWtlIHN1cmUgdGhhdCBhZnRlciBtaWdyYXRpbmcgdG8ge0BsaW5rIERhdGFGaWxlR3JvdXBJbnRlcm5hbH0sIHRoZQorICAgKiBwcmV2aW91cyBtZXRhZGF0YSBjYW4gc3RpbGwgYmUgcGFyc2VkLgorICAgKi8KKyAgYm9vbGVhbiB3cml0ZURhdGFGaWxlR3JvdXAoCisgICAgICBHcm91cEtleSBncm91cEtleSwgRGF0YUZpbGVHcm91cCBmaWxlR3JvdXAsIE9wdGlvbmFsPFN0cmluZz4gaW5zdGFuY2VJZCkgeworICAgIFN0cmluZyBzZXJpYWxpemVkR3JvdXBLZXkgPSBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLmdldFNlcmlhbGl6ZWRHcm91cEtleShncm91cEtleSwgY29udGV4dCk7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMgcHJlZnMgPQorICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoCisgICAgICAgICAgICBjb250ZXh0LCBGaWxlR3JvdXBzTWV0YWRhdGFVdGlsLk1ERF9GSUxFX0dST1VQUywgaW5zdGFuY2VJZCk7CisgICAgcmV0dXJuIFNoYXJlZFByZWZlcmVuY2VzVXRpbC53cml0ZVByb3RvKHByZWZzLCBzZXJpYWxpemVkR3JvdXBLZXksIGZpbGVHcm91cCk7CisgIH0KKworICBwcml2YXRlIERhdGFGaWxlR3JvdXBJbnRlcm5hbCByZWFkUGVuZGluZ0ZpbGVHcm91cEZyb21TaGFyZWRQcmVmcygKKyAgICAgIEdyb3VwS2V5IGtleSwgYm9vbGVhbiBzaG91bGRFeGlzdCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgR3JvdXBLZXkgZHVwbGljYXRlR3JvdXBLZXkgPSBrZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKyAgICByZXR1cm4gcmVhZEZpbGVHcm91cEZyb21TaGFyZWRQcmVmcyhkdXBsaWNhdGVHcm91cEtleSwgc2hvdWxkRXhpc3QpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHdyaXRlUGVuZGluZ0ZpbGVHcm91cFRvU2hhcmVkUHJlZnMoR3JvdXBLZXkga2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZ3JvdXApCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBHcm91cEtleSBkdXBsaWNhdGVHcm91cEtleSA9IGtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKGZhbHNlKS5idWlsZCgpOworICAgIGFzc2VydFRoYXQoZmlsZUdyb3Vwc01ldGFkYXRhLndyaXRlKGR1cGxpY2F0ZUdyb3VwS2V5LCBncm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICB9CisKKyAgcHJpdmF0ZSBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgcmVhZERvd25sb2FkZWRGaWxlR3JvdXBGcm9tU2hhcmVkUHJlZnMoCisgICAgICBHcm91cEtleSBrZXksIGJvb2xlYW4gc2hvdWxkRXhpc3QpIHRocm93cyBFeGNlcHRpb24geworICAgIEdyb3VwS2V5IGR1cGxpY2F0ZUdyb3VwS2V5ID0ga2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkZWQodHJ1ZSkuYnVpbGQoKTsKKyAgICByZXR1cm4gcmVhZEZpbGVHcm91cEZyb21TaGFyZWRQcmVmcyhkdXBsaWNhdGVHcm91cEtleSwgc2hvdWxkRXhpc3QpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHdyaXRlRG93bmxvYWRlZEZpbGVHcm91cFRvU2hhcmVkUHJlZnMoR3JvdXBLZXkga2V5LCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZ3JvdXApCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBHcm91cEtleSBkdXBsaWNhdGVHcm91cEtleSA9IGtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZGVkKHRydWUpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUoZHVwbGljYXRlR3JvdXBLZXksIGdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgIH0KKworICBwcml2YXRlIERhdGFGaWxlR3JvdXBJbnRlcm5hbCByZWFkRmlsZUdyb3VwRnJvbVNoYXJlZFByZWZzKEdyb3VwS2V5IGtleSwgYm9vbGVhbiBzaG91bGRFeGlzdCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBncm91cCA9IGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKGtleSkuZ2V0KCk7CisgICAgaWYgKHNob3VsZEV4aXN0KSB7CisgICAgICBhc3NlcnRXaXRoTWVzc2FnZShTdHJpbmcuZm9ybWF0KCJFeHBlY3RlZCB0aGF0IGtleSAlcyBzaG91bGQgZXhpc3QuIiwga2V5KSkKKyAgICAgICAgICAudGhhdChncm91cCkKKyAgICAgICAgICAuaXNOb3ROdWxsKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIGFzc2VydFdpdGhNZXNzYWdlKFN0cmluZy5mb3JtYXQoIkV4cGVjdGVkIHRoYXQga2V5ICVzIHNob3VsZCBub3QgZXhpc3QuIiwga2V5KSkKKyAgICAgICAgICAudGhhdChncm91cCkKKyAgICAgICAgICAuaXNOdWxsKCk7CisgICAgfQorICAgIHJldHVybiBncm91cDsKKyAgfQorCisgIHByaXZhdGUgdm9pZCB2ZXJpZnlOb0Vycm9ySW5QZHNNaWdyYXRpb24oKSB7fQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL01kZElzb2xhdGVkU3RydWN0dXJlc1Rlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9NZGRJc29sYXRlZFN0cnVjdHVyZXNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTgyZjQxMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9NZGRJc29sYXRlZFN0cnVjdHVyZXNUZXN0LmphdmEKQEAgLTAsMCArMSwyNTUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGphdmEubmlvLmNoYXJzZXQuU3RhbmRhcmRDaGFyc2V0cy5VVEZfMTY7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuZXh0Lmp1bml0LnJ1bm5lcnMuQW5kcm9pZEpVbml0NDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5TaWxlbnRGZWVkYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5BbmRyb2lkRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5BbmRyb2lkVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuRmFrZUZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVtcG9yYXJ5VXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUub3BlbmVycy5Xcml0ZUJ5dGVBcnJheU9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5kb3dubG9hZGVyLk1kZEZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmV4cGVyaW1lbnRhdGlvbi5Ob09wRG93bmxvYWRTdGFnZU1hbmFnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5FdmVudExvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLlN5bWxpbmtVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRlc3RpbmcuRmFrZVRpbWVTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5UZXN0RmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQXN5bmNGdW5jdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsLkFsbG93ZWRSZWFkZXJzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRG93bmxvYWRDb25kaXRpb25zOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRmlsZVN0YXR1czsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkdyb3VwS2V5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uTmV3RmlsZUtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLlNoYXJlZEZpbGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm1vY2tpdG8uTW9jazsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvSlVuaXQ7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b1J1bGU7CisKKy8qKgorICogRW11bGF0b3IgdGVzdHMgZm9yIE1ERCBpc29sYXRlZCBzdHJ1Y3R1cmVzIHN1cHBvcnQuIFRoaXMgaXMgc2VwYXJhdGUgZnJvbSB0aGUgb3RoZXIgcm9ib2xlY3RyaWMKKyAqIHRlc3RzIGJlY2F1c2UgYW5kcm9pZC5vcy5zeW1saW5rIGFuZCBhbmRyb2lkLm9zLnJlYWRsaW5rIGRvIG5vdCB3b3JrIHdpdGggcm9ib2xlY3RyaWMuCisgKi8KK0BSdW5XaXRoKEFuZHJvaWRKVW5pdDQuY2xhc3MpCitwdWJsaWMgZmluYWwgY2xhc3MgTWRkSXNvbGF0ZWRTdHJ1Y3R1cmVzVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfR1JPVVAgPSAidGVzdC1ncm91cCI7CisKKyAgQFJ1bGUgcHVibGljIFRlbXBvcmFyeVVyaSB0ZW1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworCisgIHByaXZhdGUgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIEZpbGVHcm91cE1hbmFnZXIgZmlsZUdyb3VwTWFuYWdlcjsKKyAgcHJpdmF0ZSBGaWxlR3JvdXBzTWV0YWRhdGEgZmlsZUdyb3Vwc01ldGFkYXRhOworICBwcml2YXRlIFNoYXJlZEZpbGVNYW5hZ2VyIHNoYXJlZEZpbGVNYW5hZ2VyOworICBwcml2YXRlIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YTsKKyAgcHJpdmF0ZSBGYWtlVGltZVNvdXJjZSB0ZXN0Q2xvY2s7CisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHJpdmF0ZSBGYWtlRmlsZUJhY2tlbmQgZmFrZUFuZHJvaWRGaWxlQmFja2VuZDsKKyAgQE1vY2sgU2lsZW50RmVlZGJhY2sgbW9ja1NpbGVudEZlZWRiYWNrOworCisgIEdyb3VwS2V5IGRlZmF1bHRHcm91cEtleTsKKyAgRGF0YUZpbGVHcm91cEludGVybmFsIGRlZmF1bHRGaWxlR3JvdXA7CisgIERhdGFGaWxlIGZpbGU7CisgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleTsKKyAgU2hhcmVkRmlsZSBleGlzdGluZ1NoYXJlZEZpbGU7CisKKyAgQE1vY2sgTWRkRmlsZURvd25sb2FkZXIgbW9ja0Rvd25sb2FkZXI7CisgIEBNb2NrIEV2ZW50TG9nZ2VyIG1vY2tMb2dnZXI7CisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NraXRvID0gTW9ja2l0b0pVbml0LnJ1bGUoKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFeGVjdXRvciBTRVFVRU5USUFMX0NPTlRST0xfRVhFQ1VUT1IgPQorICAgICAgRXhlY3V0b3JzLm5ld1NpbmdsZVRocmVhZFNjaGVkdWxlZEV4ZWN1dG9yKCk7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGNvbnRleHQgPSBBcHBsaWNhdGlvblByb3ZpZGVyLmdldEFwcGxpY2F0aW9uQ29udGV4dCgpOworCisgICAgdGVzdENsb2NrID0gbmV3IEZha2VUaW1lU291cmNlKCk7CisKKyAgICBUZXN0RmxhZ3MgZmxhZ3MgPSBuZXcgVGVzdEZsYWdzKCk7CisKKyAgICBmYWtlQW5kcm9pZEZpbGVCYWNrZW5kID0gbmV3IEZha2VGaWxlQmFja2VuZChBbmRyb2lkRmlsZUJhY2tlbmQuYnVpbGRlcihjb250ZXh0KS5idWlsZCgpKTsKKyAgICBmaWxlU3RvcmFnZSA9IG5ldyBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlKEFycmF5cy5hc0xpc3QoZmFrZUFuZHJvaWRGaWxlQmFja2VuZCkpOworCisgICAgZmlsZUdyb3Vwc01ldGFkYXRhID0KKyAgICAgICAgbmV3IFNoYXJlZFByZWZlcmVuY2VzRmlsZUdyb3Vwc01ldGFkYXRhKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIHRlc3RDbG9jaywKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgTW9yZUV4ZWN1dG9ycy5kaXJlY3RFeGVjdXRvcigpKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhID0KKyAgICAgICAgbmV3IFNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YSgKKyAgICAgICAgICAgIGNvbnRleHQsIG1vY2tTaWxlbnRGZWVkYmFjaywgT3B0aW9uYWwuYWJzZW50KCksIGZsYWdzKTsKKyAgICBzaGFyZWRGaWxlTWFuYWdlciA9CisgICAgICAgIG5ldyBTaGFyZWRGaWxlTWFuYWdlcigKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBtb2NrRG93bmxvYWRlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBtb2NrTG9nZ2VyLAorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBmaWxlR3JvdXBzTWV0YWRhdGEsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIE1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3IoKSk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyID0KKyAgICAgICAgbmV3IEZpbGVHcm91cE1hbmFnZXIoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0xvZ2dlciwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YSwKKyAgICAgICAgICAgIHNoYXJlZEZpbGVNYW5hZ2VyLAorICAgICAgICAgICAgbmV3IEZha2VUaW1lU291cmNlKCksCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIFNFUVVFTlRJQUxfQ09OVFJPTF9FWEVDVVRPUiwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBuZXcgTm9PcERvd25sb2FkU3RhZ2VNYW5hZ2VyKCksCisgICAgICAgICAgICBmbGFncyk7CisKKyAgICBkZWZhdWx0R3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgZGVmYXVsdEZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFByZXNlcnZlRmlsZW5hbWVzQW5kSXNvbGF0ZUZpbGVzKHRydWUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBmaWxlID0gZGVmYXVsdEZpbGVHcm91cC5nZXRGaWxlKDApOworCisgICAgbmV3RmlsZUtleSA9IFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisKKyAgICBleGlzdGluZ1NoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgiZmlsZU5hbWUiKQorICAgICAgICAgICAgLnNldEFuZHJvaWRTaGFyZWQoZmFsc2UpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RTeW1saW5rVXRpbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIFVyaSB0YXJnZXRVcmkgPSBBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuc2V0UmVsYXRpdmVQYXRoKCJ0YXJnZXRGaWxlIikuYnVpbGQoKTsKKyAgICAvLyBXcml0ZSBzb21lIGRhdGEgc28gdGhlIHRhcmdldCBmaWxlIGV4aXN0cy4KKyAgICBmaWxlU3RvcmFnZS5vcGVuKHRhcmdldFVyaSwgV3JpdGVCeXRlQXJyYXlPcGVuZXIuY3JlYXRlKCJzb21lIGJ5dGVzIi5nZXRCeXRlcyhVVEZfMTYpKSk7CisKKyAgICBVcmkgbGlua1VyaSA9IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRSZWxhdGl2ZVBhdGgoImxpbmtGaWxlIikuYnVpbGQoKTsKKworICAgIFN5bWxpbmtVdGlsLmNyZWF0ZVN5bWxpbmsoY29udGV4dCwgbGlua1VyaSwgdGFyZ2V0VXJpKTsKKworICAgIC8vIE1ha2Ugc3VyZSB0aGUgc3ltbGluayBwb2ludHMgdG8gdGhlIG9yaWdpbmFsIHRhcmdldAorICAgIGFzc2VydFRoYXQoU3ltbGlua1V0aWwucmVhZFN5bWxpbmsoY29udGV4dCwgbGlua1VyaSkpLmlzRXF1YWxUbyh0YXJnZXRVcmkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEZpbGVHcm91cE1hbmFnZXJfY3JlYXRlc0lzb2xhdGVkU3RydWN0dXJlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChkZWZhdWx0R3JvdXBLZXksIGRlZmF1bHRGaWxlR3JvdXApOworICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEud3JpdGUobmV3RmlsZUtleSwgZXhpc3RpbmdTaGFyZWRGaWxlKS5nZXQoKTsKKworICAgIFVyaSBvbkRldmljZVVyaSA9IGZpbGVHcm91cE1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZSwgZGVmYXVsdEZpbGVHcm91cCkuZ2V0KCk7CisgICAgLy8gQWN0dWFsbHkgd3JpdGUgc29tZXRoaW5nIHRvIGRpc2sgc28gdGhlIHN5bWxpbmsgcG9pbnRzIHRvIHNvbWV0aGluZy4KKyAgICBmaWxlU3RvcmFnZS5vcGVuKG9uRGV2aWNlVXJpLCBXcml0ZUJ5dGVBcnJheU9wZW5lci5jcmVhdGUoInNvbWUgY29udGVudCIuZ2V0Qnl0ZXMoVVRGXzE2KSkpOworCisgICAgLy8gRG93bmxvYWQgdGhlIGZpbGUgZ3JvdXAgc28gTUREIGNyZWF0ZXMgdGhlIHN0cnVjdHVyZXMKKyAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIGRlZmF1bHRHcm91cEtleSwgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgVXJpIGlzb2xhdGVkRmlsZVVyaSA9CisgICAgICAgIGZpbGVHcm91cE1hbmFnZXIuZ2V0QW5kVmVyaWZ5SXNvbGF0ZWRGaWxlVXJpKG9uRGV2aWNlVXJpLCBmaWxlLCBkZWZhdWx0RmlsZUdyb3VwKTsKKworICAgIGFzc2VydFRoYXQoU3ltbGlua1V0aWwucmVhZFN5bWxpbmsoY29udGV4dCwgaXNvbGF0ZWRGaWxlVXJpKSkuaXNFcXVhbFRvKG9uRGV2aWNlVXJpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RGaWxlR3JvdXBNYW5hZ2VyX2dldERvd25sb2FkZWRGaWxlR3JvdXBfcmV0dXJuc051bGxJZklzb2xhdGVkU3RydWN0dXJlc0RvbnRFeGlzdCgpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3cml0ZVBlbmRpbmdGaWxlR3JvdXAoZGVmYXVsdEdyb3VwS2V5LCBkZWZhdWx0RmlsZUdyb3VwKTsKKyAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKG5ld0ZpbGVLZXksIGV4aXN0aW5nU2hhcmVkRmlsZSkuZ2V0KCk7CisKKyAgICBmaWxlR3JvdXBNYW5hZ2VyCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cCgKKyAgICAgICAgICAgIGRlZmF1bHRHcm91cEtleSwgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSkKKyAgICAgICAgLmdldCgpOworCisgICAgVXJpIG9uRGV2aWNlVXJpID0gZmlsZUdyb3VwTWFuYWdlci5nZXRPbkRldmljZVVyaShmaWxlLCBkZWZhdWx0RmlsZUdyb3VwKS5nZXQoKTsKKyAgICBVcmkgaXNvbGF0ZWRGaWxlVXJpID0KKyAgICAgICAgZmlsZUdyb3VwTWFuYWdlci5nZXRBbmRWZXJpZnlJc29sYXRlZEZpbGVVcmkob25EZXZpY2VVcmksIGZpbGUsIGRlZmF1bHRGaWxlR3JvdXApOworCisgICAgZmlsZVN0b3JhZ2UuZGVsZXRlRmlsZShpc29sYXRlZEZpbGVVcmkpOworCisgICAgYXNzZXJ0VGhhdChmaWxlR3JvdXBNYW5hZ2VyLmdldEZpbGVHcm91cChkZWZhdWx0R3JvdXBLZXksIHRydWUpLmdldCgpKS5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RGaWxlR3JvdXBNYW5hZ2VyX3JlcGFpcnNJc29sYXRlZFN0cnVjdHVyZXNPbk1haW50ZW5hbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgd3JpdGVQZW5kaW5nRmlsZUdyb3VwKGRlZmF1bHRHcm91cEtleSwgZGVmYXVsdEZpbGVHcm91cCk7CisgICAgc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBleGlzdGluZ1NoYXJlZEZpbGUpLmdldCgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlcgorICAgICAgICAuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICBkZWZhdWx0R3JvdXBLZXksIERvd25sb2FkQ29uZGl0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIFVyaSBvbkRldmljZVVyaSA9IGZpbGVHcm91cE1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZmlsZSwgZGVmYXVsdEZpbGVHcm91cCkuZ2V0KCk7CisgICAgVXJpIGlzb2xhdGVkRmlsZVVyaSA9CisgICAgICAgIGZpbGVHcm91cE1hbmFnZXIuZ2V0QW5kVmVyaWZ5SXNvbGF0ZWRGaWxlVXJpKG9uRGV2aWNlVXJpLCBmaWxlLCBkZWZhdWx0RmlsZUdyb3VwKTsKKworICAgIGFzc2VydFRoYXQoZmlsZUdyb3VwTWFuYWdlci5nZXRGaWxlR3JvdXAoZGVmYXVsdEdyb3VwS2V5LCB0cnVlKS5nZXQoKSkuaXNOb3ROdWxsKCk7CisKKyAgICBmaWxlU3RvcmFnZS5kZWxldGVGaWxlKGlzb2xhdGVkRmlsZVVyaSk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGRlZmF1bHRHcm91cEtleSwgdHJ1ZSkuZ2V0KCkpLmlzTnVsbCgpOworCisgICAgZmlsZUdyb3VwTWFuYWdlci52ZXJpZnlBbmRBdHRlbXB0VG9SZXBhaXJJc29sYXRlZEZpbGVzKCkuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KGZpbGVHcm91cE1hbmFnZXIuZ2V0RmlsZUdyb3VwKGRlZmF1bHRHcm91cEtleSwgdHJ1ZSkuZ2V0KCkpLmlzTm90TnVsbCgpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHdyaXRlUGVuZGluZ0ZpbGVHcm91cChHcm91cEtleSBrZXksIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBncm91cCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgR3JvdXBLZXkgZHVwbGljYXRlR3JvdXBLZXkgPSBrZXkudG9CdWlsZGVyKCkuc2V0RG93bmxvYWRlZChmYWxzZSkuYnVpbGQoKTsKKyAgICBmaWxlR3JvdXBzTWV0YWRhdGEud3JpdGUoZHVwbGljYXRlR3JvdXBLZXksIGdyb3VwKS5nZXQoKTsKKyAgfQorCisgIHByaXZhdGUgQXN5bmNGdW5jdGlvbjxEYXRhRmlsZUdyb3VwSW50ZXJuYWwsIEJvb2xlYW4+IG5vQ3VzdG9tVmFsaWRhdGlvbigpIHsKKyAgICByZXR1cm4gdW51c2VkIC0+IEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvTWRkVGVzdFV0aWwuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9NZGRUZXN0VXRpbC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBjZmE0MzYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvTWRkVGVzdFV0aWwuamF2YQpAQCAtMCwwICsxLDMyOSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWw7CisKK2ltcG9ydCBzdGF0aWMgYW5kcm9pZHgudGVzdC5wbGF0Zm9ybS5hcHAuSW5zdHJ1bWVudGF0aW9uUmVnaXN0cnkuZ2V0SW5zdHJ1bWVudGF0aW9uOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRXaXRoTWVzc2FnZTsKK2ltcG9ydCBzdGF0aWMgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQuREFZUzsKK2ltcG9ydCBzdGF0aWMgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQuTUlMTElTRUNPTkRTOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZC5WRVJTSU9OOworaW1wb3J0IGFuZHJvaWQuc3VwcG9ydC50ZXN0LnVpYXV0b21hdG9yLlVpRGV2aWNlOworaW1wb3J0IGFuZHJvaWQudXRpbC5Mb2c7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmFwcHMuY29tbW9uLnRlc3RpbmcudXRpbC5CYWNrZG9vclRlc3RVdGlsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5aaXBUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5CYXNlRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGVHcm91cEludGVybmFsOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGVsdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGVsdGFGaWxlLkRpZmZEZWNvZGVyOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRmlsZVN0YXR1czsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLk5ld0ZpbGVLZXk7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5TaGFyZWRGaWxlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZUxpdGU7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK3B1YmxpYyBjbGFzcyBNZGRUZXN0VXRpbCB7CisKKyAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9VUkkgPSAiYW5kcm9pZDovL2ZpbGUiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHID0gIk1kZFRlc3RVdGlsIjsKKworICAvKioKKyAgICogQ3JlYXRlcyBhIGRhdGEgZmlsZSBncm91cCB3aXRoIHRoZSBnaXZlbiBudW1iZXIgb2YgZmlsZXMuIEl0IG9ubHkgc2V0cyB0aGUgZmllbGQgdGhhdCBhcmUgc2V0CisgICAqIGluIGEgZGF0YSBmaWxlIGdyb3VwIHRoYXQgd2UgZ2V0IGZyb20gdGhlIHNlcnZlci4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgRGF0YUZpbGVHcm91cCBjcmVhdGVEYXRhRmlsZUdyb3VwKFN0cmluZyBmaWxlR3JvdXBOYW1lLCBpbnQgZmlsZUNvdW50KSB7CisgICAgRGF0YUZpbGVHcm91cC5CdWlsZGVyIGRhdGFGaWxlR3JvdXAgPSBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKS5zZXRHcm91cE5hbWUoZmlsZUdyb3VwTmFtZSk7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWxlQ291bnQ7ICsraSkgeworICAgICAgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZS5CdWlsZGVyIGZpbGUgPQorICAgICAgICAgIGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGUubmV3QnVpbGRlcigpOworICAgICAgZmlsZS5zZXRGaWxlSWQoU3RyaW5nLmZvcm1hdCgiJXNfJXMiLCBmaWxlR3JvdXBOYW1lLCBpKSk7CisgICAgICBmaWxlLnNldFVybFRvRG93bmxvYWQoU3RyaW5nLmZvcm1hdCgiaHR0cHM6Ly8lc18lcyIsIGZpbGVHcm91cE5hbWUsIGkpKTsKKyAgICAgIGZpbGUuc2V0Qnl0ZVNpemUoMTAgKyBpKTsKKyAgICAgIGZpbGUuc2V0Q2hlY2tzdW0oIjEyMyIgKyBpKTsKKyAgICAgIGRhdGFGaWxlR3JvdXAuYWRkRmlsZShmaWxlLmJ1aWxkKCkpOworICAgIH0KKyAgICByZXR1cm4gZGF0YUZpbGVHcm91cC5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYW4gaW50ZXJuYWwgZGF0YSBmaWxlIGdyb3VwIHdpdGggdGhlIGdpdmVuIG51bWJlciBvZiBmaWxlcy4gSXQgb25seSBzZXRzIHRoZSBmaWVsZCB0aGF0CisgICAqIGFyZSBzZXQgaW4gYSBkYXRhIGZpbGUgZ3JvdXAgdGhhdCB3ZSBnZXQgZnJvbSB0aGUgc2VydmVyLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKAorICAgICAgU3RyaW5nIGZpbGVHcm91cE5hbWUsIGludCBmaWxlQ291bnQpIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBkYXRhRmlsZUdyb3VwSW50ZXJuYWwgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShmaWxlR3JvdXBOYW1lKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVDb3VudDsgKytpKSB7CisgICAgICBkYXRhRmlsZUdyb3VwSW50ZXJuYWwuYWRkRmlsZShjcmVhdGVEYXRhRmlsZShmaWxlR3JvdXBOYW1lLCBpKSk7CisgICAgfQorICAgIHJldHVybiBkYXRhRmlsZUdyb3VwSW50ZXJuYWwuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGFuIGludGVybmFsIGRhdGEgZmlsZSBncm91cCB3aXRoIHRoZSBnaXZlbiBudW1iZXIgb2YgZmlsZXMuIEl0IG9ubHkgc2V0cyB0aGUgZmllbGQgdGhhdAorICAgKiBhcmUgc2V0IGluIGEgZGF0YSBmaWxlIGdyb3VwIHRoYXQgd2UgZ2V0IGZyb20gdGhlIHNlcnZlci4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgRGF0YUZpbGVHcm91cEludGVybmFsIGNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbFdpdGhEb3dubG9hZElkKAorICAgICAgU3RyaW5nIGZpbGVHcm91cE5hbWUsIGludCBmaWxlQ291bnQpIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBkYXRhRmlsZUdyb3VwSW50ZXJuYWwgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShmaWxlR3JvdXBOYW1lKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVDb3VudDsgKytpKSB7CisgICAgICBkYXRhRmlsZUdyb3VwSW50ZXJuYWwuYWRkRmlsZShjcmVhdGVEYXRhRmlsZShmaWxlR3JvdXBOYW1lLCBpKSk7CisgICAgfQorICAgIHJldHVybiBkYXRhRmlsZUdyb3VwSW50ZXJuYWwuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGFuIGludGVybmFsIGRhdGEgZmlsZSBncm91cCB3aXRoIHRoZSBnaXZlbiBudW1iZXIgb2YgZmlsZXMsIGFsbCBjb25maWd1cmVkIHRvIGJlCisgICAqIHNoYXJlZC4gSXQgb25seSBzZXRzIHRoZSBmaWVsZCB0aGF0IGFyZSBzZXQgaW4gYSBkYXRhIGZpbGUgZ3JvdXAgdGhhdCB3ZSBnZXQgZnJvbSB0aGUgc2VydmVyLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgY3JlYXRlU2hhcmVkRGF0YUZpbGVHcm91cEludGVybmFsKAorICAgICAgU3RyaW5nIGZpbGVHcm91cE5hbWUsIGludCBmaWxlQ291bnQpIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBkYXRhRmlsZUdyb3VwSW50ZXJuYWwgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZShmaWxlR3JvdXBOYW1lKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVDb3VudDsgKytpKSB7CisgICAgICBkYXRhRmlsZUdyb3VwSW50ZXJuYWwuYWRkRmlsZShjcmVhdGVTaGFyZWREYXRhRmlsZShmaWxlR3JvdXBOYW1lLCAvKiBmaWxlSW5kZXggPSAqLyBpKSk7CisgICAgfQorICAgIHJldHVybiBkYXRhRmlsZUdyb3VwSW50ZXJuYWwuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGEgZGF0YSBmaWxlIGdyb3VwIHdpdGggdGhlIGdpdmVuIG51bWJlciBvZiBmaWxlcy4gSXQgY3JlYXRlcyBhIGRvd25sb2FkZWQgZmlsZSwgc28gdGhlCisgICAqIGZpbGUgdXJpIGlzIGFsc28gc2V0LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgY3JlYXRlRG93bmxvYWRlZERhdGFGaWxlR3JvdXBJbnRlcm5hbCgKKyAgICAgIFN0cmluZyBmaWxlR3JvdXBOYW1lLCBpbnQgZmlsZUNvdW50KSB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsLkJ1aWxkZXIgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkuc2V0R3JvdXBOYW1lKGZpbGVHcm91cE5hbWUpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmlsZUNvdW50OyArK2kpIHsKKyAgICAgIGRhdGFGaWxlR3JvdXAuYWRkRmlsZShjcmVhdGVEb3dubG9hZGVkRGF0YUZpbGUoZmlsZUdyb3VwTmFtZSwgaSkpOworICAgIH0KKyAgICByZXR1cm4gZGF0YUZpbGVHcm91cC5idWlsZCgpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgRGF0YUZpbGUgY3JlYXRlRG93bmxvYWRlZERhdGFGaWxlKFN0cmluZyBmaWxlSWQsIGludCBmaWxlSW5kZXgpIHsKKyAgICBEYXRhRmlsZSBmaWxlID0gY3JlYXRlRGF0YUZpbGUoZmlsZUlkLCBmaWxlSW5kZXgpOworICAgIHJldHVybiBmaWxlOworICB9CisKKyAgcHVibGljIHN0YXRpYyBEYXRhRmlsZSBjcmVhdGVEYXRhRmlsZShTdHJpbmcgZmlsZUlkLCBpbnQgZmlsZUluZGV4KSB7CisgICAgRGF0YUZpbGUuQnVpbGRlciBmaWxlID0gRGF0YUZpbGUubmV3QnVpbGRlcigpOworICAgIGZpbGUuc2V0RmlsZUlkKFN0cmluZy5mb3JtYXQoIiVzXyVzIiwgZmlsZUlkLCBmaWxlSW5kZXgpKTsKKyAgICBmaWxlLnNldFVybFRvRG93bmxvYWQoU3RyaW5nLmZvcm1hdCgiaHR0cHM6Ly8lc18lcyIsIGZpbGVJZCwgZmlsZUluZGV4KSk7CisgICAgZmlsZS5zZXRCeXRlU2l6ZSgxMCArIGZpbGVJbmRleCk7CisgICAgZmlsZS5zZXRDaGVja3N1bSgiMTIzIiArIGZpbGVJbmRleCk7CisgICAgcmV0dXJuIGZpbGUuYnVpbGQoKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGEgZGF0YUZpbGUgY29uZmlndXJlZCBmb3Igc2hhcmluZywgaS5lLiB3aXRoIENoZWNrc3VtVHlwZSBzZXQgdG8gU0hBMjU2IGFuZAorICAgKiBBbmRyb2lkU2hhcmluZ1R5cGUgc2V0IHRvIEFORFJPSURfQkxPQl9XSEVOX0FWQUlMQUJMRS4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgRGF0YUZpbGUgY3JlYXRlU2hhcmVkRGF0YUZpbGUoU3RyaW5nIGZpbGVJZCwgaW50IGZpbGVJbmRleCkgeworICAgIERhdGFGaWxlLkJ1aWxkZXIgZmlsZSA9IERhdGFGaWxlLm5ld0J1aWxkZXIoKTsKKyAgICBmaWxlLnNldEZpbGVJZChTdHJpbmcuZm9ybWF0KCIlc18lcyIsIGZpbGVJZCwgZmlsZUluZGV4KSk7CisgICAgZmlsZS5zZXRVcmxUb0Rvd25sb2FkKFN0cmluZy5mb3JtYXQoImh0dHBzOi8vJXNfJXMiLCBmaWxlSWQsIGZpbGVJbmRleCkpOworICAgIGZpbGUuc2V0Qnl0ZVNpemUoMTAgKyBmaWxlSW5kZXgpOworICAgIGZpbGUuc2V0Q2hlY2tzdW0oIjEyMyIgKyBmaWxlSW5kZXgpOworICAgIGZpbGUuc2V0Q2hlY2tzdW1UeXBlKERhdGFGaWxlLkNoZWNrc3VtVHlwZS5ERUZBVUxUKTsKKyAgICBmaWxlLnNldEFuZHJvaWRTaGFyaW5nVHlwZShEYXRhRmlsZS5BbmRyb2lkU2hhcmluZ1R5cGUuQU5EUk9JRF9CTE9CX1dIRU5fQVZBSUxBQkxFKTsKKyAgICBmaWxlLnNldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW1UeXBlKERhdGFGaWxlLkFuZHJvaWRTaGFyaW5nQ2hlY2tzdW1UeXBlLlNIQTJfMjU2KTsKKyAgICBmaWxlLnNldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oInNoYTI1Nl8xMjMiICsgZmlsZUluZGV4KTsKKyAgICByZXR1cm4gZmlsZS5idWlsZCgpOworICB9CisKKyAgLyoqIENyZWF0ZXMgYSBkYXRhRmlsZSB3aXRoIHJlbGF0aXZlIHBhdGguICovCisgIHB1YmxpYyBzdGF0aWMgRGF0YUZpbGUgY3JlYXRlUmVsYXRpdmVQYXRoRGF0YUZpbGUoCisgICAgICBTdHJpbmcgZmlsZUlkLCBpbnQgZmlsZUluZGV4LCBTdHJpbmcgcmVsYXRpdmVGaWxlUGF0aCkgeworICAgIHJldHVybiBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldEZpbGVJZChTdHJpbmcuZm9ybWF0KCIlc18lcyIsIGZpbGVJZCwgZmlsZUluZGV4KSkKKyAgICAgICAgLnNldFVybFRvRG93bmxvYWQoU3RyaW5nLmZvcm1hdCgiaHR0cHM6Ly8lc18lcyIsIGZpbGVJZCwgZmlsZUluZGV4KSkKKyAgICAgICAgLnNldEJ5dGVTaXplKDEwICsgZmlsZUluZGV4KQorICAgICAgICAuc2V0Q2hlY2tzdW0oIjEyMyIgKyBmaWxlSW5kZXgpCisgICAgICAgIC5zZXRDaGVja3N1bVR5cGUoRGF0YUZpbGUuQ2hlY2tzdW1UeXBlLkRFRkFVTFQpCisgICAgICAgIC5zZXRSZWxhdGl2ZUZpbGVQYXRoKHJlbGF0aXZlRmlsZVBhdGgpCisgICAgICAgIC5idWlsZCgpOworICB9CisKKyAgcHVibGljIHN0YXRpYyBEYXRhRmlsZSBjcmVhdGVaaXBGb2xkZXJEYXRhRmlsZShTdHJpbmcgZmlsZUlkLCBpbnQgZmlsZUluZGV4KSB7CisgICAgRGF0YUZpbGUuQnVpbGRlciBmaWxlID0gRGF0YUZpbGUubmV3QnVpbGRlcigpOworICAgIGZpbGUuc2V0RmlsZUlkKFN0cmluZy5mb3JtYXQoIiVzXyVzIiwgZmlsZUlkLCBmaWxlSW5kZXgpKTsKKyAgICBmaWxlLnNldFVybFRvRG93bmxvYWQoU3RyaW5nLmZvcm1hdCgiaHR0cHM6Ly8lc18lcyIsIGZpbGVJZCwgZmlsZUluZGV4KSk7CisgICAgZmlsZS5zZXRCeXRlU2l6ZSgxMCArIGZpbGVJbmRleCk7CisgICAgZmlsZS5zZXREb3dubG9hZGVkRmlsZUNoZWNrc3VtKCIxMjMiICsgZmlsZUluZGV4KTsKKyAgICBmaWxlLnNldERvd25sb2FkVHJhbnNmb3JtcygKKyAgICAgICAgVHJhbnNmb3Jtcy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRUcmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgVHJhbnNmb3JtLm5ld0J1aWxkZXIoKS5zZXRaaXAoWmlwVHJhbnNmb3JtLm5ld0J1aWxkZXIoKS5zZXRUYXJnZXQoIioiKS5idWlsZCgpKSkpOworICAgIHJldHVybiBmaWxlLmJ1aWxkKCk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBjcmVhdGVGaWxlR3JvdXBJbnRlcm5hbFdpdGhEZWx0YUZpbGUoU3RyaW5nIGZpbGVHcm91cE5hbWUpIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwuQnVpbGRlciBmaWxlR3JvdXBCdWlsZGVyID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKGZpbGVHcm91cE5hbWUsIDEpLnRvQnVpbGRlcigpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwQnVpbGRlcgorICAgICAgICAgICAgLnNldEZpbGUoMCwgZmlsZUdyb3VwQnVpbGRlci5nZXRGaWxlKDApLnRvQnVpbGRlcigpLmFkZERlbHRhRmlsZSgwLCBjcmVhdGVEZWx0YUZpbGUoKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICByZXR1cm4gZGF0YUZpbGVHcm91cDsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgRGVsdGFGaWxlIGNyZWF0ZURlbHRhRmlsZSgpIHsKKyAgICByZXR1cm4gRGVsdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaHR0cDovL2FiYyIpCisgICAgICAgIC5zZXRCeXRlU2l6ZSgxMCkKKyAgICAgICAgLnNldENoZWNrc3VtKCJBQkMiKQorICAgICAgICAuc2V0RGlmZkRlY29kZXIoRGlmZkRlY29kZXIuVkNfRElGRikKKyAgICAgICAgLnNldEJhc2VGaWxlKGNyZWF0ZURlbHRhQmFzZUZpbGUoIm15Y2hlY2tzdW0iKSkKKyAgICAgICAgLmJ1aWxkKCk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIERlbHRhRmlsZSBjcmVhdGVEZWx0YUZpbGUoU3RyaW5nIGZpbGVJZCwgaW50IGZpbGVJbmRleCkgeworICAgIHJldHVybiBEZWx0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKFN0cmluZy5mb3JtYXQoImh0dHBzOi8vJXNfJXMiLCBmaWxlSWQsIGZpbGVJbmRleCkpCisgICAgICAgIC5zZXRCeXRlU2l6ZSgxMCArIGZpbGVJbmRleCkKKyAgICAgICAgLnNldENoZWNrc3VtKCIxMjMiICsgZmlsZUluZGV4KQorICAgICAgICAuc2V0RGlmZkRlY29kZXIoRGlmZkRlY29kZXIuVkNfRElGRikKKyAgICAgICAgLnNldEJhc2VGaWxlKGNyZWF0ZURlbHRhQmFzZUZpbGUoIm15Y2hlY2tzdW0iICsgZmlsZUluZGV4KSkKKyAgICAgICAgLmJ1aWxkKCk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIEJhc2VGaWxlIGNyZWF0ZURlbHRhQmFzZUZpbGUoU3RyaW5nIGNoZWNrc3VtKSB7CisgICAgcmV0dXJuIEJhc2VGaWxlLm5ld0J1aWxkZXIoKS5zZXRDaGVja3N1bShjaGVja3N1bSkuYnVpbGQoKTsKKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgTmV3RmlsZUtleVtdIGNyZWF0ZUZpbGVLZXlzRm9yRGF0YUZpbGVHcm91cEludGVybmFsKERhdGFGaWxlR3JvdXBJbnRlcm5hbCBncm91cCkgeworICAgIE5ld0ZpbGVLZXlbXSBuZXdGaWxlS2V5cyA9IG5ldyBOZXdGaWxlS2V5W2dyb3VwLmdldEZpbGVDb3VudCgpXTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGdyb3VwLmdldEZpbGVDb3VudCgpOyArK2kpIHsKKyAgICAgIG5ld0ZpbGVLZXlzW2ldID0KKyAgICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgICAgZ3JvdXAuZ2V0RmlsZShpKSwgZ3JvdXAuZ2V0QWxsb3dlZFJlYWRlcnNFbnVtKCkpOworICAgIH0KKyAgICByZXR1cm4gbmV3RmlsZUtleXM7CisgIH0KKworICBwdWJsaWMgc3RhdGljIHZvaWQgYXNzZXJ0TWVzc2FnZUVxdWFscyhNZXNzYWdlTGl0ZSBleHBlY3RlZCwgTWVzc2FnZUxpdGUgYWN0dWFsKSB7CisgICAgYXNzZXJ0V2l0aE1lc3NhZ2UoU3RyaW5nLmZvcm1hdCgiRVhQRUNURUQ6ICVzXG4gQUNUVUFMOiAlc1xuIiwgZXhwZWN0ZWQsIGFjdHVhbCkpCisgICAgICAgIC50aGF0KGV4cGVjdGVkLmVxdWFscyhhY3R1YWwpKQorICAgICAgICAuaXNUcnVlKCk7CisgIH0KKworICBwdWJsaWMgc3RhdGljIERhdGFGaWxlIGNyZWF0ZURhdGFGaWxlV2l0aERlbHRhRmlsZSgKKyAgICAgIFN0cmluZyBmaWxlSWQsIGludCBmaWxlSW5kZXgsIGludCBkZWx0YUZpbGVDb3VudCkgeworICAgIERhdGFGaWxlLkJ1aWxkZXIgZmlsZSA9CisgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVJZChTdHJpbmcuZm9ybWF0KCIlc18lcyIsIGZpbGVJZCwgZmlsZUluZGV4KSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKFN0cmluZy5mb3JtYXQoImh0dHBzOi8vJXNfJXMiLCBmaWxlSWQsIGZpbGVJbmRleCkpCisgICAgICAgICAgICAuc2V0Qnl0ZVNpemUoMTAgKyBmaWxlSW5kZXgpCisgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oIjEyMyIgKyBmaWxlSW5kZXgpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVsdGFGaWxlQ291bnQ7IGkrKykgeworICAgICAgZmlsZS5hZGREZWx0YUZpbGUoY3JlYXRlRGVsdGFGaWxlKGZpbGVJZCArICJfZGVsdGFfIiArIGksIGkpKTsKKyAgICB9CisgICAgcmV0dXJuIGZpbGUuYnVpbGQoKTsKKyAgfQorCisgIC8qKiBFeGVjdXRlcyB0aGUgc2hlbGwgY29tbWFuZCB7QGNvZGUgY21kfS4gKi8KKyAgcHVibGljIHN0YXRpYyBTdHJpbmcgcnVuU2hlbGxDbWQoU3RyaW5nIGNtZCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKKyAgICBmaW5hbCBVaURldmljZSB1aURldmljZSA9IFVpRGV2aWNlLmdldEluc3RhbmNlKGdldEluc3RydW1lbnRhdGlvbigpKTsKKyAgICBmaW5hbCBTdHJpbmcgcmVzdWx0ID0gdWlEZXZpY2UuZXhlY3V0ZVNoZWxsQ29tbWFuZChjbWQpLnRyaW0oKTsKKyAgICBMb2cuaShUQUcsICJPdXRwdXQgb2YgJyIgKyBjbWQgKyAiJzogJyIgKyByZXN1bHQgKyAiJyIpOworICAgIHJldHVybiByZXN1bHQ7CisgIH0KKworICAvKiogRm9yIEFQSS1sZXZlbCAxOSssIGl0IG1vdmVzIHRoZSB0aW1lIGZvcndhcmQgYnkge0Bjb2RlIHRpbWVJbk1pbGxpc30gbWlsbGlzZWNvbmRzLiAqLworICBwdWJsaWMgc3RhdGljIHZvaWQgdGltZVRyYXZlbChDb250ZXh0IGNvbnRleHQsIGxvbmcgdGltZUluTWlsbGlzKSB7CisgICAgaWYgKFZFUlNJT04uU0RLX0lOVCA9PSAxOCkgeworICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKAorICAgICAgICAgICJUaW1lIHRyYXZlbCBkb2VzIG5vdCB3b3JrIG9uIEFQSS1sZXZlbCAxOCAtIGIvMzExMzIxNjEuICIKKyAgICAgICAgICAgICAgKyAiWW91IG5lZWQgdG8gZGlzYWJsZSB0aGlzIHRlc3Qgb24gQVBJLWxldmVsIDE4LiBFeGFtcGxlOiBjbC8xMzE0OTg3MjAiKTsKKyAgICB9CisKKyAgICBmaW5hbCBsb25nIHRpbWVzdGFtcEJlZm9yZVRyYXZlbCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOworICAgIGlmICghQmFja2Rvb3JUZXN0VXRpbC5hZHZhbmNlVGltZShjb250ZXh0LCB0aW1lSW5NaWxsaXMpKSB7CisgICAgICAvLyBPbiBzb21lIEFQSSBsZXZlbHMgKD4yMykgdGhlIGNhbGwgcmV0dXJucyBmYWxzZSBldmVuIGlmIHRoZSB0aW1lIGNoYW5nZWQuIEhhdmUgYSBtYW51YWwKKyAgICAgIC8vIHZhbGlkYXRpb24gdGhhdCB0aGUgdGltZSBjaGFuZ2VkIGluc3RlYWQuCisgICAgICBpZiAoVkVSU0lPTi5TREtfSU5UID49IDIzKSB7CisgICAgICAgIGFzc2VydFRoYXQoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpLmlzQXRMZWFzdCh0aW1lc3RhbXBCZWZvcmVUcmF2ZWwgKyB0aW1lSW5NaWxsaXMpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVGltZSBUcmF2ZWwgd2FzIG5vdCBzdWNjZXNzZnVsIik7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEByZXR1cm4gdGhlIHRpbWUgKGluIHNlY29uZHMpIHRoYXQgaXMgbiBkYXlzIGZyb20gdGhlIGN1cnJlbnQgdGltZQorICAgKi8KKyAgcHVibGljIHN0YXRpYyBsb25nIGRheXNGcm9tTm93KGludCBkYXlzKSB7CisgICAgbG9uZyB0aGVuTWlsbGlzID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgKyBEQVlTLnRvTWlsbGlzKGRheXMpOworICAgIHJldHVybiBNSUxMSVNFQ09ORFMudG9TZWNvbmRzKHRoZW5NaWxsaXMpOworICB9CisKKyAgLyoqCisgICAqIFdyaXRlcyB0aGUgU2hhcmVkRmlsZSBtZXRhZGF0YSBmb3IgYWxsIHRoZSBmaWxlcyBzdG9yZWQgaW4gdGhlIHtAY29kZSBmaWxlR3JvdXB9LCBzZXR0aW5nIGZvcgorICAgKiBlYWNoIG9mIHRoZW0gdGhlIHN0YXR1cyBhbmQgd2hldGhlciB0aGV5IGFyZSBjdXJyZW50bHkgYW5kcm9pZC1zaGFyZWQgYmFzZWQgb24gdGhlIGFycmF5CisgICAqIHBvc2l0aW9uLgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwLAorICAgICAgTGlzdDxGaWxlU3RhdHVzPiBzdGF0dXNlcywKKyAgICAgIExpc3Q8Qm9vbGVhbj4gYW5kcm9pZFNoYXJlZCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIGludCBzaXplID0gZmlsZUdyb3VwLmdldEZpbGVDb3VudCgpOworICAgIE5ld0ZpbGVLZXlbXSBrZXlzID0gY3JlYXRlRmlsZUtleXNGb3JEYXRhRmlsZUdyb3VwSW50ZXJuYWwoZmlsZUdyb3VwKTsKKyAgICBhc3NlcnRXaXRoTWVzc2FnZSgiQ3JlYXRlZCBmaWxlIGtleXMgbXVzdCBtYXRjaCB0aGUgZ2l2ZW4gRGF0YUZpbGVHcm91cCdzIGZpbGUgY291bnQiKQorICAgICAgICAudGhhdChrZXlzLmxlbmd0aCkKKyAgICAgICAgLmlzRXF1YWxUbyhzaXplKTsKKyAgICBhc3NlcnRXaXRoTWVzc2FnZSgiR2l2ZW4gRmlsZVN0YXR1cyBsaXN0IG11c3QgbWF0Y2ggdGhlIGdpdmVuIERhdGFGaWxlR3JvdXAncyBmaWxlIGNvdW50IikKKyAgICAgICAgLnRoYXQoc3RhdHVzZXMuc2l6ZSgpKQorICAgICAgICAuaXNFcXVhbFRvKHNpemUpOworICAgIGFzc2VydFdpdGhNZXNzYWdlKCJHaXZlbiBhbmRyb2lkU2hhcmVkIGxpc3QgbXVzdCBtYXRjaCB0aGUgZ2l2ZW4gRGF0YUZpbGVHcm91cCdzIGZpbGUgY291bnQiKQorICAgICAgICAudGhhdChhbmRyb2lkU2hhcmVkLnNpemUoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhzaXplKTsKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpbGVHcm91cC5nZXRGaWxlQ291bnQoKTsgaSsrKSB7CisgICAgICBEYXRhRmlsZSBmaWxlID0gZmlsZUdyb3VwLmdldEZpbGUoaSk7CisgICAgICBTaGFyZWRGaWxlLkJ1aWxkZXIgc2hhcmVkRmlsZUJ1aWxkZXIgPQorICAgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpLnNldEZpbGVOYW1lKGZpbGUuZ2V0RmlsZUlkKCkpLnNldEZpbGVTdGF0dXMoc3RhdHVzZXMuZ2V0KGkpKTsKKyAgICAgIGlmIChhbmRyb2lkU2hhcmVkLmdldChpKSkgeworICAgICAgICBzaGFyZWRGaWxlQnVpbGRlci5zZXRBbmRyb2lkU2hhcmVkKHRydWUpLnNldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oInNoYTI1Nl8xMjMiICsgaSk7CisgICAgICB9CisgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLndyaXRlKGtleXNbaV0sIHNoYXJlZEZpbGVCdWlsZGVyLmJ1aWxkKCkpLmdldCgpOworICAgIH0KKyAgfQorCisgIC8qKgorICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIHtAbGluayBNZGRUZXN0VXRpbCN3cml0ZVNoYXJlZEZpbGVzKFNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAqIERhdGFGaWxlR3JvdXBJbnRlcm5hbCwgTGlzdDxGaWxlU3RhdHVzPiwgTGlzdDxCb29sZWFuPil9IHdoZW4gYW5kcm9pZCBzaGFyZWQgc3RhdHVzIGlzCisgICAqIHVubmVjZXNzYXJ5LgorICAgKi8KKyAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlU2hhcmVkRmlsZXMoCisgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZmlsZUdyb3VwLAorICAgICAgTGlzdDxGaWxlU3RhdHVzPiBzdGF0dXNlcykKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIGludCBzaXplID0gZmlsZUdyb3VwLmdldEZpbGVDb3VudCgpOworICAgIExpc3Q8Qm9vbGVhbj4gYW5kcm9pZFNoYXJlZCA9IENvbGxlY3Rpb25zLm5Db3BpZXMoc2l6ZSwgZmFsc2UpOworICAgIHdyaXRlU2hhcmVkRmlsZXMoc2hhcmVkRmlsZXNNZXRhZGF0YSwgZmlsZUdyb3VwLCBzdGF0dXNlcywgYW5kcm9pZFNoYXJlZCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9NaWdyYXRpb25zVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL01pZ3JhdGlvbnNUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDcxODc5YgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9NaWdyYXRpb25zVGVzdC5qYXZhCkBAIC0wLDAgKzEsOTMgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5jb250ZW50LlNoYXJlZFByZWZlcmVuY2VzOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5TaWxlbnRGZWVkYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NaWdyYXRpb25zLkZpbGVLZXlWZXJzaW9uOworaW1wb3J0IG9yZy5qdW5pdC5BZnRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgY2xhc3MgTWlncmF0aW9uc1Rlc3QgeworCisgIHByaXZhdGUgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIFNpbGVudEZlZWRiYWNrIG1vY2tTaWxlbnRGZWVkYmFjazsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisgICAgbW9ja1NpbGVudEZlZWRiYWNrID0KKyAgICAgICAgbmV3IFNpbGVudEZlZWRiYWNrKCkgeworICAgICAgICAgIEBPdmVycmlkZQorICAgICAgICAgIHB1YmxpYyB2b2lkIHNlbmQoVGhyb3dhYmxlIHRocm93YWJsZSwgU3RyaW5nIG1lc3NhZ2VGb3JtYXQsIE9iamVjdC4uLiBhcmdzKSB7fQorICAgICAgICB9OworICB9CisKKyAgQEFmdGVyCisgIHB1YmxpYyB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgTWlncmF0aW9ucy5jbGVhcihjb250ZXh0KTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REZWZhdWx0VmVyc2lvbigpIHsKKyAgICAvLyBNYWtlIHN1cmUgdGhlIGRlZmF1bHQgdmVyc2lvbiBpcyBGaWxlS2V5VmVyc2lvbi5OZXdGaWxlS2V5CisgICAgYXNzZXJ0VGhhdChNaWdyYXRpb25zLmdldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIG1vY2tTaWxlbnRGZWVkYmFjaykpCisgICAgICAgIC5pc0VxdWFsVG8oRmlsZUtleVZlcnNpb24uTkVXX0ZJTEVfS0VZKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RTZXRBbmRHZXRWZXJzaW9uKCkgeworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uQUREX0RPV05MT0FEX1RSQU5TRk9STSk7CisgICAgYXNzZXJ0VGhhdChNaWdyYXRpb25zLmdldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIG1vY2tTaWxlbnRGZWVkYmFjaykpCisgICAgICAgIC5pc0VxdWFsVG8oRmlsZUtleVZlcnNpb24uQUREX0RPV05MT0FEX1RSQU5TRk9STSk7CisKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLk5FV19GSUxFX0tFWSk7CisgICAgYXNzZXJ0VGhhdChNaWdyYXRpb25zLmdldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIG1vY2tTaWxlbnRGZWVkYmFjaykpCisgICAgICAgIC5pc0VxdWFsVG8oRmlsZUtleVZlcnNpb24uTkVXX0ZJTEVfS0VZKTsKKworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworICAgIGFzc2VydFRoYXQoTWlncmF0aW9ucy5nZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBtb2NrU2lsZW50RmVlZGJhY2spKQorICAgICAgICAuaXNFcXVhbFRvKEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RNZGRGaWxlS2V5RW51bSgpIHsKKyAgICBhc3NlcnRUaGF0KEZpbGVLZXlWZXJzaW9uLmdldFZlcnNpb24oMCkpLmlzRXF1YWxUbyhGaWxlS2V5VmVyc2lvbi5ORVdfRklMRV9LRVkpOworICAgIGFzc2VydFRoYXQoRmlsZUtleVZlcnNpb24uZ2V0VmVyc2lvbigxKSkuaXNFcXVhbFRvKEZpbGVLZXlWZXJzaW9uLkFERF9ET1dOTE9BRF9UUkFOU0ZPUk0pOworICAgIGFzc2VydFRoYXQoRmlsZUtleVZlcnNpb24uZ2V0VmVyc2lvbigyKSkuaXNFcXVhbFRvKEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBhc3NlcnRUaHJvd3MoUnVudGltZUV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gRmlsZUtleVZlcnNpb24uZ2V0VmVyc2lvbigzKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0Q29ycnVwdGVkVmVyc2lvbigpIHsKKyAgICAvLyBTZXQgaW52YWxpZCB2YWx1ZSB0byBmaWxlIGtleSBtaWdyYXRpb24gbWV0YWRhdGEuCisgICAgU2hhcmVkUHJlZmVyZW5jZXMgbWlncmF0aW9uUHJlZnMgPQorICAgICAgICBjb250ZXh0LmdldFNoYXJlZFByZWZlcmVuY2VzKCJnbXNfaWNpbmdfbWRkX21pZ3JhdGlvbnMiLCBDb250ZXh0Lk1PREVfUFJJVkFURSk7CisgICAgbWlncmF0aW9uUHJlZnMuZWRpdCgpLnB1dEludCgibWRkX2ZpbGVfa2V5X3ZlcnNpb24iLCAxMDApLmNvbW1pdCgpOworICAgIC8vIHdoZW4obW9ja1NpbGVudEZlZWRiYWNrLnNlbmQoYW55U3RyaW5nKCksIGFuKSkKKyAgICBhc3NlcnRUaGF0KE1pZ3JhdGlvbnMuZ2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgbW9ja1NpbGVudEZlZWRiYWNrKSkKKyAgICAgICAgLmlzRXF1YWxUbyhGaWxlS2V5VmVyc2lvbi5VU0VfQ0hFQ0tTVU1fT05MWSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9Nb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL01vYmlsZURhdGFEb3dubG9hZE1hbmFnZXJUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDE2YTYzYQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9Nb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTA3MSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWw7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZTsKK2ltcG9ydCBzdGF0aWMgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQuREFZUzsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUaHJvd3M7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuYW55OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueUludDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnlMaXN0OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueUxvbmc7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuZXE7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuaXNBOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmlzTnVsbDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by5kb1Rocm93OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLm5ldmVyOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnRpbWVzOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnZlcmlmeTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnlOb0ludGVyYWN0aW9uczsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnM7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ud2hlbjsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5TaGFyZWRQcmVmZXJlbmNlczsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkRXhjZXB0aW9uLkRvd25sb2FkUmVzdWx0Q29kZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GaWxlU291cmNlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlNpbGVudEZlZWRiYWNrOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVtcG9yYXJ5VXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLkZpbGVHcm91cE1hbmFnZXIuR3JvdXBEb3dubG9hZFN0YXR1czsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NaWdyYXRpb25zLkZpbGVLZXlWZXJzaW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmV4cGVyaW1lbnRhdGlvbi5Eb3dubG9hZFN0YWdlTWFuYWdlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5leHBlcmltZW50YXRpb24uTm9PcERvd25sb2FkU3RhZ2VNYW5hZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuRXZlbnRMb2dnZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5GaWxlR3JvdXBTdGF0c0xvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLkxvZ2dpbmdTdGF0ZVN0b3JlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTmV0d29ya0xvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLk5vT3BMb2dnaW5nU3RhdGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5TdG9yYWdlTG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuRmlsZUdyb3VwVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLlNoYXJlZFByZWZlcmVuY2VzVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLkZha2VUaW1lU291cmNlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRlc3RpbmcuVGVzdEZsYWdzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTWFwOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmxhYnMuY29uY3VycmVudC5MYWJzRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuQXN5bmNGdW5jdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5Db21wcmVzc1RyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5aaXBUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlLkNoZWNrc3VtVHlwZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VOZXR3b3JrUG9saWN5OworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRG93bmxvYWRDb25kaXRpb25zLkRldmljZVN0b3JhZ2VQb2xpY3k7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IG9yZy5qdW5pdC5BZnRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Bcmd1bWVudENhcHRvcjsKK2ltcG9ydCBvcmcubW9ja2l0by5DYXB0b3I7CitpbXBvcnQgb3JnLm1vY2tpdG8uTW9jazsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvSlVuaXQ7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b1J1bGU7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuYW5ub3RhdGlvbi5Mb29wZXJNb2RlOworCisvLyBUaGUgTG9vcGVyTW9kZSBNb2RlLlBBVVNFRCBmaXhlcyBidWdneSBiZWhhdmlvciBpbiB0aGUgbGVnYWN5IGxvb3BlciBpbXBsZW1lbnRhdGlvbiB0aGF0IGNhbiBsZWFkCisvLyB0byBkZWFkbG9jayBpbiBzb21lIGNhc2VzLiBTZWUgZG9jdW1lbnRhdGlvbiBhdDoKKy8vIGh0dHA6Ly9yb2JvbGVjdHJpYy5vcmcvamF2YWRvYy80LjMvb3JnL3JvYm9sZWN0cmljL2Fubm90YXRpb24vTG9vcGVyTW9kZS5Nb2RlLmh0bWwgZm9yIG1vcmUKKy8vIGluZm9ybWF0aW9uLgorQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorQExvb3Blck1vZGUoTG9vcGVyTW9kZS5Nb2RlLlBBVVNFRCkKK3B1YmxpYyBjbGFzcyBNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRFU1RfR1JPVVAgPSAidGVzdC1ncm91cCI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEdyb3VwS2V5IFRFU1RfS0VZID0KKyAgICAgIEZpbGVHcm91cFV0aWwuY3JlYXRlR3JvdXBLZXkoVEVTVF9HUk9VUCwgImNvbS5nb29nbGUuYW5kcm9pZC5nbXMiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRXhlY3V0b3IgQ09OVFJPTF9FWEVDVVRPUiA9IEV4ZWN1dG9ycy5uZXdDYWNoZWRUaHJlYWRQb29sKCk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfREFZU19TSU5DRV9MQVNUX0xPRyA9IDE7CisKKyAgLy8gTm90ZTogV2UgY2FuJ3QgbWFrZSB0aG9zZSBhbmRyb2lkIHVyaXMgc3RhdGljIHZhcmlhYmxlIHNpbmNlIHRoZSBVcmkucGFyc2Ugd2lsbCBmYWlsCisgIC8vIHdpdGggaW5pdGlhbGl6YXRpb24uCisgIHByaXZhdGUgZmluYWwgVXJpIGZpbGVVcmkxID0gVXJpLnBhcnNlKE1kZFRlc3RVdGlsLkZJTEVfVVJJICsgIjEiKTsKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgZmlsZVVyaTIgPSBVcmkucGFyc2UoTWRkVGVzdFV0aWwuRklMRV9VUkkgKyAiMiIpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBIT1NUX0FQUF9MT0dfU09VUkNFID0gIkhPU1RfQVBQX0xPR19TT1VSQ0UiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSE9TVF9BUFBfUFJJTUVTX0xPR19TT1VSQ0UgPSAiSE9TVF9BUFBfUFJJTUVTX0xPR19TT1VSQ0UiOworCisgIHByaXZhdGUgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIgbWRkTWFuYWdlcjsKKyAgcHJpdmF0ZSBmaW5hbCBUZXN0RmxhZ3MgZmxhZ3MgPSBuZXcgVGVzdEZsYWdzKCk7CisgIEBSdWxlIHB1YmxpYyBmaW5hbCBUZW1wb3JhcnlVcmkgdG1wVXJpID0gbmV3IFRlbXBvcmFyeVVyaSgpOworICBAUnVsZSBwdWJsaWMgZmluYWwgTW9ja2l0b1J1bGUgbW9ja3MgPSBNb2NraXRvSlVuaXQucnVsZSgpOworCisgIEBNb2NrIEV2ZW50TG9nZ2VyIG1vY2tMb2dnZXI7CisgIEBNb2NrIFNoYXJlZEZpbGVNYW5hZ2VyIG1vY2tTaGFyZWRGaWxlTWFuYWdlcjsKKyAgQE1vY2sgU2hhcmVkRmlsZXNNZXRhZGF0YSBtb2NrU2hhcmVkRmlsZXNNZXRhZGF0YTsKKyAgQE1vY2sgRmlsZUdyb3VwTWFuYWdlciBtb2NrRmlsZUdyb3VwTWFuYWdlcjsKKyAgQE1vY2sgRmlsZUdyb3Vwc01ldGFkYXRhIG1vY2tGaWxlR3JvdXBzTWV0YWRhdGE7CisgIEBNb2NrIEV4cGlyYXRpb25IYW5kbGVyIG1vY2tFeHBpcmF0aW9uSGFuZGxlcjsKKyAgQE1vY2sgU2lsZW50RmVlZGJhY2sgbW9ja1NpbGVudEZlZWRiYWNrOworICBATW9jayBTdG9yYWdlTG9nZ2VyIG1vY2tTdG9yYWdlTG9nZ2VyOworICBATW9jayBGaWxlR3JvdXBTdGF0c0xvZ2dlciBtb2NrRmlsZUdyb3VwU3RhdHNMb2dnZXI7CisgIEBNb2NrIE5ldHdvcmtMb2dnZXIgbW9ja05ldHdvcmtMb2dnZXI7CisKKyAgcHJpdmF0ZSBMb2dnaW5nU3RhdGVTdG9yZSBsb2dnaW5nU3RhdGVTdG9yZTsKKyAgcHJpdmF0ZSBEb3dubG9hZFN0YWdlTWFuYWdlciBkb3dubG9hZFN0YWdlTWFuYWdlcjsKKyAgcHJpdmF0ZSBGYWtlVGltZVNvdXJjZSB0ZXN0Q2xvY2s7CisKKyAgQENhcHRvciBBcmd1bWVudENhcHRvcjxMaXN0PEdyb3VwS2V5Pj4gZ3JvdXBLZXlMaXN0Q2FwdG9yOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKyAgICB0aGlzLnRlc3RDbG9jayA9IG5ldyBGYWtlVGltZVNvdXJjZSgpOworICAgIHRlc3RDbG9jay5hZHZhbmNlKDEsIERBWVMpOworCisgICAgbG9nZ2luZ1N0YXRlU3RvcmUgPSBuZXcgTm9PcExvZ2dpbmdTdGF0ZSgpOworCisgICAgbG9nZ2luZ1N0YXRlU3RvcmUuZ2V0QW5kUmVzZXREYXlzU2luY2VMYXN0TWFpbnRlbmFuY2UoKS5nZXQoKTsKKyAgICB0ZXN0Q2xvY2suYWR2YW5jZSgxLCBEQVlTKTsgLy8gVGhlIG5leHQgY2FsbCBpbnRvIGxvZ2dpbmcgc3RhdGUgc3RvcmUgd2lsbCByZXR1cm4gMQorCisgICAgZG93bmxvYWRTdGFnZU1hbmFnZXIgPSBuZXcgTm9PcERvd25sb2FkU3RhZ2VNYW5hZ2VyKCk7CisKKyAgICBtZGRNYW5hZ2VyID0KKyAgICAgICAgbmV3IE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgbW9ja0xvZ2dlciwKKyAgICAgICAgICAgIG1vY2tTaGFyZWRGaWxlTWFuYWdlciwKKyAgICAgICAgICAgIG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICAgICAgbW9ja0ZpbGVHcm91cE1hbmFnZXIsCisgICAgICAgICAgICBtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLAorICAgICAgICAgICAgbW9ja0V4cGlyYXRpb25IYW5kbGVyLAorICAgICAgICAgICAgbW9ja1NpbGVudEZlZWRiYWNrLAorICAgICAgICAgICAgbW9ja1N0b3JhZ2VMb2dnZXIsCisgICAgICAgICAgICBtb2NrRmlsZUdyb3VwU3RhdHNMb2dnZXIsCisgICAgICAgICAgICBtb2NrTmV0d29ya0xvZ2dlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgQ09OVFJPTF9FWEVDVVRPUiwKKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgbG9nZ2luZ1N0YXRlU3RvcmUsCisgICAgICAgICAgICBkb3dubG9hZFN0YWdlTWFuYWdlcik7CisKKyAgICAvLyBFbmFibGUgbWlncmF0aW9ucyBzbyB0aGF0IGluaXQgZG9lc24ndCBydW4gYWxsIG1pZ3JhdGlvbnMgYmVmb3JlIGVhY2ggdGVzdC4KKyAgICBzZXRNaWdyYXRpb25TdGF0ZShNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLk1ERF9NSUdSQVRFRF9UT19PRkZST0FELCB0cnVlKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5pbml0KCkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmNsZWFyKCkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVNYW5hZ2VyLmNhbmNlbERvd25sb2FkKGFueSgpKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuY2FuY2VsRG93bmxvYWRBbmRDbGVhcigpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlc01ldGFkYXRhLmluaXQoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLmluaXQoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3Vwc01ldGFkYXRhLmNsZWFyKCkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworICAgIHdoZW4obW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEuY2xlYXIoKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisgIH0KKworICBAQWZ0ZXIKKyAgcHVibGljIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBtZGRNYW5hZ2VyLmNsZWFyKCkuZ2V0KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbml0X29mZnJvYWREb3dubG9hZGVyTWlncmF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc2V0TWlncmF0aW9uU3RhdGUoTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlci5NRERfTUlHUkFURURfVE9fT0ZGUk9BRCwgZmFsc2UpOworCisgICAgbWRkTWFuYWdlci5pbml0KCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5jbGVhcigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW5pdF9vZmZyb2FkRG93bmxvYWRlck1pZ3JhdGlvbl9vbmx5T25jZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHNldE1pZ3JhdGlvblN0YXRlKE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuTUREX01JR1JBVEVEX1RPX09GRlJPQUQsIGZhbHNlKTsKKworICAgIG1kZE1hbmFnZXIuaW5pdCgpLmdldCgpOworICAgIG1kZE1hbmFnZXIuaW5pdCgpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlciwgdGltZXMoMSkpLmNsZWFyKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBpbml0RG9lc05vdENsZWFyc0lmSW50ZXJuYWxJbml0U3VjY2VlZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKG1vY2tTaGFyZWRGaWxlTWFuYWdlci5pbml0KCkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSkpOworCisgICAgbWRkTWFuYWdlci5pbml0KCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyLCB0aW1lcygwKSkuY2xlYXIoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGluaXRDbGVhcnNJZkludGVybmFsSW5pdEZhaWxzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgd2hlbihtb2NrU2hhcmVkRmlsZU1hbmFnZXIuaW5pdCgpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZhbHNlKSk7CisKKyAgICBtZGRNYW5hZ2VyLmluaXQoKS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLmNsZWFyKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRoaXMgdGVzdHMgdGhhdCB0aGUgZGVmYXVsdCB2YWx1ZSBvZiB7YWxsb3dlZF9yZWFkZXJzLCBhbGxvd2VkX3JlYWRlcnNfZW51bX0gaXMgdG8gYWxsb3cKKyAgICAvLyBhY2Nlc3MgdG8gYWxsIDFwIGdvb2dsZSBhcHBzLgorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLnZlcmlmeVBlbmRpbmdHcm91cERvd25sb2FkZWQoZXEoVEVTVF9LRVkpLCBlcShkYXRhRmlsZUdyb3VwKSwgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShHcm91cERvd25sb2FkU3RhdHVzLlBFTkRJTkcpKTsKKworICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyKS5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cE1hbmFnZXIpCisgICAgICAgIC52ZXJpZnlQZW5kaW5nR3JvdXBEb3dubG9hZGVkKGVxKFRFU1RfS0VZKSwgZXEoZGF0YUZpbGVHcm91cCksIGFueSgpKTsKKyAgICB2ZXJpZnlOb0ludGVyYWN0aW9ucyhtb2NrTG9nZ2VyKTsKKworICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9jb21wcmVzc2VkRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGZpbGVHcm91cEJ1aWxkZXIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXBCdWlsZGVyCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bSgiZG93bmxvYWRjaGVja3N1bSIpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFRyYW5zZm9ybXMoCisgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRUcmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRDb21wcmVzcyhDb21wcmVzc1RyYW5zZm9ybS5nZXREZWZhdWx0SW5zdGFuY2UoKSkpKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLnZlcmlmeVBlbmRpbmdHcm91cERvd25sb2FkZWQoZXEoVEVTVF9LRVkpLCBlcShkYXRhRmlsZUdyb3VwKSwgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShHcm91cERvd25sb2FkU3RhdHVzLlBFTkRJTkcpKTsKKworICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyKS5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cE1hbmFnZXIpCisgICAgICAgIC52ZXJpZnlQZW5kaW5nR3JvdXBEb3dubG9hZGVkKGVxKFRFU1RfS0VZKSwgZXEoZGF0YUZpbGVHcm91cCksIGFueSgpKTsKKyAgICB2ZXJpZnlOb0ludGVyYWN0aW9ucyhtb2NrTG9nZ2VyKTsKKworICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9kZWx0YUZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZUZpbGVHcm91cEludGVybmFsV2l0aERlbHRhRmlsZShURVNUX0dST1VQKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3VwTWFuYWdlci52ZXJpZnlQZW5kaW5nR3JvdXBEb3dubG9hZGVkKGVxKFRFU1RfS0VZKSwgZXEoZGF0YUZpbGVHcm91cCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoR3JvdXBEb3dubG9hZFN0YXR1cy5QRU5ESU5HKSk7CisKKyAgICBhc3NlcnRUaGF0KG1kZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3VwTWFuYWdlcikuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyKQorICAgICAgICAudmVyaWZ5UGVuZGluZ0dyb3VwRG93bmxvYWRlZChlcShURVNUX0tFWSksIGVxKGRhdGFGaWxlR3JvdXApLCBhbnkoKSk7CisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0xvZ2dlcik7CisKKyAgICBhc3NlcnRUaGF0KG1kZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfZG93bmxvYWRJbW1lZGlhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUaGlzIHRlc3RzIHRoYXQgdGhlIGRlZmF1bHQgdmFsdWUgb2Yge2FsbG93ZWRfcmVhZGVycywgYWxsb3dlZF9yZWFkZXJzX2VudW19IGlzIHRvIGFsbG93CisgICAgLy8gYWNjZXNzIHRvIGFsbCAxcCBnb29nbGUgYXBwcy4KKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFZhcmlhbnRJZCgidGVzdFZhcmlhbnQiKQorICAgICAgICAgICAgLnNldEJ1aWxkSWQoMTApCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3VwTWFuYWdlci52ZXJpZnlQZW5kaW5nR3JvdXBEb3dubG9hZGVkKGVxKFRFU1RfS0VZKSwgZXEoZGF0YUZpbGVHcm91cCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoR3JvdXBEb3dubG9hZFN0YXR1cy5ET1dOTE9BREVEKSk7CisKKyAgICBhc3NlcnRUaGF0KG1kZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3VwTWFuYWdlcikuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyKQorICAgICAgICAudmVyaWZ5UGVuZGluZ0dyb3VwRG93bmxvYWRlZChlcShURVNUX0tFWSksIGVxKGRhdGFGaWxlR3JvdXApLCBhbnkoKSk7CisgICAgdmVyaWZ5KG1vY2tMb2dnZXIpCisgICAgICAgIC5sb2dFdmVudFNhbXBsZWQoCisgICAgICAgICAgICAwLAorICAgICAgICAgICAgVEVTVF9HUk9VUCwKKyAgICAgICAgICAgIC8qIGZpbGVHcm91cFZlcnNpb25OdW1iZXI9ICovIDAsCisgICAgICAgICAgICAvKiBidWlsZElkPSAqLyBkYXRhRmlsZUdyb3VwLmdldEJ1aWxkSWQoKSwKKyAgICAgICAgICAgIC8qIHZhcmlhbnRJZD0gKi8gZGF0YUZpbGVHcm91cC5nZXRWYXJpYW50SWQoKSk7CisKKyAgICBhc3NlcnRUaGF0KG1kZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfdGhyb3dzSU9FeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblRocm93KG5ldyBJT0V4Y2VwdGlvbigpKTsKKworICAgIC8vIGFzc2VydFRoYXQobWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNGYWxzZSgpOworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleGNlcHRpb24gPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPiBtZGRNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApLmdldCgpKTsKKyAgICBhc3NlcnRUaGF0KGV4Y2VwdGlvbikuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKElPRXhjZXB0aW9uLmNsYXNzKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cE1hbmFnZXIpLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApOworICAgIHZlcmlmeShtb2NrU2lsZW50RmVlZGJhY2spLnNlbmQoaXNBKElPRXhjZXB0aW9uLmNsYXNzKSwgaXNBKFN0cmluZy5jbGFzcykpOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tMb2dnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfdGhyb3dzVW5pbnN0YWxsZWRBcHBFeGNlcHRpb24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblRocm93KG5ldyBVbmluc3RhbGxlZEFwcEV4Y2VwdGlvbigpKTsKKworICAgIC8vIGFzc2VydFRoYXQobWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNGYWxzZSgpOworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleGNlcHRpb24gPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPiBtZGRNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApLmdldCgpKTsKKyAgICBhc3NlcnRUaGF0KGV4Y2VwdGlvbikuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKFVuaW5zdGFsbGVkQXBwRXhjZXB0aW9uLmNsYXNzKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cE1hbmFnZXIpLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tMb2dnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfdGhyb3dzRXhwaXJlZEZpbGVHcm91cEV4Y2VwdGlvbigpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkpCisgICAgICAgIC50aGVuVGhyb3cobmV3IEV4cGlyZWRGaWxlR3JvdXBFeGNlcHRpb24oKSk7CisKKyAgICAvLyBhc3NlcnRUaGF0KG1kZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzRmFsc2UoKTsKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXhjZXB0aW9uID0KKyAgICAgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgKCkgLT4gbWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSk7CisgICAgYXNzZXJ0VGhhdChleGNlcHRpb24pLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihFeHBpcmVkRmlsZUdyb3VwRXhjZXB0aW9uLmNsYXNzKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cE1hbmFnZXIpLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tMb2dnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfbXVsdGlwbGVDYWxsc1NhbWVHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpLCBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmYWxzZSkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIudmVyaWZ5UGVuZGluZ0dyb3VwRG93bmxvYWRlZCgKKyAgICAgICAgICAgIGVxKFRFU1RfS0VZKSwgYW55KERhdGFGaWxlR3JvdXBJbnRlcm5hbC5jbGFzcyksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoR3JvdXBEb3dubG9hZFN0YXR1cy5QRU5ESU5HKSk7CisKKyAgICBhc3NlcnRUaGF0KG1kZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyLCB0aW1lcygyKSkuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCk7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyLCB0aW1lcygxKSkKKyAgICAgICAgLnZlcmlmeVBlbmRpbmdHcm91cERvd25sb2FkZWQoZXEoVEVTVF9LRVkpLCBlcShkYXRhRmlsZUdyb3VwKSwgYW55KCkpOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tFeHBpcmF0aW9uSGFuZGxlcik7CisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0xvZ2dlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9pc1ZhbGlkR3JvdXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZSgiIikKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoInRlc3RWYXJpYW50IikKKyAgICAgICAgICAgIC5zZXRCdWlsZElkKDEwKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChtZGRNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc0ZhbHNlKCk7CisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0ZpbGVHcm91cE1hbmFnZXIpOworCisgICAgdmVyaWZ5KG1vY2tMb2dnZXIpCisgICAgICAgIC5sb2dFdmVudFNhbXBsZWQoCisgICAgICAgICAgICAwLAorICAgICAgICAgICAgIiIsCisgICAgICAgICAgICAvKiBmaWxlR3JvdXBWZXJzaW9uTnVtYmVyPSAqLyAwLAorICAgICAgICAgICAgLyogYnVpbGRJZD0gKi8gZGF0YUZpbGVHcm91cC5nZXRCdWlsZElkKCksCisgICAgICAgICAgICAvKiB2YXJpYW50SWQ9ICovIGRhdGFGaWxlR3JvdXAuZ2V0VmFyaWFudElkKCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEFkZEdyb3VwRm9yRG93bmxvYWRfbm9DaGVja3N1bSgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5CdWlsZGVyIGZpbGVHcm91cEJ1aWxkZXIgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSkudG9CdWlsZGVyKCk7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXAgPQorICAgICAgICBmaWxlR3JvdXBCdWlsZGVyCisgICAgICAgICAgICAuc2V0RmlsZSgKKyAgICAgICAgICAgICAgICAwLAorICAgICAgICAgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW1UeXBlKENoZWNrc3VtVHlwZS5OT05FKQorICAgICAgICAgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oIiIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBBcmd1bWVudENhcHRvcjxEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRhdGFGaWxlR3JvdXBDYXB0b3IgPQorICAgICAgICBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhEYXRhRmlsZUdyb3VwSW50ZXJuYWwuY2xhc3MpOworCisgICAgd2hlbihtb2NrRmlsZUdyb3VwTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKGVxKFRFU1RfS0VZKSwgZGF0YUZpbGVHcm91cENhcHRvci5jYXB0dXJlKCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3VwTWFuYWdlci52ZXJpZnlQZW5kaW5nR3JvdXBEb3dubG9hZGVkKAorICAgICAgICAgICAgZXEoVEVTVF9LRVkpLCBhbnkoRGF0YUZpbGVHcm91cEludGVybmFsLmNsYXNzKSwgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShHcm91cERvd25sb2FkU3RhdHVzLlBFTkRJTkcpKTsKKworICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0xvZ2dlcik7CisKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgY2FwdHVyZWREYXRhRmlsZUdyb3VwID0gZGF0YUZpbGVHcm91cENhcHRvci5nZXRWYWx1ZSgpOworCisgICAgYXNzZXJ0VGhhdChjYXB0dXJlZERhdGFGaWxlR3JvdXAuZ2V0RmlsZUNvdW50KCkpLmlzRXF1YWxUbygxKTsKKyAgICBEYXRhRmlsZSBkYXRhRmlsZSA9IGNhcHR1cmVkRGF0YUZpbGVHcm91cC5nZXRGaWxlKDApOworICAgIC8vIENoZWNrc3VtIG9mIHRoZSBVcmwuCisgICAgYXNzZXJ0VGhhdChkYXRhRmlsZS5nZXRDaGVja3N1bSgpKS5pc0VxdWFsVG8oIjBkNzk4NDlhODM5ZDgzZmJjNTNlM2JmZTc5NGVjMzhhMzA1YjcyMjAiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RBZGRHcm91cEZvckRvd25sb2FkX25vQ2hlY2tzdW1XaXRoWmlwVHJhbnNmb3JtKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsLkJ1aWxkZXIgZmlsZUdyb3VwQnVpbGRlciA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGZpbGVHcm91cEJ1aWxkZXIKKyAgICAgICAgICAgIC5zZXRGaWxlKAorICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgZmlsZUdyb3VwQnVpbGRlci5nZXRGaWxlKDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bVR5cGUoQ2hlY2tzdW1UeXBlLk5PTkUpCisgICAgICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bSgiIikKKyAgICAgICAgICAgICAgICAgICAgLnNldERvd25sb2FkZWRGaWxlQ2hlY2tzdW0oIiIpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFRyYW5zZm9ybXMoCisgICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRUcmFuc2Zvcm0oCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRaaXAoWmlwVHJhbnNmb3JtLm5ld0J1aWxkZXIoKS5zZXRUYXJnZXQoIioiKSkpKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgQXJndW1lbnRDYXB0b3I8RGF0YUZpbGVHcm91cEludGVybmFsPiBkYXRhRmlsZUdyb3VwQ2FwdG9yID0KKyAgICAgICAgQXJndW1lbnRDYXB0b3IuZm9yQ2xhc3MoRGF0YUZpbGVHcm91cEludGVybmFsLmNsYXNzKTsKKworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChlcShURVNUX0tFWSksIGRhdGFGaWxlR3JvdXBDYXB0b3IuY2FwdHVyZSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIudmVyaWZ5UGVuZGluZ0dyb3VwRG93bmxvYWRlZCgKKyAgICAgICAgICAgIGVxKFRFU1RfS0VZKSwgYW55KERhdGFGaWxlR3JvdXBJbnRlcm5hbC5jbGFzcyksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoR3JvdXBEb3dubG9hZFN0YXR1cy5QRU5ESU5HKSk7CisKKyAgICBhc3NlcnRUaGF0KG1kZE1hbmFnZXIuYWRkR3JvdXBGb3JEb3dubG9hZChURVNUX0tFWSwgZGF0YUZpbGVHcm91cCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tMb2dnZXIpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGNhcHR1cmVkRGF0YUZpbGVHcm91cCA9IGRhdGFGaWxlR3JvdXBDYXB0b3IuZ2V0VmFsdWUoKTsKKworICAgIGFzc2VydFRoYXQoY2FwdHVyZWREYXRhRmlsZUdyb3VwLmdldEZpbGVDb3VudCgpKS5pc0VxdWFsVG8oMSk7CisgICAgRGF0YUZpbGUgZGF0YUZpbGUgPSBjYXB0dXJlZERhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKTsKKyAgICAvLyBDaGVja3N1bSBvZiB1cmwgaXMgcHJvcGFnYXRlZCB0byBkb3dubG9hZGVkIGZpbGUgY2hlY2tzdW0gaWYgZGF0YSBmaWxlIGhhcyB6aXAgdHJhbnNmb3JtLgorICAgIGFzc2VydFRoYXQoZGF0YUZpbGUuZ2V0Q2hlY2tzdW0oKSkuaXNFbXB0eSgpOworICAgIGFzc2VydFRoYXQoZGF0YUZpbGUuZ2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bSgpKQorICAgICAgICAuaXNFcXVhbFRvKCIwZDc5ODQ5YTgzOWQ4M2ZiYzUzZTNiZmU3OTRlYzM4YTMwNWI3MjIwIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9ub0NoZWNrc3VtQW5kTm90U2V0Q2hlY2tzdW1UeXBlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsLkJ1aWxkZXIgZmlsZUdyb3VwQnVpbGRlciA9CisgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXBJbnRlcm5hbChURVNUX0dST1VQLCAxKS50b0J1aWxkZXIoKTsKKyAgICAvLyBOb3Qgc2V0dGluZyBDaGVja3N1bVR5cGUuTk9ORQorICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0KKyAgICAgICAgZmlsZUdyb3VwQnVpbGRlcgorICAgICAgICAgICAgLnNldEZpbGUoMCwgZmlsZUdyb3VwQnVpbGRlci5nZXRGaWxlKDApLnRvQnVpbGRlcigpLnNldENoZWNrc3VtKCIiKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0VGhhdChtZGRNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQoVEVTVF9LRVksIGRhdGFGaWxlR3JvdXApLmdldCgpKS5pc0ZhbHNlKCk7CisgICAgdmVyaWZ5KG1vY2tMb2dnZXIpCisgICAgICAgIC5sb2dFdmVudFNhbXBsZWQoCisgICAgICAgICAgICAwLCBURVNUX0dST1VQLCAvKiBmaWxlR3JvdXBWZXJzaW9uTnVtYmVyPSAqLyAwLCAvKiBidWlsZElkPSAqLyAwLCAvKiB2YXJpYW50SWQ9ICovICIiKTsKKyAgICB2ZXJpZnlOb0ludGVyYWN0aW9ucyhtb2NrRmlsZUdyb3VwTWFuYWdlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0QWRkR3JvdXBGb3JEb3dubG9hZF9zaWRlbG9hZGVkRmlsZV9vbmx5V2hlblNpZGVsb2FkaW5nSXNFbmFibGVkKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENyZWF0ZSBzaWRlbG9hZGVkIGdyb3VwCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHNpZGVsb2FkZWRHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5hZGRGaWxlKAorICAgICAgICAgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RmlsZUlkKCJzaWRlbG9hZGVkX2ZpbGUiKQorICAgICAgICAgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiZmlsZTovdGVzdCIpCisgICAgICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bVR5cGUoRGF0YUZpbGUuQ2hlY2tzdW1UeXBlLk5PTkUpCisgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLmFkZEdyb3VwRm9yRG93bmxvYWQoZXEoVEVTVF9LRVkpLCBhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHRydWUpKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLnZlcmlmeVBlbmRpbmdHcm91cERvd25sb2FkZWQoZXEoVEVTVF9LRVkpLCBhbnkoKSwgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShHcm91cERvd25sb2FkU3RhdHVzLkRPV05MT0FERUQpKTsKKworICAgIHsKKyAgICAgIC8vIEZvcmNlIHNpZGVsb2FkaW5nIG9mZgorICAgICAgZmxhZ3MuZW5hYmxlU2lkZWxvYWRpbmcgPSBPcHRpb25hbC5vZihmYWxzZSk7CisKKyAgICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBzaWRlbG9hZGVkR3JvdXApLmdldCgpKS5pc0ZhbHNlKCk7CisgICAgfQorCisgICAgeworICAgICAgLy8gRm9yY2Ugc2lkZWxvYWRpbmcgb24KKyAgICAgIGZsYWdzLmVuYWJsZVNpZGVsb2FkaW5nID0gT3B0aW9uYWwub2YodHJ1ZSk7CisKKyAgICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5hZGRHcm91cEZvckRvd25sb2FkKFRFU1RfS0VZLCBzaWRlbG9hZGVkR3JvdXApLmdldCgpKS5pc1RydWUoKTsKKyAgICB9CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRmlsZUdyb3VwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgd2hlbihtb2NrRmlsZUdyb3VwTWFuYWdlci5yZW1vdmVGaWxlR3JvdXAoZXEoZ3JvdXBLZXkpLCBlcShmYWxzZSkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsIC8qIFZvaWQgKi8pKTsKKworICAgIG1kZE1hbmFnZXIucmVtb3ZlRmlsZUdyb3VwKGdyb3VwS2V5LCAvKiBwZW5kaW5nT25seT0gKi8gZmFsc2UpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyKS5yZW1vdmVGaWxlR3JvdXAoZ3JvdXBLZXksIC8qIHBlbmRpbmdPbmx5PSAqLyBmYWxzZSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tGaWxlR3JvdXBNYW5hZ2VyKTsKKyAgICB2ZXJpZnlOb0ludGVyYWN0aW9ucyhtb2NrTG9nZ2VyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVGaWxlR3JvdXBfb25GYWlsdXJlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgR3JvdXBLZXkgZ3JvdXBLZXkgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgZG9UaHJvdyhuZXcgSU9FeGNlcHRpb24oKSkKKyAgICAgICAgLndoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIpCisgICAgICAgIC5yZW1vdmVGaWxlR3JvdXAoZ3JvdXBLZXksIC8qIHBlbmRpbmdPbmx5PSAqLyBmYWxzZSk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICBtZGRNYW5hZ2VyLnJlbW92ZUZpbGVHcm91cChncm91cEtleSwgLyogcGVuZGluZ09ubHk9ICovIGZhbHNlKTo6Z2V0KTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoSU9FeGNlcHRpb24uY2xhc3MpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyKS5yZW1vdmVGaWxlR3JvdXAoZ3JvdXBLZXksIC8qIHBlbmRpbmdPbmx5PSAqLyBmYWxzZSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tGaWxlR3JvdXBNYW5hZ2VyKTsKKyAgICB2ZXJpZnlOb0ludGVyYWN0aW9ucyhtb2NrTG9nZ2VyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RSZW1vdmVGaWxlR3JvdXBzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgR3JvdXBLZXkgZ3JvdXBLZXkxID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKGNvbnRleHQuZ2V0UGFja2FnZU5hbWUoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIEdyb3VwS2V5IGdyb3VwS2V5MiA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShURVNUX0dST1VQICsgIl8yIikKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLnJlbW92ZUZpbGVHcm91cHMoZ3JvdXBLZXlMaXN0Q2FwdG9yLmNhcHR1cmUoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKworICAgIG1kZE1hbmFnZXIucmVtb3ZlRmlsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKGdyb3VwS2V5MSwgZ3JvdXBLZXkyKSkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cE1hbmFnZXIpLnJlbW92ZUZpbGVHcm91cHMoYW55TGlzdCgpKTsKKyAgICBMaXN0PEdyb3VwS2V5PiBncm91cEtleUxpc3RDYXB0dXJlID0gZ3JvdXBLZXlMaXN0Q2FwdG9yLmdldFZhbHVlKCk7CisgICAgYXNzZXJ0VGhhdChncm91cEtleUxpc3RDYXB0dXJlKS5oYXNTaXplKDIpOworICAgIGFzc2VydFRoYXQoZ3JvdXBLZXlMaXN0Q2FwdHVyZSkuY29udGFpbnMoZ3JvdXBLZXkxKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5TGlzdENhcHR1cmUpLmNvbnRhaW5zKGdyb3VwS2V5Mik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRmlsZUdyb3Vwc19vbkZhaWx1cmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBHcm91cEtleSBncm91cEtleTEgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoY29udGV4dC5nZXRQYWNrYWdlTmFtZSgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgR3JvdXBLZXkgZ3JvdXBLZXkyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVAgKyAiXzIiKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShjb250ZXh0LmdldFBhY2thZ2VOYW1lKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIucmVtb3ZlRmlsZUdyb3Vwcyhncm91cEtleUxpc3RDYXB0b3IuY2FwdHVyZSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUobmV3IEV4Y2VwdGlvbigiVGVzdCBmYWlsdXJlIikpKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+IG1kZE1hbmFnZXIucmVtb3ZlRmlsZUdyb3VwcyhJbW11dGFibGVMaXN0Lm9mKGdyb3VwS2V5MSwgZ3JvdXBLZXkyKSkuZ2V0KCkpOworICAgIGFzc2VydFRoYXQoZXgpLmhhc01lc3NhZ2VUaGF0KCkuY29udGFpbnMoIlRlc3QgZmFpbHVyZSIpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyKS5yZW1vdmVGaWxlR3JvdXBzKGFueUxpc3QoKSk7CisgICAgTGlzdDxHcm91cEtleT4gZ3JvdXBLZXlMaXN0Q2FwdHVyZSA9IGdyb3VwS2V5TGlzdENhcHRvci5nZXRWYWx1ZSgpOworICAgIGFzc2VydFRoYXQoZ3JvdXBLZXlMaXN0Q2FwdHVyZSkuaGFzU2l6ZSgyKTsKKyAgICBhc3NlcnRUaGF0KGdyb3VwS2V5TGlzdENhcHR1cmUpLmNvbnRhaW5zKGdyb3VwS2V5MSk7CisgICAgYXNzZXJ0VGhhdChncm91cEtleUxpc3RDYXB0dXJlKS5jb250YWlucyhncm91cEtleTIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEdldERvd25sb2FkZWRHcm91cCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuZ2V0RmlsZUdyb3VwKFRFU1RfS0VZLCB0cnVlKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZGF0YUZpbGVHcm91cCkpOworCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGNvbXBsZXRlZERhdGFGaWxlR3JvdXAgPSBtZGRNYW5hZ2VyLmdldEZpbGVHcm91cChURVNUX0tFWSwgdHJ1ZSkuZ2V0KCk7CisgICAgTWRkVGVzdFV0aWwuYXNzZXJ0TWVzc2FnZUVxdWFscyhkYXRhRmlsZUdyb3VwLCBjb21wbGV0ZWREYXRhRmlsZUdyb3VwKTsKKyAgICB2ZXJpZnlOb0ludGVyYWN0aW9ucyhtb2NrTG9nZ2VyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RHZXREYXRhRmlsZVVyaSgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworCisgICAgd2hlbihtb2NrRmlsZUdyb3VwTWFuYWdlci5nZXRPbkRldmljZVVyaShkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCksIGRhdGFGaWxlR3JvdXApKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmaWxlVXJpMSkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDEpLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmlsZVVyaTIpKTsKKworICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5nZXREYXRhRmlsZVVyaShkYXRhRmlsZUdyb3VwLmdldEZpbGUoMCksIGRhdGFGaWxlR3JvdXApLmdldCgpKQorICAgICAgICAuaXNFcXVhbFRvKGZpbGVVcmkxKTsKKyAgICBhc3NlcnRUaGF0KG1kZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDEpLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhmaWxlVXJpMik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0R2V0RGF0YUZpbGVVcmlfcmVhZFRyYW5zZm9ybSgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDIpOworCisgICAgVHJhbnNmb3JtcyBjb21wcmVzc1RyYW5zZm9ybSA9CisgICAgICAgIFRyYW5zZm9ybXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKAorICAgICAgICAgICAgICAgIFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkuc2V0Q29tcHJlc3MoQ29tcHJlc3NUcmFuc2Zvcm0uZ2V0RGVmYXVsdEluc3RhbmNlKCkpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgZGF0YUZpbGVHcm91cCA9CisgICAgICAgIGRhdGFGaWxlR3JvdXAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlKDAsIGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgwKS50b0J1aWxkZXIoKS5zZXRSZWFkVHJhbnNmb3Jtcyhjb21wcmVzc1RyYW5zZm9ybSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuZ2V0T25EZXZpY2VVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmlsZVVyaTEpKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLmdldE9uRGV2aWNlVXJpKGRhdGFGaWxlR3JvdXAuZ2V0RmlsZSgxKSwgZGF0YUZpbGVHcm91cCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKGZpbGVVcmkyKSk7CisKKyAgICBhc3NlcnRUaGF0KG1kZE1hbmFnZXIuZ2V0RGF0YUZpbGVVcmkoZGF0YUZpbGVHcm91cC5nZXRGaWxlKDApLCBkYXRhRmlsZUdyb3VwKS5nZXQoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhmaWxlVXJpMS5idWlsZFVwb24oKS5lbmNvZGVkRnJhZ21lbnQoInRyYW5zZm9ybT1jb21wcmVzcyIpLmJ1aWxkKCkpOworICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5nZXREYXRhRmlsZVVyaShkYXRhRmlsZUdyb3VwLmdldEZpbGUoMSksIGRhdGFGaWxlR3JvdXApLmdldCgpKQorICAgICAgICAuaXNFcXVhbFRvKGZpbGVVcmkyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RHZXREYXRhRmlsZVVyaV9yZWxhdGl2ZUZpbGVQYXRocygpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIHJlbGF0aXZlUGF0aEZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVSZWxhdGl2ZVBhdGhEYXRhRmlsZSgiZmlsZSIsIDEsICJ0ZXN0Iik7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHRlc3RGaWxlR3JvdXAgPQorICAgICAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKFRFU1RfR1JPVVApCisgICAgICAgICAgICAuc2V0UHJlc2VydmVGaWxlbmFtZXNBbmRJc29sYXRlRmlsZXModHJ1ZSkKKyAgICAgICAgICAgIC5hZGRGaWxlKHJlbGF0aXZlUGF0aEZpbGUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIFVyaSBzeW1saW5rZWRVcmkgPQorICAgICAgICBGaWxlR3JvdXBVdGlsLmdldElzb2xhdGVkRmlsZVVyaSgKKyAgICAgICAgICAgIGNvbnRleHQsIE9wdGlvbmFsLmFic2VudCgpLCByZWxhdGl2ZVBhdGhGaWxlLCB0ZXN0RmlsZUdyb3VwKTsKKworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuZ2V0T25EZXZpY2VVcmkodGVzdEZpbGVHcm91cC5nZXRGaWxlKDApLCB0ZXN0RmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoZmlsZVVyaTEpKTsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLmdldEFuZFZlcmlmeUlzb2xhdGVkRmlsZVVyaSgKKyAgICAgICAgICAgIGZpbGVVcmkxLCByZWxhdGl2ZVBhdGhGaWxlLCB0ZXN0RmlsZUdyb3VwKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oc3ltbGlua2VkVXJpKTsKKworICAgIGFzc2VydFRoYXQobWRkTWFuYWdlci5nZXREYXRhRmlsZVVyaShyZWxhdGl2ZVBhdGhGaWxlLCB0ZXN0RmlsZUdyb3VwKS5nZXQoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhzeW1saW5rZWRVcmkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEdldERhdGFGaWxlVXJpX3doZW5TeW1saW5rUmVxdWlyZWRCdXROb3RQcmVzZW50X3JldHVybnNOdWxsKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgcmVsYXRpdmVQYXRoRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVJlbGF0aXZlUGF0aERhdGFGaWxlKCJmaWxlIiwgMSwgInRlc3QiKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgdGVzdEZpbGVHcm91cCA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoVEVTVF9HUk9VUCkKKyAgICAgICAgICAgIC5zZXRQcmVzZXJ2ZUZpbGVuYW1lc0FuZElzb2xhdGVGaWxlcyh0cnVlKQorICAgICAgICAgICAgLmFkZEZpbGUocmVsYXRpdmVQYXRoRmlsZSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgd2hlbihtb2NrRmlsZUdyb3VwTWFuYWdlci5nZXRPbkRldmljZVVyaSh0ZXN0RmlsZUdyb3VwLmdldEZpbGUoMCksIHRlc3RGaWxlR3JvdXApKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShmaWxlVXJpMSkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuZ2V0QW5kVmVyaWZ5SXNvbGF0ZWRGaWxlVXJpKAorICAgICAgICAgICAgZmlsZVVyaTEsIHJlbGF0aXZlUGF0aEZpbGUsIHRlc3RGaWxlR3JvdXApKQorICAgICAgICAudGhlblRocm93KG5ldyBJT0V4Y2VwdGlvbigidGVzdCBmYWlsdXJlIikpOworCisgICAgYXNzZXJ0VGhhdChtZGRNYW5hZ2VyLmdldERhdGFGaWxlVXJpKHJlbGF0aXZlUGF0aEZpbGUsIHRlc3RGaWxlR3JvdXApLmdldCgpKS5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RJbXBvcnRGaWxlc19mYWlsZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBJbW11dGFibGVMaXN0PERhdGFGaWxlPiB1cGRhdGVkRGF0YUZpbGVMaXN0ID0KKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJpbmxpbmUtZmlsZSIsIDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImlubGluZWZpbGU6c2hhMTphYmNkZWYiKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICBJbW11dGFibGVNYXA8U3RyaW5nLCBGaWxlU291cmNlPiBpbmxpbmVGaWxlTWFwID0KKyAgICAgICAgSW1tdXRhYmxlTWFwLm9mKAorICAgICAgICAgICAgImlubGluZS1maWxlIiwgRmlsZVNvdXJjZS5vZkJ5dGVTdHJpbmcoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoIlRFU1RfQ09OVEVOVCIpKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3VwTWFuYWdlci5pbXBvcnRGaWxlc0ludG9GaWxlR3JvdXAoCisgICAgICAgICAgICBlcShURVNUX0tFWSksIGFueUxvbmcoKSwgYW55KCksIGFueSgpLCBhbnkoKSwgYW55KCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUobmV3IEV4Y2VwdGlvbigiVGVzdCBmYWlsdXJlIikpKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgbWRkTWFuYWdlcgorICAgICAgICAgICAgICAgICAgICAuaW1wb3J0RmlsZXMoCisgICAgICAgICAgICAgICAgICAgICAgICBURVNUX0tFWSwKKyAgICAgICAgICAgICAgICAgICAgICAgIDEsCisgICAgICAgICAgICAgICAgICAgICAgICAidGVzdHZhcmlhbnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZERhdGFGaWxlTGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGlubGluZUZpbGVNYXAsCisgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAgICAgICAgICAgICAuZ2V0KCkpOworCisgICAgYXNzZXJ0VGhhdChleCkuaGFzTWVzc2FnZVRoYXQoKS5jb250YWlucygiVGVzdCBmYWlsdXJlIik7CisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyKQorICAgICAgICAuaW1wb3J0RmlsZXNJbnRvRmlsZUdyb3VwKAorICAgICAgICAgICAgZXEoVEVTVF9LRVkpLAorICAgICAgICAgICAgYW55TG9uZygpLAorICAgICAgICAgICAgYW55KCksCisgICAgICAgICAgICBlcSh1cGRhdGVkRGF0YUZpbGVMaXN0KSwKKyAgICAgICAgICAgIGVxKGlubGluZUZpbGVNYXApLAorICAgICAgICAgICAgYW55KCksCisgICAgICAgICAgICBhbnkoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0RmlsZXNfc3VjY2VlZHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBJbW11dGFibGVMaXN0PERhdGFGaWxlPiB1cGRhdGVkRGF0YUZpbGVMaXN0ID0KKyAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJpbmxpbmUtZmlsZSIsIDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImlubGluZWZpbGU6c2hhMTphYmNkZWYiKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgICBJbW11dGFibGVNYXA8U3RyaW5nLCBGaWxlU291cmNlPiBpbmxpbmVGaWxlTWFwID0KKyAgICAgICAgSW1tdXRhYmxlTWFwLm9mKAorICAgICAgICAgICAgImlubGluZS1maWxlIiwgRmlsZVNvdXJjZS5vZkJ5dGVTdHJpbmcoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoIlRFU1RfQ09OVEVOVCIpKSk7CisKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLmltcG9ydEZpbGVzSW50b0ZpbGVHcm91cCgKKyAgICAgICAgICAgIGVxKFRFU1RfS0VZKSwgYW55TG9uZygpLCBhbnkoKSwgYW55KCksIGFueSgpLCBhbnkoKSwgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihpbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworCisgICAgbWRkTWFuYWdlcgorICAgICAgICAuaW1wb3J0RmlsZXMoCisgICAgICAgICAgICBURVNUX0tFWSwKKyAgICAgICAgICAgIDEsCisgICAgICAgICAgICAidGVzdHZhcmlhbnQiLAorICAgICAgICAgICAgdXBkYXRlZERhdGFGaWxlTGlzdCwKKyAgICAgICAgICAgIGlubGluZUZpbGVNYXAsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIG5vQ3VzdG9tVmFsaWRhdGlvbigpKQorICAgICAgICAuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cE1hbmFnZXIpCisgICAgICAgIC5pbXBvcnRGaWxlc0ludG9GaWxlR3JvdXAoCisgICAgICAgICAgICBlcShURVNUX0tFWSksCisgICAgICAgICAgICBhbnlMb25nKCksCisgICAgICAgICAgICBhbnkoKSwKKyAgICAgICAgICAgIGVxKHVwZGF0ZWREYXRhRmlsZUxpc3QpLAorICAgICAgICAgICAgZXEoaW5saW5lRmlsZU1hcCksCisgICAgICAgICAgICBhbnkoKSwKKyAgICAgICAgICAgIGFueSgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REb3dubG9hZFBlbmRpbmdHcm91cF9mYWlsZWQoKSB7CisgICAgd2hlbihtb2NrRmlsZUdyb3VwTWFuYWdlci5kb3dubG9hZEZpbGVHcm91cChlcShURVNUX0tFWSksIGlzTnVsbCgpLCBhbnkoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKAorICAgICAgICAgICAgRnV0dXJlcy5pbW1lZGlhdGVGYWlsZWRGdXR1cmUoCisgICAgICAgICAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXREb3dubG9hZFJlc3VsdENvZGUoRG93bmxvYWRSZXN1bHRDb2RlLlVOS05PV05fRVJST1IpCisgICAgICAgICAgICAgICAgICAgIC5zZXRNZXNzYWdlKCJGYWlsIikKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8RGF0YUZpbGVHcm91cEludGVybmFsPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIG1kZE1hbmFnZXIuZG93bmxvYWRGaWxlR3JvdXAoVEVTVF9LRVksIE9wdGlvbmFsLmFic2VudCgpLCBub0N1c3RvbVZhbGlkYXRpb24oKSk7CisgICAgYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgZG93bmxvYWRGdXR1cmU6OmdldCk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gdW51c2VkID0KKyAgICAgICAgTGFic0Z1dHVyZXMuZ2V0RmFpbHVyZUNhdXNlQXMoZG93bmxvYWRGdXR1cmUsIERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKworICAgIHZlcmlmeShtb2NrRmlsZUdyb3VwTWFuYWdlcikuZG93bmxvYWRGaWxlR3JvdXAoZXEoVEVTVF9LRVkpLCBpc051bGwoKSwgYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkUGVuZGluZ0dyb3VwX2Rvd25sb2FkQ29uZGl0aW9uX2Fic2VudCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLmRvd25sb2FkRmlsZUdyb3VwKGVxKFRFU1RfS0VZKSwgaXNOdWxsKCksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUocGVuZGluZ0dyb3VwKSk7CisKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgbWRkTWFuYWdlci5kb3dubG9hZEZpbGVHcm91cChURVNUX0tFWSwgT3B0aW9uYWwuYWJzZW50KCksIG5vQ3VzdG9tVmFsaWRhdGlvbigpKS5nZXQoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhwZW5kaW5nR3JvdXApOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBNYW5hZ2VyKS5kb3dubG9hZEZpbGVHcm91cChlcShURVNUX0tFWSksIGlzTnVsbCgpLCBhbnkoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG93bmxvYWRQZW5kaW5nR3JvdXBfZG93bmxvYWRDb25kaXRpb25fcHJlc2VudCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBwZW5kaW5nR3JvdXAgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZUdyb3VwSW50ZXJuYWwoVEVTVF9HUk9VUCwgMSk7CisKKyAgICBPcHRpb25hbDxEb3dubG9hZENvbmRpdGlvbnM+IGRvd25sb2FkQ29uZGl0aW9uc09wdGlvbmFsID0KKyAgICAgICAgT3B0aW9uYWwub2YoCisgICAgICAgICAgICBEb3dubG9hZENvbmRpdGlvbnMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldERldmljZU5ldHdvcmtQb2xpY3koRGV2aWNlTmV0d29ya1BvbGljeS5ET1dOTE9BRF9PTl9BTllfTkVUV09SSykKKyAgICAgICAgICAgICAgICAuc2V0RGV2aWNlU3RvcmFnZVBvbGljeShEZXZpY2VTdG9yYWdlUG9saWN5LkJMT0NLX0RPV05MT0FEX0lOX0xPV19TVE9SQUdFKQorICAgICAgICAgICAgICAgIC5idWlsZCgpKTsKKworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuZG93bmxvYWRGaWxlR3JvdXAoCisgICAgICAgICAgICBlcShURVNUX0tFWSksIGVxKGRvd25sb2FkQ29uZGl0aW9uc09wdGlvbmFsLmdldCgpKSwgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShwZW5kaW5nR3JvdXApKTsKKworICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBtZGRNYW5hZ2VyCisgICAgICAgICAgICAgICAgLmRvd25sb2FkRmlsZUdyb3VwKFRFU1RfS0VZLCBkb3dubG9hZENvbmRpdGlvbnNPcHRpb25hbCwgbm9DdXN0b21WYWxpZGF0aW9uKCkpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNFcXVhbFRvKHBlbmRpbmdHcm91cCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cE1hbmFnZXIpCisgICAgICAgIC5kb3dubG9hZEZpbGVHcm91cChlcShURVNUX0tFWSksIGVxKGRvd25sb2FkQ29uZGl0aW9uc09wdGlvbmFsLmdldCgpKSwgYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdERvd25sb2FkQWxsUGVuZGluZ0dyb3VwcygpIHRocm93cyBFeGNlcHRpb24geworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuc2NoZWR1bGVBbGxQZW5kaW5nR3JvdXBzRm9yRG93bmxvYWQoZXEodHJ1ZSksIGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworCisgICAgbWRkTWFuYWdlci5kb3dubG9hZEFsbFBlbmRpbmdHcm91cHModHJ1ZSwgbm9DdXN0b21WYWxpZGF0aW9uKCkpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tMb2dnZXIpLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cE1hbmFnZXIpLnNjaGVkdWxlQWxsUGVuZGluZ0dyb3Vwc0ZvckRvd25sb2FkKGVxKHRydWUpLCBhbnkoKSk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tMb2dnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFZlcmlmeVBlbmRpbmdHcm91cHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKG1vY2tGaWxlR3JvdXBNYW5hZ2VyLnZlcmlmeUFsbFBlbmRpbmdHcm91cHNEb3dubG9hZGVkKGFueSgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworCisgICAgbWRkTWFuYWdlci52ZXJpZnlBbGxQZW5kaW5nR3JvdXBzKG5vQ3VzdG9tVmFsaWRhdGlvbigpKS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrRmlsZUdyb3VwTWFuYWdlcikudmVyaWZ5QWxsUGVuZGluZ0dyb3Vwc0Rvd25sb2FkZWQoYW55KCkpOworICAgIHZlcmlmeShtb2NrTG9nZ2VyKS5sb2dFdmVudFNhbXBsZWQoMCk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tMb2dnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdE1haW50ZW5hbmNlX21kZEZpbGVFeHBpcmF0aW9uKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc2V0dXBNYWludGVuYW5jZVRhc2tzKCk7CisKKyAgICBtZGRNYW5hZ2VyLm1haW50ZW5hbmNlKCkuZ2V0KCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cE1hbmFnZXIpLmRlbGV0ZVVuaW5zdGFsbGVkQXBwR3JvdXBzKCk7CisKKyAgICB2ZXJpZnkobW9ja0V4cGlyYXRpb25IYW5kbGVyKS51cGRhdGVFeHBpcmF0aW9uKCk7CisKKyAgICB2ZXJpZnkobW9ja0ZpbGVHcm91cFN0YXRzTG9nZ2VyKS5sb2coYW55SW50KCkpOworICAgIHZlcmlmeShtb2NrTG9nZ2VyKS5sb2dFdmVudFNhbXBsZWQoMCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0TWFpbnRlbmFuY2VfbG9nU3RvcmFnZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIHNldHVwTWFpbnRlbmFuY2VUYXNrcygpOworCisgICAgbWRkTWFuYWdlci5tYWludGVuYW5jZSgpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tGaWxlR3JvdXBTdGF0c0xvZ2dlcikubG9nKGFueUludCgpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RNYWludGVuYW5jZV9sb2dOZXR3b3JrKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc2V0dXBNYWludGVuYW5jZVRhc2tzKCk7CisKKyAgICBtZGRNYW5hZ2VyLm1haW50ZW5hbmNlKCkuZ2V0KCk7CisgICAgdmVyaWZ5KG1vY2tOZXR3b3JrTG9nZ2VyKS5sb2coKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1haW50ZW5hbmNlX3RyaWdnZXJTeW5jX2Fic2VudFNwZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIG1kZE1hbmFnZXIgPQorICAgICAgICBuZXcgTW9iaWxlRGF0YURvd25sb2FkTWFuYWdlcigKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrTG9nZ2VyLAorICAgICAgICAgICAgbW9ja1NoYXJlZEZpbGVNYW5hZ2VyLAorICAgICAgICAgICAgbW9ja1NoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgICAgICBtb2NrRmlsZUdyb3VwTWFuYWdlciwKKyAgICAgICAgICAgIG1vY2tGaWxlR3JvdXBzTWV0YWRhdGEsCisgICAgICAgICAgICBtb2NrRXhwaXJhdGlvbkhhbmRsZXIsCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICBtb2NrU3RvcmFnZUxvZ2dlciwKKyAgICAgICAgICAgIG1vY2tGaWxlR3JvdXBTdGF0c0xvZ2dlciwKKyAgICAgICAgICAgIG1vY2tOZXR3b3JrTG9nZ2VyLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBDT05UUk9MX0VYRUNVVE9SLAorICAgICAgICAgICAgZmxhZ3MsCisgICAgICAgICAgICBsb2dnaW5nU3RhdGVTdG9yZSwKKyAgICAgICAgICAgIGRvd25sb2FkU3RhZ2VNYW5hZ2VyKTsKKworICAgIHNldHVwTWFpbnRlbmFuY2VUYXNrcygpOworCisgICAgbWRkTWFuYWdlci5tYWludGVuYW5jZSgpLmdldCgpOworCisgICAgLy8gV2l0aCBhYnNlbnQgU1BFLCBubyB0cmlnZ2VyU3luYyB3YXMgY2FsbGVkLgorICAgIHZlcmlmeShtb2NrRmlsZUdyb3VwTWFuYWdlciwgbmV2ZXIoKSkudHJpZ2dlclN5bmNBbGxQZW5kaW5nR3JvdXBzKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0TWFpbnRlbmFuY2VfZGVsZXRlUmVtb3ZlZEFjY291bnRHcm91cHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzZXR1cE1haW50ZW5hbmNlVGFza3MoKTsKKworICAgIGZsYWdzLm1kZERlbGV0ZUdyb3Vwc1JlbW92ZWRBY2NvdW50cyA9IE9wdGlvbmFsLm9mKHRydWUpOworCisgICAgbWRkTWFuYWdlci5tYWludGVuYW5jZSgpLmdldCgpOworICAgIHZlcmlmeShtb2NrRmlsZUdyb3VwTWFuYWdlcikuZGVsZXRlUmVtb3ZlZEFjY291bnRHcm91cHMoKTsKKyAgfQorCisgIHZvaWQgc2V0dXBNYWludGVuYW5jZVRhc2tzKCkgeworICAgIGZsYWdzLmVuYWJsZURheXNTaW5jZUxhc3RNYWludGVuYW5jZVRyYWNraW5nID0gT3B0aW9uYWwub2YodHJ1ZSk7CisKKyAgICB3aGVuKG1vY2tTdG9yYWdlTG9nZ2VyLmxvZ1N0b3JhZ2VTdGF0cyhhbnlJbnQoKSkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworICAgIHdoZW4obW9ja0V4cGlyYXRpb25IYW5kbGVyLnVwZGF0ZUV4cGlyYXRpb24oKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3VwU3RhdHNMb2dnZXIubG9nKGFueUludCgpKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKSk7CisgICAgd2hlbihtb2NrTmV0d29ya0xvZ2dlci5sb2coKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKSk7CisgICAgd2hlbihtb2NrRmlsZUdyb3VwTWFuYWdlci5sb2dBbmREZWxldGVGb3JNaXNzaW5nU2hhcmVkRmlsZXMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuZGVsZXRlVW5pbnN0YWxsZWRBcHBHcm91cHMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIuZGVsZXRlUmVtb3ZlZEFjY291bnRHcm91cHMoKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIudHJpZ2dlclN5bmNBbGxQZW5kaW5nR3JvdXBzKCkpLnRoZW5SZXR1cm4oaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKworICAgIHdoZW4obW9ja0ZpbGVHcm91cE1hbmFnZXIudmVyaWZ5QW5kQXR0ZW1wdFRvUmVwYWlySXNvbGF0ZWRGaWxlcygpKQorICAgICAgICAudGhlblJldHVybihpbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdENsZWFyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgbWRkTWFuYWdlci5jbGVhcigpLmdldCgpOworCisgICAgdmVyaWZ5KG1vY2tTaGFyZWRGaWxlTWFuYWdlcikuY2FuY2VsRG93bmxvYWRBbmRDbGVhcigpOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tMb2dnZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdENoZWNrUmVzZXRUcmlnZ2VyX3Jlc2V0VHJpZ2dlcl9ub0luY3JlbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHNldFNhdmVkUmVzZXRWYWx1ZSgxKTsKKyAgICBmbGFncy5tZGRSZXNldFRyaWdnZXIgPSBPcHRpb25hbC5vZigxKTsKKworICAgIG1kZE1hbmFnZXIuY2hlY2tSZXNldFRyaWdnZXIoKS5nZXQoKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyLCBuZXZlcigpKS5jbGVhcigpOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tMb2dnZXIpOworICAgIC8vIHNhdmVkIHJlc2V0IHZhbHVlIHNob3VsZCBub3QgaGF2ZSBjaGFuZ2VkCisgICAgY2hlY2tTYXZlZFJlc2V0VmFsdWUoMSk7CisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0xvZ2dlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0Q2hlY2tSZXNldFRyaWdnZXJfcmVzZXRUcmlnZ2VyX3NpbmdsZUluY3JlbWVudCgpIHRocm93cyBFeGNlcHRpb24geworICAgIHNldFNhdmVkUmVzZXRWYWx1ZSgxKTsKKyAgICBmbGFncy5tZGRSZXNldFRyaWdnZXIgPSBPcHRpb25hbC5vZigyKTsKKworICAgIG1kZE1hbmFnZXIuY2hlY2tSZXNldFRyaWdnZXIoKS5nZXQoKTsKKyAgICB2ZXJpZnkobW9ja1NoYXJlZEZpbGVNYW5hZ2VyKS5jYW5jZWxEb3dubG9hZEFuZENsZWFyKCk7CisgICAgdmVyaWZ5KG1vY2tMb2dnZXIpLmxvZ0V2ZW50U2FtcGxlZCgwKTsKKyAgICAvLyBzYXZlZCByZXNldCB2YWx1ZSBzaG91bGQgYmUgc2V0IHRvIDIKKyAgICBjaGVja1NhdmVkUmVzZXRWYWx1ZSgyKTsKKyAgICB2ZXJpZnlOb01vcmVJbnRlcmFjdGlvbnMobW9ja0xvZ2dlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0Q2hlY2tSZXNldFRyaWdnZXJfcmVzZXRUcmlnZ2VyX3NpbmdsZUluY3JlbWVudE11bHRpcGxlQ2hlY2tzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgc2V0U2F2ZWRSZXNldFZhbHVlKDEpOworICAgIGZsYWdzLm1kZFJlc2V0VHJpZ2dlciA9IE9wdGlvbmFsLm9mKDIpOworCisgICAgbWRkTWFuYWdlci5jaGVja1Jlc2V0VHJpZ2dlcigpLmdldCgpOworICAgIC8vIFRoZSBzZWNvbmQgY2hlY2sgc2hvdWxkIGhhdmUgbm8gZWZmZWN0IC0gY2xlYXIgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIG9uY2UuCisgICAgbWRkTWFuYWdlci5jaGVja1Jlc2V0VHJpZ2dlcigpLmdldCgpOworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIpLmNhbmNlbERvd25sb2FkQW5kQ2xlYXIoKTsKKyAgICB2ZXJpZnkobW9ja0xvZ2dlcikubG9nRXZlbnRTYW1wbGVkKDApOworICAgIC8vIHNhdmVkIHJlc2V0IHZhbHVlIHNob3VsZCBiZSBzZXQgdG8gMgorICAgIGNoZWNrU2F2ZWRSZXNldFZhbHVlKDIpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrTG9nZ2VyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RDaGVja1Jlc2V0VHJpZ2dlcl9yZXNldFRyaWdnZXJfbXVsdGlwbGVJbmNyZW1lbnRNdWx0aXBsZUNoZWNrcygpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBzZXRTYXZlZFJlc2V0VmFsdWUoMSk7CisgICAgZmxhZ3MubWRkUmVzZXRUcmlnZ2VyID0gT3B0aW9uYWwub2YoMik7CisKKyAgICBtZGRNYW5hZ2VyLmNoZWNrUmVzZXRUcmlnZ2VyKCkuZ2V0KCk7CisKKyAgICBmbGFncy5tZGRSZXNldFRyaWdnZXIgPSBPcHRpb25hbC5vZigzKTsKKworICAgIG1kZE1hbmFnZXIuY2hlY2tSZXNldFRyaWdnZXIoKS5nZXQoKTsKKworICAgIHZlcmlmeShtb2NrU2hhcmVkRmlsZU1hbmFnZXIsIHRpbWVzKDIpKS5jYW5jZWxEb3dubG9hZEFuZENsZWFyKCk7CisgICAgdmVyaWZ5KG1vY2tMb2dnZXIsIHRpbWVzKDIpKS5sb2dFdmVudFNhbXBsZWQoMCk7CisgICAgLy8gc2F2ZWQgcmVzZXQgdmFsdWUgc2hvdWxkIGJlIHNldCB0byAyCisgICAgY2hlY2tTYXZlZFJlc2V0VmFsdWUoMyk7CisgICAgdmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zKG1vY2tMb2dnZXIpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIHNldE1pZ3JhdGlvblN0YXRlKFN0cmluZyBrZXksIGJvb2xlYW4gdmFsdWUpIHsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBzaGFyZWRQcmVmZXJlbmNlcyA9CisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcygKKyAgICAgICAgICAgIGNvbnRleHQsIE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuTUREX01BTkFHRVJfTUVUQURBVEEsIE9wdGlvbmFsLmFic2VudCgpKTsKKyAgICBzaGFyZWRQcmVmZXJlbmNlcy5lZGl0KCkucHV0Qm9vbGVhbihrZXksIHZhbHVlKS5jb21taXQoKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBzZXRTYXZlZFJlc2V0VmFsdWUoaW50IHZhbHVlKSB7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMgcHJlZnMgPQorICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoCisgICAgICAgICAgICBjb250ZXh0LCBNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLk1ERF9NQU5BR0VSX01FVEFEQVRBLCBPcHRpb25hbC5hYnNlbnQoKSk7CisgICAgU2hhcmVkUHJlZmVyZW5jZXMuRWRpdG9yIGVkaXRvciA9IHByZWZzLmVkaXQoKTsKKyAgICBlZGl0b3IucHV0SW50KE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuUkVTRVRfVFJJR0dFUiwgdmFsdWUpOworICAgIGVkaXRvci5jb21taXQoKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCBjaGVja1NhdmVkUmVzZXRWYWx1ZShpbnQgZXhwZWN0ZWQpIHsKKyAgICBTaGFyZWRQcmVmZXJlbmNlcyBwcmVmcyA9CisgICAgICAgIFNoYXJlZFByZWZlcmVuY2VzVXRpbC5nZXRTaGFyZWRQcmVmZXJlbmNlcygKKyAgICAgICAgICAgIGNvbnRleHQsIE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXIuTUREX01BTkFHRVJfTUVUQURBVEEsIE9wdGlvbmFsLmFic2VudCgpKTsKKyAgICBhc3NlcnRUaGF0KHByZWZzLmdldEludChNb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyLlJFU0VUX1RSSUdHRVIsIGV4cGVjdGVkIC0gMSkpCisgICAgICAgIC5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgcHJpdmF0ZSBBc3luY0Z1bmN0aW9uPERhdGFGaWxlR3JvdXBJbnRlcm5hbCwgQm9vbGVhbj4gbm9DdXN0b21WYWxpZGF0aW9uKCkgeworICAgIHJldHVybiB1bnVzZWQgLT4gRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUodHJ1ZSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9TaGFyZWRGaWxlTWFuYWdlclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9TaGFyZWRGaWxlTWFuYWdlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMGQ1NjgyCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL1NoYXJlZEZpbGVNYW5hZ2VyVGVzdC5qYXZhCkBAIC0wLDAgKzEsMTAwMCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWw7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuU2hhcmVkRmlsZU1hbmFnZXIuTUREX1NIQVJFRF9GSUxFX01BTkFHRVJfTUVUQURBVEE7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuYW55OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueUludDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnlMaXN0OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmVxOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmlzQTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by5uZXZlcjsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by50aW1lczsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5Tm9JbnRlcmFjdGlvbnM7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ud2hlbjsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5TaGFyZWRQcmVmZXJlbmNlczsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZDsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb24uRG93bmxvYWRSZXN1bHRDb2RlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkZpbGVTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuU2lsZW50RmVlZGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZGVsdGEuRGVsdGFEZWNvZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuU3luY2hyb25vdXNGaWxlU3RvcmFnZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRGaWxlQmFja2VuZDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLmJhY2tlbmRzLkFuZHJvaWRVcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5CbG9iVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLkJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS50cmFuc2Zvcm1zLkNvbXByZXNzVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1pZ3JhdGlvbnMuRmlsZUtleVZlcnNpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuZG93bmxvYWRlci5Eb3dubG9hZGVyQ2FsbGJhY2tJbXBsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmRvd25sb2FkZXIuTWRkRmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5FdmVudExvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLkRpcmVjdG9yeVV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbC5GaWxlR3JvdXBVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuU2hhcmVkUHJlZmVyZW5jZXNVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLm1vbml0b3IuRG93bmxvYWRQcm9ncmVzc01vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5UZXN0RmxhZ3M7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5PcHRpb25hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5jb2xsZWN0LkltbXV0YWJsZUxpc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbC5BbGxvd2VkUmVhZGVyczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRlbHRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRlbHRhRmlsZS5EaWZmRGVjb2RlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9uczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkZpbGVTdGF0dXM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5Hcm91cEtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLk5ld0ZpbGVLZXk7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5TaGFyZWRGaWxlOworaW1wb3J0IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZzsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IG9yZy5qdW5pdC5BZnRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5QYXJhbWV0ZXJpemVkUm9ib2xlY3RyaWNUZXN0UnVubmVyOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5QYXJhbWV0ZXJpemVkUm9ib2xlY3RyaWNUZXN0UnVubmVyLlBhcmFtZXRlcjsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUGFyYW1ldGVyaXplZFJvYm9sZWN0cmljVGVzdFJ1bm5lci5QYXJhbWV0ZXJzOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5hbm5vdGF0aW9uLkNvbmZpZzsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMudXRpbC5SZWZsZWN0aW9uSGVscGVyczsKKworQFJ1bldpdGgoUGFyYW1ldGVyaXplZFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK0BDb25maWcoc2hhZG93cyA9IHt9KQorcHVibGljIGNsYXNzIFNoYXJlZEZpbGVNYW5hZ2VyVGVzdCB7CisKKyAgQFBhcmFtZXRlcnMoCisgICAgICBuYW1lID0KKyAgICAgICAgICAicnVuQWZ0ZXJNaWdyYXRlZFRvQWRkRG93bmxvYWRUcmFuc2Zvcm0gPSB7MH0sIHJ1bkFmdGVyTWlncmF0ZWRUb1VzZUNoZWNrc3VtT25seSA9IHsxfSIpCisgIHB1YmxpYyBzdGF0aWMgQ29sbGVjdGlvbjxPYmplY3RbXT4gcGFyYW1ldGVycygpIHsKKyAgICByZXR1cm4gQXJyYXlzLmFzTGlzdChuZXcgT2JqZWN0W11bXSB7e2ZhbHNlLCBmYWxzZX0sIHt0cnVlLCBmYWxzZX0sIHt0cnVlLCB0cnVlfX0pOworICB9CisKKyAgQFBhcmFtZXRlcih2YWx1ZSA9IDApCisgIHB1YmxpYyBib29sZWFuIHJ1bkFmdGVyTWlncmF0ZWRUb0FkZERvd25sb2FkVHJhbnNmb3JtOworCisgIEBQYXJhbWV0ZXIodmFsdWUgPSAxKQorICBwdWJsaWMgYm9vbGVhbiBydW5BZnRlck1pZ3JhdGVkVG9Vc2VDaGVja3N1bU9ubHk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRG93bmxvYWRDb25kaXRpb25zIERPV05MT0FEX0NPTkRJVElPTlMgPQorICAgICAgRG93bmxvYWRDb25kaXRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUUkFGRklDX1RBRyA9IDEwMDA7CisKKyAgcHJpdmF0ZSBDb250ZXh0IGNvbnRleHQ7CisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBGSUxFX0dST1VQX0VYUElSQVRJT05fREFURV9TRUNTID0gMTA7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBURVNUX0dST1VQID0gInRlc3QtZ3JvdXAiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVkVSU0lPTl9OVU1CRVIgPSA3OworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIEJVSUxEX0lEID0gMDsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRGF0YUZpbGVHcm91cEludGVybmFsIEZJTEVfR1JPVVAgPQorICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVHcm91cEludGVybmFsKFRFU1RfR1JPVVAsIDEpLnRvQnVpbGRlcigpCisgICAgICAgICAgLnNldEZpbGVHcm91cFZlcnNpb25OdW1iZXIoVkVSU0lPTl9OVU1CRVIpCisgICAgICAgICAgLmJ1aWxkKCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEdyb3VwS2V5IEdST1VQX0tFWSA9CisgICAgICBGaWxlR3JvdXBVdGlsLmNyZWF0ZUdyb3VwS2V5KEZJTEVfR1JPVVAuZ2V0R3JvdXBOYW1lKCksIEZJTEVfR1JPVVAuZ2V0T3duZXJQYWNrYWdlKCkpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBFeGVjdXRvciBDT05UUk9MX0VYRUNVVE9SID0KKyAgICAgIE1vcmVFeGVjdXRvcnMubmV3U2VxdWVudGlhbEV4ZWN1dG9yKEV4ZWN1dG9ycy5uZXdDYWNoZWRUaHJlYWRQb29sKCkpOworICBwcml2YXRlIFNoYXJlZEZpbGVNYW5hZ2VyIHNmbTsKKworICAvLyBUaGlzIGlzIGN1cnJlbnRseSBub3QgbW9ja2VkIGFzIHRoZSBjbGFzcyB3YXMgc3BsaXQgZnJvbSBTaGFyZWRGaWxlTWFuYWdlciwgYW5kIHRoaXMgZW5zdXJlcworICAvLyB0aGF0IGFsbCB0ZXN0cyBzdGlsbCBydW4gdGhlIHNhbWUgd2F5LgorICBwcml2YXRlIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YTsKKyAgcHJpdmF0ZSBGaWxlIHB1YmxpY0RpcmVjdG9yeTsKKyAgcHJpdmF0ZSBGaWxlIHByaXZhdGVEaXJlY3Rvcnk7CisgIHByaXZhdGUgT3B0aW9uYWw8RGVsdGFEZWNvZGVyPiBkZWx0YURlY29kZXI7CisgIHByaXZhdGUgZmluYWwgVGVzdEZsYWdzIGZsYWdzID0gbmV3IFRlc3RGbGFncygpOworICBATW9jayBTaWxlbnRGZWVkYmFjayBtb2NrU2lsZW50RmVlZGJhY2s7CisgIEBNb2NrIE1kZEZpbGVEb3dubG9hZGVyIG1vY2tEb3dubG9hZGVyOworICBATW9jayBEb3dubG9hZFByb2dyZXNzTW9uaXRvciBtb2NrRG93bmxvYWRNb25pdG9yOworICBATW9jayBFdmVudExvZ2dlciBldmVudExvZ2dlcjsKKyAgQE1vY2sgRmlsZUdyb3Vwc01ldGFkYXRhIGZpbGVHcm91cHNNZXRhZGF0YTsKKyAgQE1vY2sgQmFja2VuZCBtb2NrQmFja2VuZDsKKworICBAUnVsZSBwdWJsaWMgZmluYWwgTW9ja2l0b1J1bGUgbW9ja3MgPSBNb2NraXRvSlVuaXQucnVsZSgpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgIGNvbnRleHQgPSBBcHBsaWNhdGlvblByb3ZpZGVyLmdldEFwcGxpY2F0aW9uQ29udGV4dCgpOworCisgICAgd2hlbihtb2NrQmFja2VuZC5uYW1lKCkpLnRoZW5SZXR1cm4oImJsb2JzdG9yZSIpOworICAgIGZpbGVTdG9yYWdlID0KKyAgICAgICAgbmV3IFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UoCisgICAgICAgICAgICBBcnJheXMuYXNMaXN0KEFuZHJvaWRGaWxlQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLmJ1aWxkKCksIG1vY2tCYWNrZW5kKSwKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YobmV3IENvbXByZXNzVHJhbnNmb3JtKCkpKTsKKworICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEgPQorICAgICAgICBuZXcgU2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhKAorICAgICAgICAgICAgY29udGV4dCwgbW9ja1NpbGVudEZlZWRiYWNrLCBPcHRpb25hbC5hYnNlbnQoKSwgZmxhZ3MpOworCisgICAgZGVsdGFEZWNvZGVyID0gT3B0aW9uYWwuYWJzZW50KCk7CisgICAgc2ZtID0KKyAgICAgICAgbmV3IFNoYXJlZEZpbGVNYW5hZ2VyKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjaywKKyAgICAgICAgICAgIHNoYXJlZEZpbGVzTWV0YWRhdGEsCisgICAgICAgICAgICBmaWxlU3RvcmFnZSwKKyAgICAgICAgICAgIG1vY2tEb3dubG9hZGVyLAorICAgICAgICAgICAgZGVsdGFEZWNvZGVyLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICBldmVudExvZ2dlciwKKyAgICAgICAgICAgIGZsYWdzLAorICAgICAgICAgICAgZmlsZUdyb3Vwc01ldGFkYXRhLAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBDT05UUk9MX0VYRUNVVE9SKTsKKworICAgIC8vIFRPRE8oYi8xMTc1NzEwODMpOiBSZXBsYWNlIHdpdGggZmlsZVN0b3JhZ2UgQVBJLgorICAgIEZpbGUgZG93bmxvYWREaXJlY3RvcnkgPQorICAgICAgICBuZXcgRmlsZShjb250ZXh0LmdldEZpbGVzRGlyKCksIERpcmVjdG9yeVV0aWwuTUREX1NUT1JBR0VfTU9EVUxFICsgIi8iICsgInNoYXJlZCIpOworICAgIHB1YmxpY0RpcmVjdG9yeSA9IG5ldyBGaWxlKGRvd25sb2FkRGlyZWN0b3J5LCBEaXJlY3RvcnlVdGlsLk1ERF9TVE9SQUdFX0FMTF9HT09HTEVfQVBQUyk7CisgICAgcHJpdmF0ZURpcmVjdG9yeSA9CisgICAgICAgIG5ldyBGaWxlKGRvd25sb2FkRGlyZWN0b3J5LCBEaXJlY3RvcnlVdGlsLk1ERF9TVE9SQUdFX09OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMpOworICAgIHB1YmxpY0RpcmVjdG9yeS5ta2RpcnMoKTsKKyAgICBwcml2YXRlRGlyZWN0b3J5Lm1rZGlycygpOworCisgICAgaWYgKHJ1bkFmdGVyTWlncmF0ZWRUb1VzZUNoZWNrc3VtT25seSkgeworICAgICAgTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBGaWxlS2V5VmVyc2lvbi5VU0VfQ0hFQ0tTVU1fT05MWSk7CisgICAgfSBlbHNlIGlmIChydW5BZnRlck1pZ3JhdGVkVG9BZGREb3dubG9hZFRyYW5zZm9ybSkgeworICAgICAgTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBGaWxlS2V5VmVyc2lvbi5BRERfRE9XTkxPQURfVFJBTlNGT1JNKTsKKyAgICB9CisgIH0KKworICBAQWZ0ZXIKKyAgcHVibGljIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoCisgICAgICAgICAgICBjb250ZXh0LCBNRERfU0hBUkVEX0ZJTEVfTUFOQUdFUl9NRVRBREFUQSwgT3B0aW9uYWwuYWJzZW50KCkpCisgICAgICAgIC5lZGl0KCkKKyAgICAgICAgLmNsZWFyKCkKKyAgICAgICAgLmNvbW1pdCgpOworCisgICAgLy8gUmVzZXQgdG8gYXZvaWQgZXhjZXB0aW9uIGluIHRoZSBjYWxsIGJlbG93LgorICAgIGZpbGVTdG9yYWdlLmRlbGV0ZVJlY3Vyc2l2ZWx5KAorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldEJhc2VEb3dubG9hZERpcmVjdG9yeShjb250ZXh0LCBPcHRpb25hbC5hYnNlbnQoKSkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgaW5pdF9taWdyYXRlVG9OZXdLZXlfZW5hYmxlZF92MjNUb1YyNCgpIHRocm93cyBFeGNlcHRpb24geworICAgIE1pZ3JhdGlvbnMuc2V0TWlncmF0ZWRUb05ld0ZpbGVLZXkoY29udGV4dCwgZmFsc2UpOworCisgICAgYXNzZXJ0VGhhdChNaWdyYXRpb25zLmlzTWlncmF0ZWRUb05ld0ZpbGVLZXkoY29udGV4dCkpLmlzRmFsc2UoKTsKKworICAgIFNoYXJlZFByZWZlcmVuY2VzIHNmbU1ldGFkYXRhID0KKyAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKAorICAgICAgICAgICAgY29udGV4dCwgTUREX1NIQVJFRF9GSUxFX01BTkFHRVJfTUVUQURBVEEsIE9wdGlvbmFsLmFic2VudCgpKTsKKyAgICBzZm1NZXRhZGF0YQorICAgICAgICAuZWRpdCgpCisgICAgICAgIC5wdXRCb29sZWFuKFNoYXJlZEZpbGVNYW5hZ2VyLlBSRUZTX0tFWV9NSUdSQVRFRF9UT19ORVdfRklMRV9LRVksIHRydWUpCisgICAgICAgIC5jb21taXQoKTsKKworICAgIGFzc2VydFRoYXQoc2ZtLmluaXQoKS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBhc3NlcnRUaGF0KE1pZ3JhdGlvbnMuaXNNaWdyYXRlZFRvTmV3RmlsZUtleShjb250ZXh0KSkuaXNUcnVlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0U3Vic2NyaWJlQW5kVW5zdWJzY3JpYmVTaW5nbGVGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgYXNzZXJ0VGhhdChzZm0ucmVzZXJ2ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICAvLyBNYWtlIHN1cmUgdGhlIGZpbGUgZW50cnkgd2FzIHN0b3JlZC4KKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChuZXdGaWxlS2V5KSkuaXNOb3ROdWxsKCk7CisKKyAgICAvLyBVbnN1YnNjcmliZSBhbmQgZW5zdXJlIGVudHJ5IGZvciBmaWxlIHdhcyBkZWxldGVkLgorICAgIGFzc2VydFRoYXQoc2ZtLnJlbW92ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSkuZ2V0KCkpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdE11bHRpcGxlU3Vic2NyaWJlcygpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIGFzc2VydFRoYXQoc2ZtLnJlc2VydmVGaWxlRW50cnkobmV3RmlsZUtleSkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoc2ZtLnJlc2VydmVGaWxlRW50cnkobmV3RmlsZUtleSkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgLy8gVW5zdWJzY3JpYmUgb25jZS4gSXQgc2hvdWxkIG5vdCBtYXR0ZXIgaG93IG1hbnkgc3Vic2NyaWJlcyB3ZXJlIHByZXZpb3VzbHkgY2FsbGVkLiBBbgorICAgIC8vIHVuc3Vic2NyaWJlIHNob3VsZCByZW1vdmUgdGhlIGVudHJ5LgorICAgIGFzc2VydFRoYXQoc2ZtLnJlbW92ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSkuZ2V0KCkpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFJlbW92ZUZpbGVFbnRyeV9ub25leGlzdGVudEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZSBmaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGVJZCIsIDApOworCisgICAgLy8gVHJ5IHRvIHVuc3Vic2NyaWJlIGZyb20gYSBmaWxlIHRoYXQgd2FzIG5ldmVyIHN1YnNjcmliZWQgdG8gYW5kIGVuc3VyZSB0aGF0IHRoaXMgd29uJ3QgYWRkCisgICAgLy8gYW4gZW50cnkgZm9yIHRoZSBmaWxlLgorICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgYXNzZXJ0VGhhdChzZm0ucmVtb3ZlRmlsZUVudHJ5KG5ld0ZpbGVLZXkpLmdldCgpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSkuZ2V0KCkpLmlzTnVsbCgpOworCisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0Rvd25sb2FkZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFJlbW92ZUZpbGVFbnRyeV9wYXJ0aWFsRG93bmxvYWRGaWxlTm90RGVsZXRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIGFzc2VydFRoYXQoc2ZtLnJlc2VydmVGaWxlRW50cnkobmV3RmlsZUtleSkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgLy8gRG93bmxvYWQgdGhlIGZpbGUsIGJ1dCBkbyBub3QgdXBkYXRlIHNoYXJlZCBwcmVmcyB0byBzYXkgaXQgaXMgZG93bmxvYWRlZC4KKyAgICBGaWxlIG9uRGV2aWNlRmlsZSA9IHNpbXVsYXRlRG93bmxvYWQoZmlsZSwgZ2V0TGFzdEZpbGVOYW1lKCksIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisKKyAgICBhc3NlcnRUaGF0KG9uRGV2aWNlRmlsZS5leGlzdHMoKSkuaXNUcnVlKCk7CisKKyAgICBVcmkgdXJpID0gc2ZtLmdldE9uRGV2aWNlVXJpKG5ld0ZpbGVLZXkpLmdldCgpOworCisgICAgLy8gRW5zdXJlIHRoYXQgZGVyZWdpc3RlciBoYXMgYWN0dWFsbHkgZGVsZXRlZCB0aGUgZmlsZSBvbiBkaXNrLgorICAgIGFzc2VydFRoYXQoc2ZtLnJlbW92ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSkuZ2V0KCkpLmlzTnVsbCgpOworICAgIC8vIFRoZSBwYXJ0aWFsIGRvd25sb2FkIGZpbGUgc2hvdWxkIGJlIGRlbGV0ZWQKKyAgICBhc3NlcnRUaGF0KG9uRGV2aWNlRmlsZS5leGlzdHMoKSkuaXNUcnVlKCk7CisKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkZXIpLnN0b3BEb3dubG9hZGluZyh1cmkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFN0YXJ0SW1wb3J0X3N0YXJ0c0lubGluZUZpbGVDb3B5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRmlsZVNvdXJjZSBpbmxpbmVTb3VyY2UgPSBGaWxlU291cmNlLm9mQnl0ZVN0cmluZyhCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiVEVTVF9DT05URU5UIikpOworICAgIERhdGFGaWxlIGZpbGUgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJpbmxpbmVmaWxlOjEyMyIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgYXNzZXJ0VGhhdChzZm0ucmVzZXJ2ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgVXJpIGZpbGVVcmkgPSBzZm0uZ2V0T25EZXZpY2VVcmkobmV3RmlsZUtleSkuZ2V0KCk7CisgICAgd2hlbihmaWxlR3JvdXBzTWV0YWRhdGEucmVhZChHUk9VUF9LRVkpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKEZJTEVfR1JPVVApKTsKKyAgICB3aGVuKG1vY2tEb3dubG9hZGVyLnN0YXJ0Q29weWluZygKKyAgICAgICAgICAgIGVxKGZpbGVVcmkpLAorICAgICAgICAgICAgZXEoZmlsZS5nZXRVcmxUb0Rvd25sb2FkKCkpLAorICAgICAgICAgICAgZXEoZmlsZS5nZXRCeXRlU2l6ZSgpKSwKKyAgICAgICAgICAgIGVxKERPV05MT0FEX0NPTkRJVElPTlMpLAorICAgICAgICAgICAgaXNBKERvd25sb2FkZXJDYWxsYmFja0ltcGwuY2xhc3MpLAorICAgICAgICAgICAgYW55KCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKSk7CisKKyAgICBzZm0uc3RhcnRJbXBvcnQoR1JPVVBfS0VZLCBmaWxlLCBuZXdGaWxlS2V5LCBET1dOTE9BRF9DT05ESVRJT05TLCBpbmxpbmVTb3VyY2UpLmdldCgpOworCisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0gc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKG5ld0ZpbGVLZXkpLmdldCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZS5nZXRGaWxlU3RhdHVzKCkpLmlzRXF1YWxUbyhGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RTdGFydEltcG9ydF93aGVuRmlsZUFscmVhZHlEb3dubG9hZGVkX3JldHVybnNFYXJseSgpIHRocm93cyBFeGNlcHRpb24geworICAgIEZpbGVTb3VyY2UgaW5saW5lU291cmNlID0gRmlsZVNvdXJjZS5vZkJ5dGVTdHJpbmcoQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoIlRFU1RfQ09OVEVOVCIpKTsKKyAgICBEYXRhRmlsZSBmaWxlID0KKyAgICAgICAgTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGVJZCIsIDApLnRvQnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaW5saW5lZmlsZToxMjMiKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIGFzc2VydFRoYXQoc2ZtLnJlc2VydmVGaWxlRW50cnkobmV3RmlsZUtleSkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIEZpbGUgb25EZXZpY2VGaWxlID0gc2ltdWxhdGVEb3dubG9hZChmaWxlLCBnZXRMYXN0RmlsZU5hbWUoKSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBjaGFuZ2VGaWxlU3RhdHVzQXMobmV3RmlsZUtleSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSk7CisKKyAgICAvLyBGaWxlIGlzIGFscmVhZHkgZG93bmxvYWRlZCwgc28gd2Ugc2hvdWxkIHJldHVybiBlYXJseQorICAgIHNmbS5zdGFydEltcG9ydChHUk9VUF9LRVksIGZpbGUsIG5ld0ZpbGVLZXksIERPV05MT0FEX0NPTkRJVElPTlMsIGlubGluZVNvdXJjZSkuZ2V0KCk7CisgICAgb25EZXZpY2VGaWxlLmRlbGV0ZSgpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZGVyLCB0aW1lcygwKSkuc3RhcnRDb3B5aW5nKGFueSgpLCBhbnkoKSwgYW55SW50KCksIGFueSgpLCBhbnkoKSwgYW55KCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFN0YXJ0SW1wb3J0X3doZW5VbnJlc2VydmVkRW50cnlfdGhyb3dzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRmlsZVNvdXJjZSBpbmxpbmVTb3VyY2UgPSBGaWxlU291cmNlLm9mQnl0ZVN0cmluZyhCeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgiVEVTVF9DT05URU5UIikpOworICAgIERhdGFGaWxlIGZpbGUgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJpbmxpbmVmaWxlOjEyMyIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4ID0KKyAgICAgICAgQXNzZXJ0LmFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgc2ZtLnN0YXJ0SW1wb3J0KEdST1VQX0tFWSwgZmlsZSwgbmV3RmlsZUtleSwgRE9XTkxPQURfQ09ORElUSU9OUywgaW5saW5lU291cmNlKQorICAgICAgICAgICAgICAgICAgICAuZ2V0KCkpOworCisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkZXggPSAoRG93bmxvYWRFeGNlcHRpb24pIGV4LmdldENhdXNlKCk7CisKKyAgICBhc3NlcnRUaGF0KGRleC5nZXREb3dubG9hZFJlc3VsdENvZGUoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZFJlc3VsdENvZGUuU0hBUkVEX0ZJTEVfTk9UX0ZPVU5EX0VSUk9SKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RTdGFydEltcG9ydF93aGVuTm90SW5saW5lRmlsZVVybFNjaGVtZV90aHJvd3MoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBGaWxlU291cmNlIGlubGluZVNvdXJjZSA9IEZpbGVTb3VyY2Uub2ZCeXRlU3RyaW5nKEJ5dGVTdHJpbmcuY29weUZyb21VdGY4KCJURVNUX0NPTlRFTlQiKSk7CisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4ID0KKyAgICAgICAgQXNzZXJ0LmFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgc2ZtLnN0YXJ0SW1wb3J0KEdST1VQX0tFWSwgZmlsZSwgbmV3RmlsZUtleSwgRE9XTkxPQURfQ09ORElUSU9OUywgaW5saW5lU291cmNlKQorICAgICAgICAgICAgICAgICAgICAuZ2V0KCkpOworCisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkZXggPSAoRG93bmxvYWRFeGNlcHRpb24pIGV4LmdldENhdXNlKCk7CisgICAgYXNzZXJ0VGhhdChkZXguZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpCisgICAgICAgIC5pc0VxdWFsVG8oRG93bmxvYWRSZXN1bHRDb2RlLklOVkFMSURfSU5MSU5FX0ZJTEVfVVJMX1NDSEVNRSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0Tm90aWZ5Q3VycmVudFNpemVfcGFydGlhbERvd25sb2FkRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIGFzc2VydFRoYXQoc2ZtLnJlc2VydmVGaWxlRW50cnkobmV3RmlsZUtleSkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgLy8gRG93bmxvYWQgdGhlIGZpbGUsIGJ1dCBkbyBub3QgdXBkYXRlIHNoYXJlZCBwcmVmcyB0byBzYXkgaXQgaXMgZG93bmxvYWRlZC4KKyAgICBGaWxlIG9uRGV2aWNlRmlsZSA9IHNpbXVsYXRlRG93bmxvYWQoZmlsZSwgZ2V0TGFzdEZpbGVOYW1lKCksIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgVXJpIGZpbGVVcmkgPSBzZm0uZ2V0T25EZXZpY2VVcmkobmV3RmlsZUtleSkuZ2V0KCk7CisKKyAgICB3aGVuKGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKEdST1VQX0tFWSkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRklMRV9HUk9VUCkpOworICAgIHdoZW4obW9ja0Rvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIGVxKEdST1VQX0tFWSksCisgICAgICAgICAgICBlcShWRVJTSU9OX05VTUJFUiksCisgICAgICAgICAgICBlcShCVUlMRF9JRCksCisgICAgICAgICAgICBlcShmaWxlVXJpKSwKKyAgICAgICAgICAgIGVxKGZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpKSwKKyAgICAgICAgICAgIGVxKGZpbGUuZ2V0Qnl0ZVNpemUoKSksCisgICAgICAgICAgICBlcShET1dOTE9BRF9DT05ESVRJT05TKSwKKyAgICAgICAgICAgIGlzQShEb3dubG9hZGVyQ2FsbGJhY2tJbXBsLmNsYXNzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55TGlzdCgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworCisgICAgc2ZtLnN0YXJ0RG93bmxvYWQoCisgICAgICAgICAgICBHUk9VUF9LRVksCisgICAgICAgICAgICBmaWxlLAorICAgICAgICAgICAgbmV3RmlsZUtleSwKKyAgICAgICAgICAgIERPV05MT0FEX0NPTkRJVElPTlMsCisgICAgICAgICAgICBUUkFGRklDX1RBRywKKyAgICAgICAgICAgIC8qZXh0cmFIdHRwSGVhZGVycyA9ICovIEltbXV0YWJsZUxpc3Qub2YoKSkKKyAgICAgICAgLmdldCgpOworCisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0gc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKG5ld0ZpbGVLZXkpLmdldCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZS5nZXRGaWxlU3RhdHVzKCkpLmlzRXF1YWxUbyhGaWxlU3RhdHVzLkRPV05MT0FEX0lOX1BST0dSRVNTKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTW9uaXRvcikubm90aWZ5Q3VycmVudEZpbGVTaXplKFRFU1RfR1JPVVAsIG9uRGV2aWNlRmlsZS5sZW5ndGgoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0RG9udERlbGV0ZVVuc3Vic2NyaWJlZEZpbGVzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZGF0YWZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShkYXRhZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBhc3NlcnRUaGF0KHNmbS5yZXNlcnZlRmlsZUVudHJ5KG5ld0ZpbGVLZXkpLmdldCgpKS5pc1RydWUoKTsKKworICAgIC8vICJkb3dubG9hZCIgdGhlIGZpbGUgYW5kIHVwZGF0ZSBzaGFyZWRQcmVmcworICAgIEZpbGUgb25EZXZpY2VGaWxlID0KKyAgICAgICAgc2ltdWxhdGVEb3dubG9hZChkYXRhZmlsZSwgZ2V0TGFzdEZpbGVOYW1lKCksIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgY2hhbmdlRmlsZVN0YXR1c0FzKG5ld0ZpbGVLZXksIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpOworCisgICAgYXNzZXJ0VGhhdChvbkRldmljZUZpbGUuZXhpc3RzKCkpLmlzVHJ1ZSgpOworICAgIFVyaSB1cmkgPSBzZm0uZ2V0T25EZXZpY2VVcmkobmV3RmlsZUtleSkuZ2V0KCk7CisKKyAgICAvLyBFbnN1cmUgdGhhdCBkZXJlZ2lzdGVyIGhhcyBhY3R1YWxseSBkZWxldGVkIHRoZSBmaWxlIG9uIGRpc2suCisgICAgYXNzZXJ0VGhhdChzZm0ucmVtb3ZlRmlsZUVudHJ5KG5ld0ZpbGVLZXkpLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChuZXdGaWxlS2V5KS5nZXQoKSkuaXNOdWxsKCk7CisgICAgLy8gVGhlIGZpbGUgc2hvdWxkIG5vdCBiZSBkZWxldGVkIGJ5IHRoZSBTRk0gYmVjYXVzZSBkZWxldGlvbiBpcyBoYW5kbGVkIGJ5IEV4cGlyYXRpb25IYW5kbGVyLgorICAgIGFzc2VydFRoYXQob25EZXZpY2VGaWxlLmV4aXN0cygpKS5pc1RydWUoKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRlcikuc3RvcERvd25sb2FkaW5nKHVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0U3RhcnREb3dubG9hZF93aGVuSW5saW5lRmlsZVVybFNjaGVtZV9mYWlscygpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIGlubGluZUZpbGUgPQorICAgICAgICBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiaW5saW5lRmlsZUlkIiwgMCkudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJpbmxpbmVmaWxlOmFiYyIpCisgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oImFiYyIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShpbmxpbmVGaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4ID0KKyAgICAgICAgQXNzZXJ0LmFzc2VydFRocm93cygKKyAgICAgICAgICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgc2ZtLnN0YXJ0RG93bmxvYWQoCisgICAgICAgICAgICAgICAgICAgICAgICBHUk9VUF9LRVksCisgICAgICAgICAgICAgICAgICAgICAgICBpbmxpbmVGaWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgbmV3RmlsZUtleSwKKyAgICAgICAgICAgICAgICAgICAgICAgIERPV05MT0FEX0NPTkRJVElPTlMsCisgICAgICAgICAgICAgICAgICAgICAgICBUUkFGRklDX1RBRywKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGV4dHJhSHR0cEhlYWRlcnMgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoKSk7CisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkZXggPSAoRG93bmxvYWRFeGNlcHRpb24pIGV4LmdldENhdXNlKCk7CisgICAgYXNzZXJ0VGhhdChkZXguZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpCisgICAgICAgIC5pc0VxdWFsVG8oRG93bmxvYWRSZXN1bHRDb2RlLklOVkFMSURfSU5MSU5FX0ZJTEVfVVJMX1NDSEVNRSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0U3RhcnREb3dubG9hZF91bnN1YnNjcmliZWRGaWxlKCkgeworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBleCA9CisgICAgICAgIEFzc2VydC5hc3NlcnRUaHJvd3MoCisgICAgICAgICAgICBFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsCisgICAgICAgICAgICAoKSAtPgorICAgICAgICAgICAgICAgIHNmbS5zdGFydERvd25sb2FkKAorICAgICAgICAgICAgICAgICAgICAgICAgR1JPVVBfS0VZLAorICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZpbGVLZXksCisgICAgICAgICAgICAgICAgICAgICAgICBET1dOTE9BRF9DT05ESVRJT05TLAorICAgICAgICAgICAgICAgICAgICAgICAgVFJBRkZJQ19UQUcsCisgICAgICAgICAgICAgICAgICAgICAgICAvKmV4dHJhSHR0cEhlYWRlcnMgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoKSk7CisgICAgYXNzZXJ0VGhhdChleCkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNNZXNzYWdlVGhhdCgpLmNvbnRhaW5zKCJTSEFSRURfRklMRV9OT1RfRk9VTkRfRVJST1IiKTsKKworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tEb3dubG9hZGVyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RTdGFydERvd25sb2FkX25ld0ZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZSBmaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGVJZCIsIDApOworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisKKyAgICBhc3NlcnRUaGF0KHNmbS5yZXNlcnZlRmlsZUVudHJ5KG5ld0ZpbGVLZXkpLmdldCgpKS5pc1RydWUoKTsKKyAgICBVcmkgZmlsZVVyaSA9IHNmbS5nZXRPbkRldmljZVVyaShuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICB3aGVuKGZpbGVHcm91cHNNZXRhZGF0YS5yZWFkKEdST1VQX0tFWSkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUoRklMRV9HUk9VUCkpOworICAgIHdoZW4obW9ja0Rvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIGVxKEdST1VQX0tFWSksCisgICAgICAgICAgICBlcShWRVJTSU9OX05VTUJFUiksCisgICAgICAgICAgICBlcShCVUlMRF9JRCksCisgICAgICAgICAgICBlcShmaWxlVXJpKSwKKyAgICAgICAgICAgIGVxKGZpbGUuZ2V0VXJsVG9Eb3dubG9hZCgpKSwKKyAgICAgICAgICAgIGVxKGZpbGUuZ2V0Qnl0ZVNpemUoKSksCisgICAgICAgICAgICBlcShET1dOTE9BRF9DT05ESVRJT05TKSwKKyAgICAgICAgICAgIGlzQShEb3dubG9hZGVyQ2FsbGJhY2tJbXBsLmNsYXNzKSwKKyAgICAgICAgICAgIGFueUludCgpLAorICAgICAgICAgICAgYW55TGlzdCgpKSkKKyAgICAgICAgLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworCisgICAgc2ZtLnN0YXJ0RG93bmxvYWQoCisgICAgICAgICAgICBHUk9VUF9LRVksCisgICAgICAgICAgICBmaWxlLAorICAgICAgICAgICAgbmV3RmlsZUtleSwKKyAgICAgICAgICAgIERPV05MT0FEX0NPTkRJVElPTlMsCisgICAgICAgICAgICBUUkFGRklDX1RBRywKKyAgICAgICAgICAgIC8qIGV4dHJhSHR0cEhlYWRlcnMgPSAqLyBJbW11dGFibGVMaXN0Lm9mKCkpCisgICAgICAgIC5nZXQoKTsKKworICAgIFNoYXJlZEZpbGUgc2hhcmVkRmlsZSA9IHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUuZ2V0RmlsZVN0YXR1cygpKS5pc0VxdWFsVG8oRmlsZVN0YXR1cy5ET1dOTE9BRF9JTl9QUk9HUkVTUyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0U3RhcnREb3dubG9hZF9kb3dubG9hZGVkRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIGFzc2VydFRoYXQoc2ZtLnJlc2VydmVGaWxlRW50cnkobmV3RmlsZUtleSkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIEZpbGUgb25EZXZpY2VGaWxlID0gc2ltdWxhdGVEb3dubG9hZChmaWxlLCBnZXRMYXN0RmlsZU5hbWUoKSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBjaGFuZ2VGaWxlU3RhdHVzQXMobmV3RmlsZUtleSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSk7CisKKyAgICAvLyBUaGUgZmlsZSBpcyBhbHJlYWR5IGRvd25sb2FkZWQsIHNvIHdlIHNob3VsZCBqdXN0IHJldHVybiBET1dOTE9BREVELgorICAgIHNmbS5zdGFydERvd25sb2FkKAorICAgICAgICAgICAgR1JPVVBfS0VZLAorICAgICAgICAgICAgZmlsZSwKKyAgICAgICAgICAgIG5ld0ZpbGVLZXksCisgICAgICAgICAgICBET1dOTE9BRF9DT05ESVRJT05TLAorICAgICAgICAgICAgVFJBRkZJQ19UQUcsCisgICAgICAgICAgICAvKiBleHRyYUh0dHBIZWFkZXJzID0gKi8gSW1tdXRhYmxlTGlzdC5vZigpKQorICAgICAgICAuZ2V0KCk7CisgICAgb25EZXZpY2VGaWxlLmRlbGV0ZSgpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZE1vbml0b3IpLm5vdGlmeUN1cnJlbnRGaWxlU2l6ZShURVNUX0dST1VQLCBmaWxlLmdldEJ5dGVTaXplKCkpOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tEb3dubG9hZGVyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RWZXJpZnlEb3dubG9hZF9ub25FeGlzdGVudEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZSBmaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGVJZCIsIDApOworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBBc3NlcnQuYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc2ZtLmdldEZpbGVTdGF0dXMobmV3RmlsZUtleSkuZ2V0KCkpOworICAgIGFzc2VydFRoYXQoZXgpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihTaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbi5jbGFzcyk7CisgICAgZXggPSBBc3NlcnQuYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc2ZtLmdldE9uRGV2aWNlVXJpKG5ld0ZpbGVLZXkpLmdldCgpKTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24uY2xhc3MpOworCisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0Rvd25sb2FkZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFZlcmlmeURvd25sb2FkX2ZpbGVEb3dubG9hZGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgYXNzZXJ0VGhhdChzZm0ucmVzZXJ2ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgc2ltdWxhdGVEb3dubG9hZChmaWxlLCBnZXRMYXN0RmlsZU5hbWUoKSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBjaGFuZ2VGaWxlU3RhdHVzQXMobmV3RmlsZUtleSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSk7CisKKyAgICAvLyBWZXJpZnlEb3dubG9hZCBzaG91bGQgdXBkYXRlIHRoZSBvbkRldmljZVVyaSBmaWVsZHMgZm9yIHN0b3JlZEZpbGUuCisgICAgYXNzZXJ0VGhhdChzZm0uZ2V0RmlsZVN0YXR1cyhuZXdGaWxlS2V5KS5nZXQoKSkuaXNFcXVhbFRvKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFZlcmlmeURvd25sb2FkX2Rvd25sb2FkTm90QXR0ZW1wdGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgYXNzZXJ0VGhhdChzZm0ucmVzZXJ2ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBhc3NlcnRUaGF0KHNmbS5nZXRGaWxlU3RhdHVzKG5ld0ZpbGVLZXkpLmdldCgpKS5pc0VxdWFsVG8oRmlsZVN0YXR1cy5TVUJTQ1JJQkVEKTsKKworICAgIC8vIGdldE9uRGV2aWNlVXJpIHdpbGwgcG9wdWxhdGUgdGhlIG9uRGV2aWNlVXJpIGV2ZW4gZG93bmxvYWQgd2FzIG5vdCBhdHRlbXB0ZWQuCisgICAgYXNzZXJ0VGhhdChzZm0uZ2V0T25EZXZpY2VVcmkobmV3RmlsZUtleSkudG9TdHJpbmcoKSkuaXNOb3RFbXB0eSgpOworCisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0Rvd25sb2FkZXIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFZlcmlmeURvd25sb2FkX2FscmVhZHlEb3dubG9hZGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgYXNzZXJ0VGhhdChzZm0ucmVzZXJ2ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgRmlsZSBvbkRldmljZUZpbGUgPSBzaW11bGF0ZURvd25sb2FkKGZpbGUsIGdldExhc3RGaWxlTmFtZSgpLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIGNoYW5nZUZpbGVTdGF0dXNBcyhuZXdGaWxlS2V5LCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKTsKKworICAgIGFzc2VydFRoYXQoc2ZtLmdldEZpbGVTdGF0dXMobmV3RmlsZUtleSkuZ2V0KCkpLmlzRXF1YWxUbyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKTsKKyAgICBhc3NlcnRUaGF0KHNmbS5nZXRPbkRldmljZVVyaShuZXdGaWxlS2V5KS5nZXQoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuZnJvbUZpbGUob25EZXZpY2VGaWxlKS5idWlsZCgpKTsKKworICAgIG9uRGV2aWNlRmlsZS5kZWxldGUoKTsKKyAgICB2ZXJpZnlOb0ludGVyYWN0aW9ucyhtb2NrRG93bmxvYWRlcik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBmaW5kTm9EZWx0YUZpbGVfd2l0aE5vQmFzZUZpbGVPbkRldmljZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZVdpdGhEZWx0YUZpbGUoImZpbGVJZCIsIDAsIDMpOworICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBzZm0uZmluZEZpcnN0RGVsdGFGaWxlV2l0aEJhc2VGaWxlRG93bmxvYWRlZChmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpCisgICAgICAgICAgICAgICAgLmdldCgpKQorICAgICAgICAuaXNOdWxsKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBmaW5kRXhwZWN0ZWREZWx0YUZpbGVfd2l0aERpZmZlcmVudFJlYWRlckJhc2VGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlV2l0aERlbHRhRmlsZSgiZmlsZUlkIiwgMCwgMyk7CisgICAgbWFya0Jhc2VGaWxlRG93bmxvYWRlZCgKKyAgICAgICAgZmlsZS5nZXREZWx0YUZpbGUoMSkuZ2V0QmFzZUZpbGUoKS5nZXRDaGVja3N1bSgpLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIGFzc2VydFRoYXQoCisgICAgICAgICAgICBzZm0uZmluZEZpcnN0RGVsdGFGaWxlV2l0aEJhc2VGaWxlRG93bmxvYWRlZCgKKyAgICAgICAgICAgICAgICAgICAgZmlsZSwgQWxsb3dlZFJlYWRlcnMuT05MWV9HT09HTEVfUExBWV9TRVJWSUNFUykKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGZpbmROb0RlbHRhRmlsZV93aGVuRGVjb2Rlck5vdFN1cHBvcnRlZCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGRlbHRhRGVjb2RlciA9CisgICAgICAgIE9wdGlvbmFsLm9mKAorICAgICAgICAgICAgbmV3IERlbHRhRGVjb2RlcigpIHsKKyAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgIHB1YmxpYyB2b2lkIGRlY29kZShVcmkgYmFzZVVyaSwgVXJpIGRlbHRhVXJpLCBVcmkgdGFyZ2V0VXJpKSB7CisgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCJObyBkZWx0YSBkZWNvZGVyIHByb3ZpZGVkLiIpOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgIHB1YmxpYyBEaWZmRGVjb2RlciBnZXREZWNvZGVyTmFtZSgpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gRGlmZkRlY29kZXIuVU5TUEVDSUZJRUQ7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0pOworICAgIHNmbSA9CisgICAgICAgIG5ldyBTaGFyZWRGaWxlTWFuYWdlcigKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLAorICAgICAgICAgICAgZmlsZVN0b3JhZ2UsCisgICAgICAgICAgICBtb2NrRG93bmxvYWRlciwKKyAgICAgICAgICAgIGRlbHRhRGVjb2RlciwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZE1vbml0b3IpLAorICAgICAgICAgICAgZXZlbnRMb2dnZXIsCisgICAgICAgICAgICBmbGFncywKKyAgICAgICAgICAgIGZpbGVHcm91cHNNZXRhZGF0YSwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgQ09OVFJPTF9FWEVDVVRPUik7CisKKyAgICBEYXRhRmlsZSBmaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGVXaXRoRGVsdGFGaWxlKCJmaWxlSWQiLCAwLCAzKTsKKyAgICBtYXJrQmFzZUZpbGVEb3dubG9hZGVkKAorICAgICAgICBmaWxlLmdldERlbHRhRmlsZSgxKS5nZXRCYXNlRmlsZSgpLmdldENoZWNrc3VtKCksIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgRGVsdGFGaWxlIGRlbHRhRmlsZSA9CisgICAgICAgIHNmbS5maW5kRmlyc3REZWx0YUZpbGVXaXRoQmFzZUZpbGVEb3dubG9hZGVkKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUykuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChkZWx0YUZpbGUpLmlzTnVsbCgpOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIG1hcmtCYXNlRmlsZURvd25sb2FkZWQoU3RyaW5nIGNoZWNrc3VtLCBBbGxvd2VkUmVhZGVycyBhbGxvd2VkUmVhZGVycykKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIE5ld0ZpbGVLZXkgZmlsZUtleSA9CisgICAgICAgIE5ld0ZpbGVLZXkubmV3QnVpbGRlcigpLnNldENoZWNrc3VtKGNoZWNrc3VtKS5zZXRBbGxvd2VkUmVhZGVycyhhbGxvd2VkUmVhZGVycykuYnVpbGQoKTsKKyAgICBhc3NlcnRUaGF0KHNmbS5yZXNlcnZlRmlsZUVudHJ5KGZpbGVLZXkpLmdldCgpKS5pc1RydWUoKTsKKyAgICBjaGFuZ2VGaWxlU3RhdHVzQXMoZmlsZUtleSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0Q2xlYXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgdHdvIGZpbGVzLCBvbmUgZG93bmxvYWRlZCBhbmQgdGhlIG90aGVyIGN1cnJlbnRseSBiZWluZyBkb3dubG9hZGVkLgorICAgIERhdGFGaWxlIGRvd25sb2FkZWRGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGUiLCAwKTsKKyAgICBEYXRhRmlsZSByZWdpc3RlcmVkRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJyZWdpc3RlcmVkLWZpbGUiLCAwKTsKKworICAgIE5ld0ZpbGVLZXkgZG93bmxvYWRlZEtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGRvd25sb2FkZWRGaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIE5ld0ZpbGVLZXkgcmVnaXN0ZXJlZEtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKHJlZ2lzdGVyZWRGaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgYXNzZXJ0VGhhdChzZm0ucmVzZXJ2ZUZpbGVFbnRyeShkb3dubG9hZGVkS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgRmlsZSBvbkRldmljZVB1YmxpY0ZpbGUgPQorICAgICAgICBzaW11bGF0ZURvd25sb2FkKGRvd25sb2FkZWRGaWxlLCBnZXRMYXN0RmlsZU5hbWUoKSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBjaGFuZ2VGaWxlU3RhdHVzQXMoZG93bmxvYWRlZEtleSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSk7CisKKyAgICBhc3NlcnRUaGF0KHNmbS5yZXNlcnZlRmlsZUVudHJ5KHJlZ2lzdGVyZWRLZXkpLmdldCgpKS5pc1RydWUoKTsKKworICAgIGFzc2VydFRoYXQoc2ZtLmdldE9uRGV2aWNlVXJpKGRvd25sb2FkZWRLZXkpLmdldCgpKQorICAgICAgICAuaXNFcXVhbFRvKEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5mcm9tRmlsZShvbkRldmljZVB1YmxpY0ZpbGUpLmJ1aWxkKCkpOworICAgIGFzc2VydFRoYXQob25EZXZpY2VQdWJsaWNGaWxlLmV4aXN0cygpKS5pc1RydWUoKTsKKworICAgIC8vIENsZWFyIHNob3VsZCBkZWxldGUgYWxsIGZpbGVzIGluIG91ciBkaXJlY3Rvcmllcy4KKyAgICBzZm0uY2xlYXIoKS5nZXQoKTsKKworICAgIGFzc2VydFRoYXQob25EZXZpY2VQdWJsaWNGaWxlLmV4aXN0cygpKS5pc0ZhbHNlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0Q2xlYXJfc2RrTGVzc3RoYW5SKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gU2V0IHNjZW5hcmlvOiBTREsgPCBSLCBlbmFibGVBbmRyb2lkRmlsZVNoYXJpbmcgZmxhZyBPTgorICAgIFJlZmxlY3Rpb25IZWxwZXJzLnNldFN0YXRpY0ZpZWxkKEJ1aWxkLlZFUlNJT04uY2xhc3MsICJTREtfSU5UIiwgQnVpbGQuVkVSU0lPTl9DT0RFUy5RKTsKKworICAgIC8vIENyZWF0ZSB0d28gZmlsZXMsIG9uZSBkb3dubG9hZGVkIGFuZCB0aGUgb3RoZXIgY3VycmVudGx5IGJlaW5nIGRvd25sb2FkZWQuCisgICAgRGF0YUZpbGUgZG93bmxvYWRlZEZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZSIsIDApOworICAgIERhdGFGaWxlIHJlZ2lzdGVyZWRGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoInJlZ2lzdGVyZWQtZmlsZSIsIDApOworCisgICAgTmV3RmlsZUtleSBkb3dubG9hZGVkS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZG93bmxvYWRlZEZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgTmV3RmlsZUtleSByZWdpc3RlcmVkS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUocmVnaXN0ZXJlZEZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisKKyAgICBhc3NlcnRUaGF0KHNmbS5yZXNlcnZlRmlsZUVudHJ5KGRvd25sb2FkZWRLZXkpLmdldCgpKS5pc1RydWUoKTsKKyAgICBGaWxlIG9uRGV2aWNlUHVibGljRmlsZSA9CisgICAgICAgIHNpbXVsYXRlRG93bmxvYWQoZG93bmxvYWRlZEZpbGUsIGdldExhc3RGaWxlTmFtZSgpLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIGNoYW5nZUZpbGVTdGF0dXNBcyhkb3dubG9hZGVkS2V5LCBGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKTsKKworICAgIGFzc2VydFRoYXQoc2ZtLnJlc2VydmVGaWxlRW50cnkocmVnaXN0ZXJlZEtleSkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgYXNzZXJ0VGhhdChzZm0uZ2V0T25EZXZpY2VVcmkoZG93bmxvYWRlZEtleSkuZ2V0KCkpCisgICAgICAgIC5pc0VxdWFsVG8oQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLmZyb21GaWxlKG9uRGV2aWNlUHVibGljRmlsZSkuYnVpbGQoKSk7CisgICAgYXNzZXJ0VGhhdChvbkRldmljZVB1YmxpY0ZpbGUuZXhpc3RzKCkpLmlzVHJ1ZSgpOworCisgICAgLy8gQ2xlYXIgc2hvdWxkIGRlbGV0ZSBhbGwgZmlsZXMgaW4gb3VyIGRpcmVjdG9yaWVzLgorICAgIHNmbS5jbGVhcigpLmdldCgpOworCisgICAgYXNzZXJ0VGhhdChvbkRldmljZVB1YmxpY0ZpbGUuZXhpc3RzKCkpLmlzRmFsc2UoKTsKKyAgICB2ZXJpZnkobW9ja0JhY2tlbmQsIG5ldmVyKCkpLmRlbGV0ZUZpbGUoYW55KCkpOworICAgIHZlcmlmeShldmVudExvZ2dlciwgbmV2ZXIoKSkubG9nRXZlbnRTYW1wbGVkKDApOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdENsZWFyX3dpdGhBbmRyb2lkU2hhcmVkRmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBTZXQgc2NlbmFyaW86IFNESyA+PSBSCisgICAgUmVmbGVjdGlvbkhlbHBlcnMuc2V0U3RhdGljRmllbGQoQnVpbGQuVkVSU0lPTi5jbGFzcywgIlNES19JTlQiLCBCdWlsZC5WRVJTSU9OX0NPREVTLlIpOworCisgICAgLy8gQ3JlYXRlIHRocmVlIGZpbGVzLCBvbmUgZG93bmxvYWRlZCwgdGhlIG90aGVyIGN1cnJlbnRseSBiZWluZyBkb3dubG9hZGVkIGFuZCBvbmUgc2hhcmVkIHdpdGgKKyAgICAvLyB0aGUgQW5kcm9pZCBCbG9iIFNoYXJpbmcgU2VydmljZS4KKyAgICBEYXRhRmlsZSBkb3dubG9hZGVkRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJmaWxlIiwgLyogZmlsZUluZGV4ID0gKi8gMCk7CisgICAgRGF0YUZpbGUgcmVnaXN0ZXJlZEZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgicmVnaXN0ZXJlZC1maWxlIiwgLyogZmlsZUluZGV4ID0gKi8gMSk7CisgICAgRGF0YUZpbGUgc2hhcmVkRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJzaGFyZWQtZmlsZSIsIC8qIGZpbGVJbmRleCA9ICovIDIpOworCisgICAgTmV3RmlsZUtleSBkb3dubG9hZGVkS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZG93bmxvYWRlZEZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgTmV3RmlsZUtleSByZWdpc3RlcmVkS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUocmVnaXN0ZXJlZEZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgTmV3RmlsZUtleSBzaGFyZWRGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoc2hhcmVkRmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIGFzc2VydFRoYXQoc2ZtLnJlc2VydmVGaWxlRW50cnkoZG93bmxvYWRlZEtleSkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIEZpbGUgb25EZXZpY2VQdWJsaWNGaWxlID0KKyAgICAgICAgc2ltdWxhdGVEb3dubG9hZChkb3dubG9hZGVkRmlsZSwgZ2V0TGFzdEZpbGVOYW1lKCksIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgY2hhbmdlRmlsZVN0YXR1c0FzKGRvd25sb2FkZWRLZXksIEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpOworCisgICAgYXNzZXJ0VGhhdChzZm0ucmVzZXJ2ZUZpbGVFbnRyeShyZWdpc3RlcmVkS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBhc3NlcnRUaGF0KHNmbS5yZXNlcnZlRmlsZUVudHJ5KHNoYXJlZEZpbGVLZXkpLmdldCgpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgc2ZtLnNldEFuZHJvaWRTaGFyZWREb3dubG9hZGVkRmlsZUVudHJ5KAorICAgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlS2V5LAorICAgICAgICAgICAgICAgICAgICBzaGFyZWRGaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwKKyAgICAgICAgICAgICAgICAgICAgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUykKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKyAgICBVcmkgYWxsTGVhc2VzVXJpID0gRGlyZWN0b3J5VXRpbC5nZXRCbG9iU3RvcmVBbGxMZWFzZXNVcmkoY29udGV4dCk7CisKKyAgICBhc3NlcnRUaGF0KHNmbS5nZXRPbkRldmljZVVyaShkb3dubG9hZGVkS2V5KS5nZXQoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhBbmRyb2lkVXJpLmJ1aWxkZXIoY29udGV4dCkuZnJvbUZpbGUob25EZXZpY2VQdWJsaWNGaWxlKS5idWlsZCgpKTsKKyAgICBhc3NlcnRUaGF0KG9uRGV2aWNlUHVibGljRmlsZS5leGlzdHMoKSkuaXNUcnVlKCk7CisKKyAgICAvLyBDbGVhciBzaG91bGQgZGVsZXRlIGFsbCBmaWxlcyBpbiBvdXIgZGlyZWN0b3JpZXMuCisgICAgc2ZtLmNsZWFyKCkuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KG9uRGV2aWNlUHVibGljRmlsZS5leGlzdHMoKSkuaXNGYWxzZSgpOworICAgIHZlcmlmeShtb2NrQmFja2VuZCkuZGVsZXRlRmlsZShhbGxMZWFzZXNVcmkpOworCisgICAgdmVyaWZ5KGV2ZW50TG9nZ2VyKS5sb2dFdmVudFNhbXBsZWQoMCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjYW5jZWxEb3dubG9hZF9vbkRvd25sb2FkZWRGaWxlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZG93bmxvYWRlZEZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZG93bmxvYWRlZC1maWxlIiwgMCk7CisgICAgTmV3RmlsZUtleSBkb3dubG9hZGVkS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZG93bmxvYWRlZEZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisKKyAgICBhc3NlcnRUaGF0KHNmbS5yZXNlcnZlRmlsZUVudHJ5KGRvd25sb2FkZWRLZXkpLmdldCgpKS5pc1RydWUoKTsKKyAgICBjaGFuZ2VGaWxlU3RhdHVzQXMoZG93bmxvYWRlZEtleSwgRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSk7CisKKyAgICAvLyBDYWxsaW5nIGNhbmNlbERvd25sb2FkIG9uIGRvd25sb2FkZWQgZmlsZSBpcyBhIG5vLW9wLgorICAgIHNmbS5jYW5jZWxEb3dubG9hZChkb3dubG9hZGVkS2V5KS5nZXQoKTsKKworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tEb3dubG9hZGVyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNhbmNlbERvd25sb2FkX29uUmVnaXN0ZXJlZEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZSByZWdpc3RlcmVkRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJyZWdpc3RlcmVkLWZpbGUiLCAwKTsKKyAgICBOZXdGaWxlS2V5IHJlZ2lzdGVyZWRLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShyZWdpc3RlcmVkRmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIGFzc2VydFRoYXQoc2ZtLnJlc2VydmVGaWxlRW50cnkocmVnaXN0ZXJlZEtleSkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgLy8gQ2FsbGluZyBjYW5jZWxEb3dubG9hZCBvbiByZWdpc3RlcmVkIGZpbGUgd2lsbCBzdG9wIHRoZSBkb3dubG9hZC4KKyAgICBzZm0uY2FuY2VsRG93bmxvYWQocmVnaXN0ZXJlZEtleSkuZ2V0KCk7CisKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPSBzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQocmVnaXN0ZXJlZEtleSkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlKS5pc05vdE51bGwoKTsKKyAgICBVcmkgb25EZXZpY2VVcmkgPQorICAgICAgICBEaXJlY3RvcnlVdGlsLmdldE9uRGV2aWNlVXJpKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIHJlZ2lzdGVyZWRLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKSwKKyAgICAgICAgICAgIHNoYXJlZEZpbGUuZ2V0RmlsZU5hbWUoKSwKKyAgICAgICAgICAgIHJlZ2lzdGVyZWRGaWxlLmdldENoZWNrc3VtKCksCisgICAgICAgICAgICBtb2NrU2lsZW50RmVlZGJhY2ssCisgICAgICAgICAgICAvKiBpbnN0YW5jZUlkPSAqLyBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIGZhbHNlKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkZXIpLnN0b3BEb3dubG9hZGluZyhvbkRldmljZVVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2hhcmVkRmlsZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlIGZpbGUgPSBNZGRUZXN0VXRpbC5jcmVhdGVEYXRhRmlsZSgiZmlsZUlkIiwgLyogZmlsZUluZGV4ID0gKi8gMCk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoZmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKworICAgIGFzc2VydFRoYXQoc2ZtLnJlc2VydmVGaWxlRW50cnkobmV3RmlsZUtleSkuZ2V0KCkpLmlzVHJ1ZSgpOworCisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0gc2ZtLmdldFNoYXJlZEZpbGUobmV3RmlsZUtleSkuZ2V0KCk7CisgICAgU2hhcmVkRmlsZSBleHBlY3RlZFNoYXJlZEZpbGUgPSBzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSkuZ2V0KCk7CisKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZSkuaXNFcXVhbFRvKGV4cGVjdGVkU2hhcmVkRmlsZSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0R2V0U2hhcmVkRmlsZV9ub25FeGlzdGVudEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZSBmaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGVJZCIsIDApOworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBBc3NlcnQuYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gc2ZtLmdldFNoYXJlZEZpbGUobmV3RmlsZUtleSkuZ2V0KCkpOworICAgIGFzc2VydFRoYXQoZXgpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihTaGFyZWRGaWxlTWlzc2luZ0V4Y2VwdGlvbi5jbGFzcyk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlTWF4RXhwaXJhdGlvbkRhdGVTZWNzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgYXNzZXJ0VGhhdChzZm0ucmVzZXJ2ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlQmVmb3JlVXBkYXRlID0gc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKG5ld0ZpbGVLZXkpLmdldCgpOworICAgIFNoYXJlZEZpbGUgZXhwZWN0ZWRTaGFyZWRGaWxlQWZ0ZXJVcGRhdGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoc2hhcmVkRmlsZUJlZm9yZVVwZGF0ZSkKKyAgICAgICAgICAgIC5zZXRNYXhFeHBpcmF0aW9uRGF0ZVNlY3MoRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUykKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlQmVmb3JlVXBkYXRlKS5pc05vdE51bGwoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVCZWZvcmVVcGRhdGUpLmlzTm90RXF1YWxUbyhleHBlY3RlZFNoYXJlZEZpbGVBZnRlclVwZGF0ZSk7CisKKyAgICAvLyB1cGRhdGVNYXhFeHBpcmF0aW9uRGF0ZVNlY3MgdXBkYXRlcyBtYXhFeHBpcmF0aW9uRGF0ZVNlY3MKKyAgICBhc3NlcnRUaGF0KHNmbS51cGRhdGVNYXhFeHBpcmF0aW9uRGF0ZVNlY3MobmV3RmlsZUtleSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUykuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGVBZnRlclVwZGF0ZSA9IHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVBZnRlclVwZGF0ZSkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlQWZ0ZXJVcGRhdGUpLmlzRXF1YWxUbyhleHBlY3RlZFNoYXJlZEZpbGVBZnRlclVwZGF0ZSk7CisKKyAgICAvLyB1cGRhdGVNYXhFeHBpcmF0aW9uRGF0ZVNlY3MgZG9lc24ndCB1cGRhdGUgbWF4RXhwaXJhdGlvbkRhdGVTZWNzCisgICAgYXNzZXJ0VGhhdCgKKyAgICAgICAgICAgIHNmbS51cGRhdGVNYXhFeHBpcmF0aW9uRGF0ZVNlY3MobmV3RmlsZUtleSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUyAtIDEpLmdldCgpKQorICAgICAgICAuaXNUcnVlKCk7CisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlQWZ0ZXJTZWNvbmRVcGRhdGUgPSBzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlQWZ0ZXJTZWNvbmRVcGRhdGUpLmlzTm90TnVsbCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZUFmdGVyU2Vjb25kVXBkYXRlKS5pc0VxdWFsVG8oZXhwZWN0ZWRTaGFyZWRGaWxlQWZ0ZXJVcGRhdGUpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFVwZGF0ZU1heEV4cGlyYXRpb25EYXRlU2Vjc19ub25FeGlzdGVudEZpbGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZSBmaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImZpbGVJZCIsIDApOworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPQorICAgICAgICBBc3NlcnQuYXNzZXJ0VGhyb3dzKAorICAgICAgICAgICAgRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLAorICAgICAgICAgICAgKCkgLT4KKyAgICAgICAgICAgICAgICBzZm0udXBkYXRlTWF4RXhwaXJhdGlvbkRhdGVTZWNzKG5ld0ZpbGVLZXksIEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpLmdldCgpKTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoU2hhcmVkRmlsZU1pc3NpbmdFeGNlcHRpb24uY2xhc3MpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFNldEFuZHJvaWRTaGFyZWREb3dubG9hZGVkRmlsZUVudHJ5KCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBTaGFyZWRGaWxlIGV4cGVjdGVkU2hhcmVkRmlsZUFmdGVyVXBkYXRlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImFuZHJvaWRfc2hhcmVkXyIgKyBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSkKKyAgICAgICAgICAgIC5zZXRBbmRyb2lkU2hhcmVkKHRydWUpCisgICAgICAgICAgICAuc2V0TWF4RXhwaXJhdGlvbkRhdGVTZWNzKEZJTEVfR1JPVVBfRVhQSVJBVElPTl9EQVRFX1NFQ1MpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bShmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIE5ld0ZpbGVLZXkgbmV3RmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGZpbGUsIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgYXNzZXJ0VGhhdChzZm0ucmVzZXJ2ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPSBzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQobmV3RmlsZUtleSkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlKS5pc05vdE51bGwoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGUpLmlzTm90RXF1YWxUbyhleHBlY3RlZFNoYXJlZEZpbGVBZnRlclVwZGF0ZSk7CisKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgc2ZtLnNldEFuZHJvaWRTaGFyZWREb3dubG9hZGVkRmlsZUVudHJ5KAorICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUykKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKyAgICBzaGFyZWRGaWxlID0gc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKG5ld0ZpbGVLZXkpLmdldCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZSkuaXNOb3ROdWxsKCk7CisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlKS5pc0VxdWFsVG8oZXhwZWN0ZWRTaGFyZWRGaWxlQWZ0ZXJVcGRhdGUpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdE9uRGV2aWNlVXJpKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGUgZmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVNoYXJlZERhdGFGaWxlKCJmaWxlSWQiLCAwKTsKKyAgICBOZXdGaWxlS2V5IG5ld0ZpbGVLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShmaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworCisgICAgYXNzZXJ0VGhhdChzZm0ucmVzZXJ2ZUZpbGVFbnRyeShuZXdGaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICBGaWxlIG9uRGV2aWNlRmlsZSA9IHNpbXVsYXRlRG93bmxvYWQoZmlsZSwgZ2V0TGFzdEZpbGVOYW1lKCksIEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgYXNzZXJ0VGhhdChzZm0uZ2V0T25EZXZpY2VVcmkobmV3RmlsZUtleSkuZ2V0KCkpCisgICAgICAgIC5pc0VxdWFsVG8oQW5kcm9pZFVyaS5idWlsZGVyKGNvbnRleHQpLmZyb21GaWxlKG9uRGV2aWNlRmlsZSkuYnVpbGQoKSk7CisKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgc2ZtLnNldEFuZHJvaWRTaGFyZWREb3dubG9hZGVkRmlsZUVudHJ5KAorICAgICAgICAgICAgICAgICAgICBuZXdGaWxlS2V5LCBmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSwgRklMRV9HUk9VUF9FWFBJUkFUSU9OX0RBVEVfU0VDUykKKyAgICAgICAgICAgICAgICAuZ2V0KCkpCisgICAgICAgIC5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHNmbS5nZXRPbkRldmljZVVyaShuZXdGaWxlS2V5KS5nZXQoKSkKKyAgICAgICAgLmlzRXF1YWxUbygKKyAgICAgICAgICAgIEJsb2JVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRCbG9iUGFyYW1ldGVycyhmaWxlLmdldEFuZHJvaWRTaGFyaW5nQ2hlY2tzdW0oKSkuYnVpbGQoKSk7CisgIH0KKworICBwcml2YXRlIEZpbGUgc2ltdWxhdGVEb3dubG9hZChEYXRhRmlsZSBkYXRhRmlsZSwgU3RyaW5nIGZpbGVOYW1lLCBBbGxvd2VkUmVhZGVycyBhbGxvd2VkUmVhZGVycykKKyAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CisgICAgRmlsZSBvbkRldmljZUZpbGU7CisgICAgaWYgKGFsbG93ZWRSZWFkZXJzID09IEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUykgeworICAgICAgb25EZXZpY2VGaWxlID0gbmV3IEZpbGUocHVibGljRGlyZWN0b3J5LCBmaWxlTmFtZSk7CisgICAgfSBlbHNlIHsKKyAgICAgIG9uRGV2aWNlRmlsZSA9IG5ldyBGaWxlKHByaXZhdGVEaXJlY3RvcnksIGZpbGVOYW1lKTsKKyAgICB9CisgICAgRmlsZU91dHB1dFN0cmVhbSB3cml0ZXIgPSBuZXcgRmlsZU91dHB1dFN0cmVhbShvbkRldmljZUZpbGUpOworICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlW2RhdGFGaWxlLmdldEJ5dGVTaXplKCldOworICAgIHdyaXRlci53cml0ZShieXRlcyk7CisgICAgd3JpdGVyLmNsb3NlKCk7CisKKyAgICByZXR1cm4gb25EZXZpY2VGaWxlOworICB9CisKKyAgcHJpdmF0ZSB2b2lkIGNoYW5nZUZpbGVTdGF0dXNBcyhOZXdGaWxlS2V5IG5ld0ZpbGVLZXksIEZpbGVTdGF0dXMgZmlsZVN0YXR1cykKKyAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICBzeW5jaHJvbml6ZWQgKFNoYXJlZEZpbGVzTWV0YWRhdGEuY2xhc3MpIHsKKyAgICAgIFNoYXJlZEZpbGUgc2hhcmVkRmlsZSA9IHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChuZXdGaWxlS2V5KS5nZXQoKTsKKyAgICAgIHNoYXJlZEZpbGUgPSBzaGFyZWRGaWxlLnRvQnVpbGRlcigpLnNldEZpbGVTdGF0dXMoZmlsZVN0YXR1cykuYnVpbGQoKTsKKyAgICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS53cml0ZShuZXdGaWxlS2V5LCBzaGFyZWRGaWxlKS5nZXQoKSkuaXNUcnVlKCk7CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBTdHJpbmcgZ2V0TGFzdEZpbGVOYW1lKCkgeworICAgIFNoYXJlZFByZWZlcmVuY2VzIHNmbU1ldGFkYXRhID0KKyAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKAorICAgICAgICAgICAgY29udGV4dCwgTUREX1NIQVJFRF9GSUxFX01BTkFHRVJfTUVUQURBVEEsIE9wdGlvbmFsLmFic2VudCgpKTsKKyAgICBsb25nIGxhc3ROYW1lID0gc2ZtTWV0YWRhdGEuZ2V0TG9uZyhTaGFyZWRGaWxlTWFuYWdlci5QUkVGU19LRVlfTkVYVF9GSUxFX05BTUUsIDEpIC0gMTsKKyAgICByZXR1cm4gU2hhcmVkRmlsZU1hbmFnZXIuRklMRV9OQU1FX1BSRUZJWCArIGxhc3ROYW1lOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvU2hhcmVkRmlsZXNNZXRhZGF0YVRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9TaGFyZWRGaWxlc01ldGFkYXRhVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjNWUxMzkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvU2hhcmVkRmlsZXNNZXRhZGF0YVRlc3QuamF2YQpAQCAtMCwwICsxLDU3OCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWw7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQuY29udGVudC5TaGFyZWRQcmVmZXJlbmNlczsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuU2lsZW50RmVlZGJhY2s7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5TeW5jaHJvbm91c0ZpbGVTdG9yYWdlOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuYmFja2VuZHMuQW5kcm9pZEZpbGVCYWNrZW5kOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1pZ3JhdGlvbnMuRmlsZUtleVZlcnNpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5FdmVudExvZ2dlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLlNoYXJlZEZpbGVzTWV0YWRhdGFVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuRmlsZUtleURlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsLlNoYXJlZFByZWZlcmVuY2VzVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLlRlc3RGbGFnczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLlRyYW5zZm9ybVByb3RvLkNvbXByZXNzVHJhbnNmb3JtOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLlRyYW5zZm9ybVByb3RvLlRyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm1zOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uRGF0YUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5EYXRhRmlsZUdyb3VwSW50ZXJuYWwuQWxsb3dlZFJlYWRlcnM7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90by5GaWxlU3RhdHVzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLk1ldGFkYXRhUHJvdG8uTmV3RmlsZUtleTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLlNoYXJlZEZpbGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5czsKK2ltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IG9yZy5qdW5pdC5BZnRlcjsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Nb2NrOworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9KVW5pdDsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvUnVsZTsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUGFyYW1ldGVyaXplZFJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUGFyYW1ldGVyaXplZFJvYm9sZWN0cmljVGVzdFJ1bm5lci5QYXJhbWV0ZXI7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlBhcmFtZXRlcml6ZWRSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuUGFyYW1ldGVyczsKKworQFJ1bldpdGgoUGFyYW1ldGVyaXplZFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBTaGFyZWRGaWxlc01ldGFkYXRhVGVzdCB7CisKKyAgcHJpdmF0ZSBlbnVtIE1ldGFkYXRhU3RvcmVJbXBsIHsKKyAgICBTUF9JTVBMLAorICB9CisKKyAgQFBhcmFtZXRlcnMobmFtZSA9ICJtZXRhZGF0YVN0b3JlSW1wbCA9IHswfSBpbnN0YW5jZUlkID0gezF9IikKKyAgcHVibGljIHN0YXRpYyBDb2xsZWN0aW9uPE9iamVjdFtdPiBwYXJhbWV0ZXJzKCkgeworICAgIHJldHVybiBBcnJheXMuYXNMaXN0KAorICAgICAgICBuZXcgT2JqZWN0W11bXSB7CisgICAgICAgICAge01ldGFkYXRhU3RvcmVJbXBsLlNQX0lNUEwsIE9wdGlvbmFsLmFic2VudCgpfSwKKyAgICAgICAgICB7TWV0YWRhdGFTdG9yZUltcGwuU1BfSU1QTCwgT3B0aW9uYWwub2YoImlkIil9LAorICAgICAgICB9KTsKKyAgfQorCisgIEBQYXJhbWV0ZXIodmFsdWUgPSAwKQorICBwdWJsaWMgTWV0YWRhdGFTdG9yZUltcGwgbWV0YWRhdGFTdG9yZUltcGw7CisKKyAgQFBhcmFtZXRlcih2YWx1ZSA9IDEpCisgIHB1YmxpYyBPcHRpb25hbDxTdHJpbmc+IGluc3RhbmNlSWQ7CisKKyAgcHJpdmF0ZSBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIHN0b3JhZ2U7CisgIHByaXZhdGUgQ29udGV4dCBjb250ZXh0OworICBwcml2YXRlIFNoYXJlZEZpbGVzTWV0YWRhdGEgc2hhcmVkRmlsZXNNZXRhZGF0YTsKKworICBwcml2YXRlIGZpbmFsIFRlc3RGbGFncyBmbGFncyA9IG5ldyBUZXN0RmxhZ3MoKTsKKyAgQE1vY2sgU2lsZW50RmVlZGJhY2sgbW9ja1NpbGVudEZlZWRiYWNrOworICBATW9jayBFdmVudExvZ2dlciBtb2NrTG9nZ2VyOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRyYW5zZm9ybXMgQ09NUFJFU1NfVFJBTlNGT1JNID0KKyAgICAgIFRyYW5zZm9ybXMubmV3QnVpbGRlcigpCisgICAgICAgICAgLmFkZFRyYW5zZm9ybShUcmFuc2Zvcm0ubmV3QnVpbGRlcigpLnNldENvbXByZXNzKENvbXByZXNzVHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKSkKKyAgICAgICAgICAuYnVpbGQoKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRXhlY3V0b3IgQ09OVFJPTF9FWEVDVVRPUiA9CisgICAgICBNb3JlRXhlY3V0b3JzLm5ld1NlcXVlbnRpYWxFeGVjdXRvcihFeGVjdXRvcnMubmV3Q2FjaGVkVGhyZWFkUG9vbCgpKTsKKworICBAUnVsZSBwdWJsaWMgZmluYWwgTW9ja2l0b1J1bGUgbW9ja3MgPSBNb2NraXRvSlVuaXQucnVsZSgpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbiB7CisKKyAgICBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKworICAgIHN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZShBcnJheXMuYXNMaXN0KEFuZHJvaWRGaWxlQmFja2VuZC5idWlsZGVyKGNvbnRleHQpLmJ1aWxkKCkpKTsKKworICAgIFNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YSBzaGFyZWRQcmVmZXJlbmNlc01ldGFkYXRhID0KKyAgICAgICAgbmV3IFNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YShjb250ZXh0LCBtb2NrU2lsZW50RmVlZGJhY2ssIGluc3RhbmNlSWQsIGZsYWdzKTsKKworICAgIHN3aXRjaCAobWV0YWRhdGFTdG9yZUltcGwpIHsKKyAgICAgIGNhc2UgU1BfSU1QTDoKKyAgICAgICAgc2hhcmVkRmlsZXNNZXRhZGF0YSA9IHNoYXJlZFByZWZlcmVuY2VzTWV0YWRhdGE7CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIE1pZ3JhdGlvbnMuY2xlYXIoY29udGV4dCk7CisgICAgTWlncmF0aW9ucy5zZXRNaWdyYXRlZFRvTmV3RmlsZUtleShjb250ZXh0LCB0cnVlKTsKKyAgfQorCisgIEBBZnRlcgorICBwdWJsaWMgdm9pZCB0ZWFyRG93bigpIHRocm93cyBFeGNlcHRpb24geworICAgIHN5bmNocm9uaXplZCAoU2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhLmNsYXNzKSB7CisgICAgICBzaGFyZWRGaWxlc01ldGFkYXRhLmNsZWFyKCkuZ2V0KCk7CisgICAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgICBTaGFyZWRQcmVmZXJlbmNlc1V0aWwuZ2V0U2hhcmVkUHJlZmVyZW5jZXMoCisgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuTUREX1NIQVJFRF9GSUxFUywgaW5zdGFuY2VJZCkKKyAgICAgICAgICAgICAgICAgIC5lZGl0KCkKKyAgICAgICAgICAgICAgICAgIC5jbGVhcigpCisgICAgICAgICAgICAgICAgICAuY29tbWl0KCkpCisgICAgICAgICAgLmlzVHJ1ZSgpOworICAgIH0KKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGluaXRfYWx3YXlzTWlncmF0ZVRvTmV3S2V5KCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24geworICAgIE1pZ3JhdGlvbnMuc2V0TWlncmF0ZWRUb05ld0ZpbGVLZXkoY29udGV4dCwgZmFsc2UpOworICAgIGZsYWdzLmZpbGVLZXlWZXJzaW9uID0gT3B0aW9uYWwub2YoRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkudmFsdWUpOworCisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLmluaXQoKS5nZXQoKSkuaXNGYWxzZSgpOworCisgICAgYXNzZXJ0VGhhdChNaWdyYXRpb25zLmlzTWlncmF0ZWRUb05ld0ZpbGVLZXkoY29udGV4dCkpLmlzVHJ1ZSgpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgd2UgYWxzbyBzZXQgdGhlIGN1cnJlbnQgZmlsZSB2ZXJzaW9uIHRvIHRoZSBsYXRlc3QgdmVyc2lvbiBpbiB0aGlzIGNhc2UuCisgICAgYXNzZXJ0VGhhdChNaWdyYXRpb25zLmdldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIG1vY2tTaWxlbnRGZWVkYmFjaykpCisgICAgICAgIC5pc0VxdWFsVG8oRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdE1pZ3JhdGVUb05ld1ZlcnNpb25fbm9WZXJzaW9uQ2hhbmdlKCkKKyAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICBmbGFncy5maWxlS2V5VmVyc2lvbiA9IE9wdGlvbmFsLm9mKEZpbGVLZXlWZXJzaW9uLk5FV19GSUxFX0tFWS52YWx1ZSk7CisKKyAgICAvLyBDcmVhdGUgdHdvIGZpbGVzLCBvbmUgZG93bmxvYWRlZCBhbmQgdGhlIG90aGVyIGN1cnJlbnRseSBiZWluZyBkb3dubG9hZGVkLgorICAgIERhdGFGaWxlIHJlZ2lzdGVyZWRGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoInJlZ2lzdGVyZWQtZmlsZSIsIDApOworICAgIERhdGFGaWxlIGRvd25sb2FkZWRGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImRvd25sb2FkZWQtZmlsZSIsIC8qIGZpbGVJbmRleCAqLyAwKTsKKworICAgIE5ld0ZpbGVLZXkgZG93bmxvYWRlZEtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGRvd25sb2FkZWRGaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIE5ld0ZpbGVLZXkgcmVnaXN0ZXJlZEtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgcmVnaXN0ZXJlZEZpbGUsIEFsbG93ZWRSZWFkZXJzLk9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMpOworCisgICAgU2hhcmVkRmlsZSByZWdpc3RlcmVkU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoInJlZ2lzdGVyZWQtZmlsZSIpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLlNVQlNDUklCRUQpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBTaGFyZWRGaWxlIGRvd25sb2FkZWRTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgiZG93bmxvYWRlZC1maWxlIikKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHN5bmNocm9uaXplZCAoU2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhLmNsYXNzKSB7CisgICAgICBhc3NlcnRUaGF0KHdyaXRlU2hhcmVkRmlsZShyZWdpc3RlcmVkS2V5LCByZWdpc3RlcmVkU2hhcmVkRmlsZSkpLmlzVHJ1ZSgpOworICAgICAgYXNzZXJ0VGhhdCh3cml0ZVNoYXJlZEZpbGUoZG93bmxvYWRlZEtleSwgZG93bmxvYWRlZFNoYXJlZEZpbGUpKS5pc1RydWUoKTsKKyAgICB9CisKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEuaW5pdCgpLmdldCgpKS5pc1RydWUoKTsKKworICAgIC8vIENoZWNrIHRoYXQgd2UgYXJlIGFibGUgdG8gcmVhZCB0aGUgZmlsZSBhZnRlciB0aGUgbWlncmF0aW9uLgorICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKHJlZ2lzdGVyZWRLZXkpLmdldCgpKS5pc0VxdWFsVG8ocmVnaXN0ZXJlZFNoYXJlZEZpbGUpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKGRvd25sb2FkZWRLZXkpLmdldCgpKS5pc0VxdWFsVG8oZG93bmxvYWRlZFNoYXJlZEZpbGUpOworCisgICAgdmVyaWZ5Tm9FcnJvckluUGRzTWlncmF0aW9uKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0TWlncmF0ZVRvTmV3VmVyc2lvbl90b0FkZERvd25sb2FkVHJhbnNmb3JtKCkKKyAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICBmbGFncy5maWxlS2V5VmVyc2lvbiA9IE9wdGlvbmFsLm9mKEZpbGVLZXlWZXJzaW9uLkFERF9ET1dOTE9BRF9UUkFOU0ZPUk0udmFsdWUpOworCisgICAgLy8gQ3JlYXRlIHR3byBmaWxlcywgb25lIGRvd25sb2FkZWQgYW5kIHRoZSBvdGhlciBjdXJyZW50bHkgYmVpbmcgZG93bmxvYWRlZC4KKyAgICBEYXRhRmlsZSByZWdpc3RlcmVkRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJyZWdpc3RlcmVkLWZpbGUiLCAwKTsKKyAgICBEYXRhRmlsZSBkb3dubG9hZGVkRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJkb3dubG9hZGVkLWZpbGUiLCAvKiBmaWxlSW5kZXggKi8gMCk7CisKKyAgICBOZXdGaWxlS2V5IGRvd25sb2FkZWRLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShkb3dubG9hZGVkRmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBOZXdGaWxlS2V5IHJlZ2lzdGVyZWRLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIHJlZ2lzdGVyZWRGaWxlLCBBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKTsKKworICAgIFNoYXJlZEZpbGUgcmVnaXN0ZXJlZFNoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJyZWdpc3RlcmVkLWZpbGUiKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5TVUJTQ1JJQkVEKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgU2hhcmVkRmlsZSBkb3dubG9hZGVkU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImRvd25sb2FkZWQtZmlsZSIpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBzeW5jaHJvbml6ZWQgKFNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YS5jbGFzcykgeworICAgICAgYXNzZXJ0VGhhdCh3cml0ZVNoYXJlZEZpbGUocmVnaXN0ZXJlZEtleSwgcmVnaXN0ZXJlZFNoYXJlZEZpbGUpKS5pc1RydWUoKTsKKyAgICAgIGFzc2VydFRoYXQod3JpdGVTaGFyZWRGaWxlKGRvd25sb2FkZWRLZXksIGRvd25sb2FkZWRTaGFyZWRGaWxlKSkuaXNUcnVlKCk7CisgICAgfQorCisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLmluaXQoKS5nZXQoKSkuaXNUcnVlKCk7CisKKyAgICAvLyBDaGVjayB0aGF0IHdlIGFyZSBhYmxlIHRvIHJlYWQgdGhlIGZpbGUgYWZ0ZXIgdGhlIG1pZ3JhdGlvbi4KKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChyZWdpc3RlcmVkS2V5KS5nZXQoKSkuaXNFcXVhbFRvKHJlZ2lzdGVyZWRTaGFyZWRGaWxlKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChkb3dubG9hZGVkS2V5KS5nZXQoKSkuaXNFcXVhbFRvKGRvd25sb2FkZWRTaGFyZWRGaWxlKTsKKworICAgIHZlcmlmeU5vRXJyb3JJblBkc01pZ3JhdGlvbigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdE1pZ3JhdGVUb05ld1ZlcnNpb25fdXNlQ2hlY2tzdW1Pbmx5KCkKKyAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICBmbGFncy5maWxlS2V5VmVyc2lvbiA9IE9wdGlvbmFsLm9mKEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZLnZhbHVlKTsKKworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uQUREX0RPV05MT0FEX1RSQU5TRk9STSk7CisKKyAgICAvLyBDcmVhdGUgdHdvIGZpbGVzLCBvbmUgZG93bmxvYWRlZCBhbmQgdGhlIG90aGVyIGN1cnJlbnRseSBiZWluZyBkb3dubG9hZGVkLgorICAgIERhdGFGaWxlIHJlZ2lzdGVyZWRGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoInJlZ2lzdGVyZWQtZmlsZSIsIDApOworICAgIERhdGFGaWxlIGRvd25sb2FkZWRGaWxlID0gTWRkVGVzdFV0aWwuY3JlYXRlRGF0YUZpbGUoImRvd25sb2FkZWQtZmlsZSIsIC8qIGZpbGVJbmRleCAqLyAwKTsKKworICAgIE5ld0ZpbGVLZXkgZG93bmxvYWRlZEtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKGRvd25sb2FkZWRGaWxlLCBBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpOworICAgIE5ld0ZpbGVLZXkgcmVnaXN0ZXJlZEtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGEuY3JlYXRlS2V5RnJvbURhdGFGaWxlKAorICAgICAgICAgICAgcmVnaXN0ZXJlZEZpbGUsIEFsbG93ZWRSZWFkZXJzLk9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMpOworCisgICAgU2hhcmVkRmlsZSByZWdpc3RlcmVkU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoInJlZ2lzdGVyZWQtZmlsZSIpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLlNVQlNDUklCRUQpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBTaGFyZWRGaWxlIGRvd25sb2FkZWRTaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgiZG93bmxvYWRlZC1maWxlIikKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHN5bmNocm9uaXplZCAoU2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhLmNsYXNzKSB7CisgICAgICBhc3NlcnRUaGF0KHdyaXRlU2hhcmVkRmlsZShyZWdpc3RlcmVkS2V5LCByZWdpc3RlcmVkU2hhcmVkRmlsZSkpLmlzVHJ1ZSgpOworICAgICAgYXNzZXJ0VGhhdCh3cml0ZVNoYXJlZEZpbGUoZG93bmxvYWRlZEtleSwgZG93bmxvYWRlZFNoYXJlZEZpbGUpKS5pc1RydWUoKTsKKyAgICB9CisKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEuaW5pdCgpLmdldCgpKS5pc1RydWUoKTsKKworICAgIC8vIENoZWNrIHRoYXQgd2UgYXJlIGFibGUgdG8gcmVhZCB0aGUgZmlsZSBhZnRlciB0aGUgbWlncmF0aW9uLgorICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKHJlZ2lzdGVyZWRLZXkpLmdldCgpKS5pc0VxdWFsVG8ocmVnaXN0ZXJlZFNoYXJlZEZpbGUpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKGRvd25sb2FkZWRLZXkpLmdldCgpKS5pc0VxdWFsVG8oZG93bmxvYWRlZFNoYXJlZEZpbGUpOworCisgICAgdmVyaWZ5Tm9FcnJvckluUGRzTWlncmF0aW9uKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0TWlncmF0ZUZyb21OZXdGaWxlS2V5VG9Vc2VDaGVja3N1bU9ubHlfY29ycnVwdGVkTWV0YWRhdGEoKQorICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24geworICAgIGZsYWdzLmZpbGVLZXlWZXJzaW9uID0gT3B0aW9uYWwub2YoRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkudmFsdWUpOworCisgICAgLy8gQ3JlYXRlIHR3byBmaWxlcywgb25lIGRvd25sb2FkZWQgYW5kIHRoZSBvdGhlciBjdXJyZW50bHkgYmVpbmcgZG93bmxvYWRlZC4KKyAgICBEYXRhRmlsZSByZWdpc3RlcmVkRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJyZWdpc3RlcmVkLWZpbGUiLCAwKTsKKyAgICBEYXRhRmlsZSBkb3dubG9hZGVkRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJkb3dubG9hZGVkLWZpbGUiLCAvKiBmaWxlSW5kZXggKi8gMCk7CisKKyAgICBOZXdGaWxlS2V5IGRvd25sb2FkZWRLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShkb3dubG9hZGVkRmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBOZXdGaWxlS2V5IHJlZ2lzdGVyZWRLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIHJlZ2lzdGVyZWRGaWxlLCBBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKTsKKworICAgIFNoYXJlZEZpbGUgcmVnaXN0ZXJlZFNoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJyZWdpc3RlcmVkLWZpbGUiKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5TVUJTQ1JJQkVEKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgU2hhcmVkRmlsZSBkb3dubG9hZGVkU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImRvd25sb2FkZWQtZmlsZSIpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBzeW5jaHJvbml6ZWQgKFNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YS5jbGFzcykgeworICAgICAgYXNzZXJ0VGhhdCh3cml0ZVNoYXJlZEZpbGUocmVnaXN0ZXJlZEtleSwgcmVnaXN0ZXJlZFNoYXJlZEZpbGUpKS5pc1RydWUoKTsKKyAgICAgIGFzc2VydFRoYXQod3JpdGVTaGFyZWRGaWxlKGRvd25sb2FkZWRLZXksIGRvd25sb2FkZWRTaGFyZWRGaWxlKSkuaXNUcnVlKCk7CisgICAgfQorCisgICAgLy8gU2V0IGludmFsaWQgdmVyc2lvbgorICAgIFNoYXJlZFByZWZlcmVuY2VzIG1pZ3JhdGlvblByZWZzID0KKyAgICAgICAgY29udGV4dC5nZXRTaGFyZWRQcmVmZXJlbmNlcygiZ21zX2ljaW5nX21kZF9taWdyYXRpb25zIiwgQ29udGV4dC5NT0RFX1BSSVZBVEUpOworICAgIG1pZ3JhdGlvblByZWZzLmVkaXQoKS5wdXRJbnQoIm1kZF9maWxlX2tleV92ZXJzaW9uIiwgMjAwKS5jb21taXQoKTsKKworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5pbml0KCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIC8vIENoZWNrIHRoYXQgd2UgYXJlIGFibGUgdG8gcmVhZCB0aGUgZmlsZSBhZnRlciB0aGUgbWlncmF0aW9uLgorICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKHJlZ2lzdGVyZWRLZXkpLmdldCgpKS5pc0VxdWFsVG8ocmVnaXN0ZXJlZFNoYXJlZEZpbGUpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKGRvd25sb2FkZWRLZXkpLmdldCgpKS5pc0VxdWFsVG8oZG93bmxvYWRlZFNoYXJlZEZpbGUpOworCisgICAgdmVyaWZ5Tm9FcnJvckluUGRzTWlncmF0aW9uKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0Tm9NaWdyYXRlX2NvcnJ1cHRlZE1ldGFkYXRhKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24geworICAgIGZsYWdzLmZpbGVLZXlWZXJzaW9uID0gT3B0aW9uYWwub2YoRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkudmFsdWUpOworICAgIE1pZ3JhdGlvbnMuc2V0Q3VycmVudFZlcnNpb24oY29udGV4dCwgRmlsZUtleVZlcnNpb24uVVNFX0NIRUNLU1VNX09OTFkpOworCisgICAgLy8gQ3JlYXRlIHR3byBmaWxlcywgb25lIGRvd25sb2FkZWQgYW5kIHRoZSBvdGhlciBjdXJyZW50bHkgYmVpbmcgZG93bmxvYWRlZC4KKyAgICBEYXRhRmlsZSByZWdpc3RlcmVkRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJyZWdpc3RlcmVkLWZpbGUiLCAwKTsKKyAgICBEYXRhRmlsZSBkb3dubG9hZGVkRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlKCJkb3dubG9hZGVkLWZpbGUiLCAvKiBmaWxlSW5kZXggKi8gMCk7CisKKyAgICBOZXdGaWxlS2V5IGRvd25sb2FkZWRLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZShkb3dubG9hZGVkRmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBOZXdGaWxlS2V5IHJlZ2lzdGVyZWRLZXkgPQorICAgICAgICBTaGFyZWRGaWxlc01ldGFkYXRhLmNyZWF0ZUtleUZyb21EYXRhRmlsZSgKKyAgICAgICAgICAgIHJlZ2lzdGVyZWRGaWxlLCBBbGxvd2VkUmVhZGVycy5PTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTKTsKKworICAgIFNoYXJlZEZpbGUgcmVnaXN0ZXJlZFNoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJyZWdpc3RlcmVkLWZpbGUiKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5TVUJTQ1JJQkVEKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgU2hhcmVkRmlsZSBkb3dubG9hZGVkU2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImRvd25sb2FkZWQtZmlsZSIpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBzeW5jaHJvbml6ZWQgKFNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YS5jbGFzcykgeworICAgICAgYXNzZXJ0VGhhdCh3cml0ZVNoYXJlZEZpbGUocmVnaXN0ZXJlZEtleSwgcmVnaXN0ZXJlZFNoYXJlZEZpbGUpKS5pc1RydWUoKTsKKyAgICAgIGFzc2VydFRoYXQod3JpdGVTaGFyZWRGaWxlKGRvd25sb2FkZWRLZXksIGRvd25sb2FkZWRTaGFyZWRGaWxlKSkuaXNUcnVlKCk7CisgICAgfQorCisgICAgLy8gU2V0IGludmFsaWQgdmVyc2lvbgorICAgIFNoYXJlZFByZWZlcmVuY2VzIG1pZ3JhdGlvblByZWZzID0KKyAgICAgICAgY29udGV4dC5nZXRTaGFyZWRQcmVmZXJlbmNlcygiZ21zX2ljaW5nX21kZF9taWdyYXRpb25zIiwgQ29udGV4dC5NT0RFX1BSSVZBVEUpOworICAgIG1pZ3JhdGlvblByZWZzLmVkaXQoKS5wdXRJbnQoIm1kZF9maWxlX2tleV92ZXJzaW9uIiwgMjAwKS5jb21taXQoKTsKKworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5pbml0KCkuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIC8vIFVuYWJsZSB0byByZWFkIHRoZSBmaWxlIGJlY2F1c2UgdGhlIGZpbGUga2V5IHZlcnNpb24gZG9lc24ndCBtYXRjaCBkdXJpbmcgbWlncmF0aW9uCisgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQocmVnaXN0ZXJlZEtleSkuZ2V0KCkpLmlzTnVsbCgpOworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5yZWFkKGRvd25sb2FkZWRLZXkpLmdldCgpKS5pc051bGwoKTsKKworICAgIHZlcmlmeU5vRXJyb3JJblBkc01pZ3JhdGlvbigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdE1pZ3JhdGVUb05ld1ZlcnNpb25fZG93bmdyYWRlX2NsZWFyT2ZmKCkKKyAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLkFERF9ET1dOTE9BRF9UUkFOU0ZPUk0pOworICAgIGZsYWdzLmZpbGVLZXlWZXJzaW9uID0gT3B0aW9uYWwub2YoRmlsZUtleVZlcnNpb24uTkVXX0ZJTEVfS0VZLnZhbHVlKTsKKworICAgIGFzc2VydFRoYXQoc2hhcmVkRmlsZXNNZXRhZGF0YS5pbml0KCkuZ2V0KCkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3REZXNlcmlhbGl6ZU5ld0ZpbGVLZXkoKSB0aHJvd3MgRmlsZUtleURlc2VyaWFsaXphdGlvbkV4Y2VwdGlvbiB7CisgICAgTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBGaWxlS2V5VmVyc2lvbi5ORVdfRklMRV9LRVkpOworICAgIFN0cmluZyB1cmwgPSAiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vaWNpbmcvaWRkL2FwaXRlc3QvY29tcHJlc3NlZEZpbGUudHh0LmRlZmxhdGUiOworICAgIGludCBzaXplID0gMTU7CisgICAgU3RyaW5nIGNoZWNrc3VtID0gImVjODc2ODUwZTdkZGM5ZWNkZTFhMzg0NDAwNmUzNjYzZDcwNTY5ZTMiOworICAgIE5ld0ZpbGVLZXkgZmlsZUtleSA9CisgICAgICAgIE5ld0ZpbGVLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCh1cmwpCisgICAgICAgICAgICAuc2V0Qnl0ZVNpemUoc2l6ZSkKKyAgICAgICAgICAgIC5zZXRDaGVja3N1bShjaGVja3N1bSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVycyhBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBTdHJpbmcgc2VyaWFsaXplZFN0ciA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGFVdGlsLmdldFNlcmlhbGl6ZWRGaWxlS2V5KGZpbGVLZXksIGNvbnRleHQsIG1vY2tTaWxlbnRGZWVkYmFjayk7CisgICAgTmV3RmlsZUtleSBuZXdGaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuZGVzZXJpYWxpemVOZXdGaWxlS2V5KHNlcmlhbGl6ZWRTdHIsIGNvbnRleHQsIG1vY2tTaWxlbnRGZWVkYmFjayk7CisgICAgYXNzZXJ0VGhhdChuZXdGaWxlS2V5LmdldFVybFRvRG93bmxvYWQoKSkuaXNFcXVhbFRvKHVybCk7CisgICAgYXNzZXJ0VGhhdChuZXdGaWxlS2V5LmdldEJ5dGVTaXplKCkpLmlzRXF1YWxUbyhzaXplKTsKKyAgICBhc3NlcnRUaGF0KG5ld0ZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSkuaXNFcXVhbFRvKGNoZWNrc3VtKTsKKyAgICBhc3NlcnRUaGF0KG5ld0ZpbGVLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKSkuaXNFcXVhbFRvKEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisgICAgYXNzZXJ0VGhhdChuZXdGaWxlS2V5Lmhhc0Rvd25sb2FkVHJhbnNmb3JtcygpKS5pc0ZhbHNlKCk7CisKKyAgICAvLyB0ZXN0IHdpdGggdHJhbnNmb3JtcywgaXQgc2hvdWxkIGJlIHNraXBwZWQKKyAgICBTdHJpbmcgc2VyaWFsaXplZFN0cldpdGhEb3dubG9hZFRyYW5zZm9ybSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGFVdGlsLmdldFNlcmlhbGl6ZWRGaWxlS2V5KAorICAgICAgICAgICAgbmV3RmlsZUtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZFRyYW5zZm9ybXMoQ09NUFJFU1NfVFJBTlNGT1JNKS5idWlsZCgpLAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIG1vY2tTaWxlbnRGZWVkYmFjayk7CisgICAgbmV3RmlsZUtleSA9CisgICAgICAgIFNoYXJlZEZpbGVzTWV0YWRhdGFVdGlsLmRlc2VyaWFsaXplTmV3RmlsZUtleSgKKyAgICAgICAgICAgIHNlcmlhbGl6ZWRTdHJXaXRoRG93bmxvYWRUcmFuc2Zvcm0sIGNvbnRleHQsIG1vY2tTaWxlbnRGZWVkYmFjayk7CisgICAgYXNzZXJ0VGhhdChuZXdGaWxlS2V5LmdldFVybFRvRG93bmxvYWQoKSkuaXNFcXVhbFRvKHVybCk7CisgICAgYXNzZXJ0VGhhdChuZXdGaWxlS2V5LmdldEJ5dGVTaXplKCkpLmlzRXF1YWxUbyhzaXplKTsKKyAgICBhc3NlcnRUaGF0KG5ld0ZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSkuaXNFcXVhbFRvKGNoZWNrc3VtKTsKKyAgICBhc3NlcnRUaGF0KG5ld0ZpbGVLZXkuZ2V0QWxsb3dlZFJlYWRlcnMoKSkuaXNFcXVhbFRvKEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUyk7CisKKyAgICBhc3NlcnRUaGF0KG5ld0ZpbGVLZXkuaGFzRG93bmxvYWRUcmFuc2Zvcm1zKCkpLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHRlc3RSZWFkQW5kV3JpdGVBZnRlckRvd25sb2FkVHJhbnNmb3JtTWlncmF0aW9uKCkKKyAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLkFERF9ET1dOTE9BRF9UUkFOU0ZPUk0pOworICAgIFN0cmluZyB1cmwgPSAiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vaWNpbmcvaWRkL2FwaXRlc3QvY29tcHJlc3NlZEZpbGUudHh0LmRlZmxhdGUiOworICAgIGludCBzaXplID0gMTU7CisgICAgU3RyaW5nIGNoZWNrc3VtID0gImVjODc2ODUwZTdkZGM5ZWNkZTFhMzg0NDAwNmUzNjYzZDcwNTY5ZTMiOworICAgIE5ld0ZpbGVLZXkgZmlsZUtleSA9CisgICAgICAgIE5ld0ZpbGVLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCh1cmwpCisgICAgICAgICAgICAuc2V0Qnl0ZVNpemUoc2l6ZSkKKyAgICAgICAgICAgIC5zZXRDaGVja3N1bShjaGVja3N1bSkKKyAgICAgICAgICAgIC5zZXRBbGxvd2VkUmVhZGVycyhBbGxvd2VkUmVhZGVycy5BTExfR09PR0xFX0FQUFMpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJyZWdpc3RlcmVkLWZpbGUiKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gQ2hhbmdlIHRoZSBzYW1lIGtleSBhbmQganVzdCBhZGQgZG93bmxvYWQgdHJhbnNmb3JtCisgICAgTmV3RmlsZUtleSBmaWxlS2V5V2l0aFRyYW5zZm9ybXMgPQorICAgICAgICBmaWxlS2V5LnRvQnVpbGRlcigpLnNldERvd25sb2FkVHJhbnNmb3JtcyhDT01QUkVTU19UUkFOU0ZPUk0pLmJ1aWxkKCk7CisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlV2l0aFRyYW5zZm9ybSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoImZpbGUtd2l0aC10cmFuc2Zvcm0iKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5TVUJTQ1JJQkVEKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBzeW5jaHJvbml6ZWQgKFNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YS5jbGFzcykgeworICAgICAgYXNzZXJ0VGhhdCh3cml0ZVNoYXJlZEZpbGUoZmlsZUtleSwgc2hhcmVkRmlsZSkpLmlzVHJ1ZSgpOworICAgICAgYXNzZXJ0VGhhdCh3cml0ZVNoYXJlZEZpbGUoZmlsZUtleVdpdGhUcmFuc2Zvcm1zLCBzaGFyZWRGaWxlV2l0aFRyYW5zZm9ybSkpLmlzVHJ1ZSgpOworCisgICAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChmaWxlS2V5KS5nZXQoKSkuaXNFcXVhbFRvKHNoYXJlZEZpbGUpOworICAgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLnJlYWQoZmlsZUtleVdpdGhUcmFuc2Zvcm1zKS5nZXQoKSkKKyAgICAgICAgICAuaXNFcXVhbFRvKHNoYXJlZEZpbGVXaXRoVHJhbnNmb3JtKTsKKworICAgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLnJlbW92ZShmaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEucmVtb3ZlKGZpbGVLZXlXaXRoVHJhbnNmb3JtcykuZ2V0KCkpLmlzVHJ1ZSgpOworICAgIH0KKworICAgIHZlcmlmeU5vRXJyb3JJblBkc01pZ3JhdGlvbigpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdFJlYWRBbmRXcml0ZV9hZnRlckNoZWNrc3VtT25seU1pZ3JhdGlvbigpCisgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbiB7CisgICAgTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBGaWxlS2V5VmVyc2lvbi5VU0VfQ0hFQ0tTVU1fT05MWSk7CisKKyAgICBTdHJpbmcgY2hlY2tzdW0gPSAiZWM4NzY4NTBlN2RkYzllY2RlMWEzODQ0MDA2ZTM2NjNkNzA1NjllMyI7CisgICAgTmV3RmlsZUtleSBmaWxlS2V5ID0gTmV3RmlsZUtleS5uZXdCdWlsZGVyKCkuc2V0Q2hlY2tzdW0oY2hlY2tzdW0pLmJ1aWxkKCk7CisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgicmVnaXN0ZXJlZC1maWxlIikKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHN5bmNocm9uaXplZCAoU2hhcmVkUHJlZmVyZW5jZXNTaGFyZWRGaWxlc01ldGFkYXRhLmNsYXNzKSB7CisgICAgICBhc3NlcnRUaGF0KHdyaXRlU2hhcmVkRmlsZShmaWxlS2V5LCBzaGFyZWRGaWxlKSkuaXNUcnVlKCk7CisgICAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEucmVhZChmaWxlS2V5KS5nZXQoKSkuaXNFcXVhbFRvKHNoYXJlZEZpbGUpOworICAgICAgYXNzZXJ0VGhhdChzaGFyZWRGaWxlc01ldGFkYXRhLnJlbW92ZShmaWxlS2V5KS5nZXQoKSkuaXNUcnVlKCk7CisgICAgfQorCisgICAgdmVyaWZ5Tm9FcnJvckluUGRzTWlncmF0aW9uKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0R2V0QWxsRmlsZUtleXNfYWZ0ZXJEb3dubG9hZFRyYW5zZm9ybU1pZ3JhdGlvbigpCisgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbiB7CisgICAgTWlncmF0aW9ucy5zZXRDdXJyZW50VmVyc2lvbihjb250ZXh0LCBGaWxlS2V5VmVyc2lvbi5BRERfRE9XTkxPQURfVFJBTlNGT1JNKTsKKyAgICBTdHJpbmcgdXJsID0gImh0dHBzOi8vd3d3LmdzdGF0aWMuY29tL2ljaW5nL2lkZC9hcGl0ZXN0L2NvbXByZXNzZWRGaWxlLnR4dC5kZWZsYXRlIjsKKyAgICBpbnQgc2l6ZSA9IDE1OworICAgIFN0cmluZyBjaGVja3N1bSA9ICJlYzg3Njg1MGU3ZGRjOWVjZGUxYTM4NDQwMDZlMzY2M2Q3MDU2OWUzIjsKKyAgICBOZXdGaWxlS2V5IGZpbGVLZXkgPQorICAgICAgICBOZXdGaWxlS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQodXJsKQorICAgICAgICAgICAgLnNldEJ5dGVTaXplKHNpemUpCisgICAgICAgICAgICAuc2V0Q2hlY2tzdW0oY2hlY2tzdW0pCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnMoQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgU2hhcmVkRmlsZSBzaGFyZWRGaWxlID0KKyAgICAgICAgU2hhcmVkRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRGaWxlTmFtZSgicmVnaXN0ZXJlZC1maWxlIikKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuRE9XTkxPQURfQ09NUExFVEUpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIENoYW5nZSB0aGUgc2FtZSBrZXkgYW5kIGp1c3QgYWRkIGRvd25sb2FkIHRyYW5zZm9ybQorICAgIE5ld0ZpbGVLZXkgZmlsZUtleVdpdGhUcmFuc2Zvcm1zID0KKyAgICAgICAgZmlsZUtleS50b0J1aWxkZXIoKS5zZXREb3dubG9hZFRyYW5zZm9ybXMoQ09NUFJFU1NfVFJBTlNGT1JNKS5idWlsZCgpOworICAgIFNoYXJlZEZpbGUgc2hhcmVkRmlsZVdpdGhUcmFuc2Zvcm0gPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJmaWxlLXdpdGgtdHJhbnNmb3JtIikKKyAgICAgICAgICAgIC5zZXRGaWxlU3RhdHVzKEZpbGVTdGF0dXMuU1VCU0NSSUJFRCkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgc3luY2hyb25pemVkIChTaGFyZWRQcmVmZXJlbmNlc1NoYXJlZEZpbGVzTWV0YWRhdGEuY2xhc3MpIHsKKyAgICAgIGFzc2VydFRoYXQod3JpdGVTaGFyZWRGaWxlKGZpbGVLZXksIHNoYXJlZEZpbGUpKS5pc1RydWUoKTsKKyAgICAgIGFzc2VydFRoYXQod3JpdGVTaGFyZWRGaWxlKGZpbGVLZXlXaXRoVHJhbnNmb3Jtcywgc2hhcmVkRmlsZVdpdGhUcmFuc2Zvcm0pKS5pc1RydWUoKTsKKworICAgICAgTGlzdDxOZXdGaWxlS2V5PiBhbGxGaWxlS2V5cyA9IHNoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKS5nZXQoKTsKKyAgICAgIGFzc2VydFRoYXQoYWxsRmlsZUtleXMpLmhhc1NpemUoMik7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEdldEFsbEZpbGVLZXlzX2FmdGVyQ2hlY2tzdW1Pbmx5TWlncmF0aW9uKCkKKyAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICBNaWdyYXRpb25zLnNldEN1cnJlbnRWZXJzaW9uKGNvbnRleHQsIEZpbGVLZXlWZXJzaW9uLlVTRV9DSEVDS1NVTV9PTkxZKTsKKworICAgIFN0cmluZyBjaGVja3N1bSA9ICJlYzg3Njg1MGU3ZGRjOWVjZGUxYTM4NDQwMDZlMzY2M2Q3MDU2OWUzIjsKKyAgICBOZXdGaWxlS2V5IGZpbGVLZXkgPQorICAgICAgICBOZXdGaWxlS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldENoZWNrc3VtKGNoZWNrc3VtKQorICAgICAgICAgICAgLnNldEFsbG93ZWRSZWFkZXJzKEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUykKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIFNoYXJlZEZpbGUgc2hhcmVkRmlsZSA9CisgICAgICAgIFNoYXJlZEZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZU5hbWUoInJlZ2lzdGVyZWQtZmlsZSIpCisgICAgICAgICAgICAuc2V0RmlsZVN0YXR1cyhGaWxlU3RhdHVzLkRPV05MT0FEX0NPTVBMRVRFKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBzeW5jaHJvbml6ZWQgKFNoYXJlZFByZWZlcmVuY2VzU2hhcmVkRmlsZXNNZXRhZGF0YS5jbGFzcykgeworICAgICAgYXNzZXJ0VGhhdCh3cml0ZVNoYXJlZEZpbGUoZmlsZUtleSwgc2hhcmVkRmlsZSkpLmlzVHJ1ZSgpOworCisgICAgICBMaXN0PE5ld0ZpbGVLZXk+IGFsbEZpbGVLZXlzID0gc2hhcmVkRmlsZXNNZXRhZGF0YS5nZXRBbGxGaWxlS2V5cygpLmdldCgpOworICAgICAgYXNzZXJ0VGhhdChhbGxGaWxlS2V5cykuaGFzU2l6ZSgxKTsKKyAgICAgIGFzc2VydFRoYXQoYWxsRmlsZUtleXMuZ2V0KDApKS5pc0VxdWFsVG8oZmlsZUtleSk7CisgICAgfQorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEdldEFsbEZpbGVLZXlzV2l0aENvcnJ1cHRlZERhdGEoKQorICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24geworICAgIFNoYXJlZFByZWZlcmVuY2VzIHByZWZzID0KKyAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKAorICAgICAgICAgICAgY29udGV4dCwgU2hhcmVkRmlsZXNNZXRhZGF0YVV0aWwuTUREX1NIQVJFRF9GSUxFUywgaW5zdGFuY2VJZCk7CisgICAgU3RyaW5nIHZhbGlkS2V5T25lID0KKyAgICAgICAgImh0dHBzOi8vd3d3LmdzdGF0aWMuY29tL2ljaW5nL2lkZC9hcGl0ZXN0L2NvbXByZXNzZWRGaWxlLnR4dC5kZWZsYXRlfDE1fGNoZWNrc3VtfDEiOworICAgIFN0cmluZyBjb3JydXB0ZWRLZXlPbmUgPQorICAgICAgICAiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vaWNpbmcvaWRkL2FwaXRlc3QvY29tcHJlc3NlZEZpbGUudHh0LmRlZmxhdGV8MTV8YWJjIjsKKyAgICBTaGFyZWRGaWxlIHNoYXJlZEZpbGUgPQorICAgICAgICBTaGFyZWRGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVOYW1lKCJyZWdpc3RlcmVkLWZpbGUiKQorICAgICAgICAgICAgLnNldEZpbGVTdGF0dXMoRmlsZVN0YXR1cy5ET1dOTE9BRF9DT01QTEVURSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGFzc2VydFRoYXQoU2hhcmVkUHJlZmVyZW5jZXNVdGlsLndyaXRlUHJvdG8ocHJlZnMsIHZhbGlkS2V5T25lLCBzaGFyZWRGaWxlKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChTaGFyZWRQcmVmZXJlbmNlc1V0aWwud3JpdGVQcm90byhwcmVmcywgY29ycnVwdGVkS2V5T25lLCBzaGFyZWRGaWxlKSkuaXNUcnVlKCk7CisgICAgU3RyaW5nIGNvcnJ1cHRlZEtleVR3byA9ICJ8MTV8YWJjIjsKKyAgICBhc3NlcnRUaGF0KFNoYXJlZFByZWZlcmVuY2VzVXRpbC53cml0ZVByb3RvKHByZWZzLCBjb3JydXB0ZWRLZXlUd28sIHNoYXJlZEZpbGUpKS5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KHNoYXJlZEZpbGVzTWV0YWRhdGEuZ2V0QWxsRmlsZUtleXMoKS5nZXQoKSkuaGFzU2l6ZSgxKTsKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgU2hhcmVkUHJlZmVyZW5jZXNVdGlsLmdldFNoYXJlZFByZWZlcmVuY2VzKAorICAgICAgICAgICAgICAgICAgICBjb250ZXh0LCBTaGFyZWRGaWxlc01ldGFkYXRhVXRpbC5NRERfU0hBUkVEX0ZJTEVTLCBpbnN0YW5jZUlkKQorICAgICAgICAgICAgICAgIC5nZXRBbGwoKSkKKyAgICAgICAgLmhhc1NpemUoMSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0X2NyZWF0ZUtleUZyb21EYXRhRmlsZV93aXRoWmlwRG93bmxvYWRUcmFuc2Zvcm0oKSB7CisgICAgRGF0YUZpbGUgemlwRmlsZSA9IE1kZFRlc3RVdGlsLmNyZWF0ZVppcEZvbGRlckRhdGFGaWxlKCJ0ZXN0emlwIiwgMCk7CisgICAgTmV3RmlsZUtleSBmaWxlS2V5ID0KKyAgICAgICAgU2hhcmVkRmlsZXNNZXRhZGF0YS5jcmVhdGVLZXlGcm9tRGF0YUZpbGUoemlwRmlsZSwgQWxsb3dlZFJlYWRlcnMuQUxMX0dPT0dMRV9BUFBTKTsKKyAgICBhc3NlcnRUaGF0KGZpbGVLZXkuZ2V0Q2hlY2tzdW0oKSkuaXNFcXVhbFRvKHppcEZpbGUuZ2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bSgpKTsKKyAgfQorCisgIHByaXZhdGUgYm9vbGVhbiB3cml0ZVNoYXJlZEZpbGUoTmV3RmlsZUtleSBuZXdGaWxlS2V5LCBTaGFyZWRGaWxlIHNoYXJlZEZpbGUpCisgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbiB7CisgICAgcmV0dXJuIHNoYXJlZEZpbGVzTWV0YWRhdGEud3JpdGUobmV3RmlsZUtleSwgc2hhcmVkRmlsZSkuZ2V0KCk7CisgIH0KKworICBwcml2YXRlIHZvaWQgdmVyaWZ5Tm9FcnJvckluUGRzTWlncmF0aW9uKCkge30KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL0FuZHJvaWRNYW5pZmVzdC54bWwgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9BbmRyb2lkTWFuaWZlc3QueG1sCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlhNzQ2Y2EKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9BbmRyb2lkTWFuaWZlc3QueG1sCkBAIC0wLDAgKzEsMzAgQEAKKzwhLS0KKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCistLT4KKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9InV0Zi04Ij8+Cis8bWFuaWZlc3QgeG1sbnM6YW5kcm9pZD0iaHR0cDovL3NjaGVtYXMuYW5kcm9pZC5jb20vYXBrL3Jlcy9hbmRyb2lkIgorICAgIHBhY2thZ2U9ImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwiPgorICA8dXNlcy1zZGsKKyAgICAgIGFuZHJvaWQ6bWluU2RrVmVyc2lvbj0iMTYiCisgICAgICBhbmRyb2lkOnRhcmdldFNka1ZlcnNpb249IjI3Ii8+CisgIDxhcHBsaWNhdGlvbj4KKyAgICA8dXNlcy1saWJyYXJ5IGFuZHJvaWQ6bmFtZT0iYW5kcm9pZC50ZXN0LnJ1bm5lciIgLz4KKyAgPC9hcHBsaWNhdGlvbj4KKyAgPGluc3RydW1lbnRhdGlvbgorICAgICAgYW5kcm9pZDpuYW1lPSJjb20uZ29vZ2xlLmFuZHJvaWQuYXBwcy5jb21tb24udGVzdGluZy50ZXN0cnVubmVyLkdvb2dsZTNJbnN0cnVtZW50YXRpb25UZXN0UnVubmVyIgorICAgICAgYW5kcm9pZDp0YXJnZXRQYWNrYWdlPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC51dGlsIiAvPgorPC9tYW5pZmVzdD4KXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2ZjQ4MDUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9CVUlMRApAQCAtMCwwICsxLDExMyBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorbG9hZCgiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwgImFuZHJvaWRfbGlicmFyeSIsICJhbmRyb2lkX2xvY2FsX3Rlc3QiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJEaXJlY3RvcnlVdGlsVGVzdCIsCisgICAgc3JjcyA9IFsiRGlyZWN0b3J5VXRpbFRlc3QuamF2YSJdLAorICAgIG1hbmlmZXN0X3ZhbHVlcyA9IHsKKyAgICAgICAgIm1pblNka1ZlcnNpb24iOiAiMTYiLAorICAgICAgICAidGFyZ2V0U2RrVmVyc2lvbiI6ICIyNyIsCisgICAgfSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpEaXJlY3RvcnlVdGlsIiwKKyAgICAgICAgIkBhbmRyb2lkeF90ZXN0IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiRWl0aGVyVGVzdCIsCisgICAgc3JjcyA9IFsiRWl0aGVyVGVzdC5qYXZhIl0sCisgICAgbWFuaWZlc3RfdmFsdWVzID0geworICAgICAgICAibWluU2RrVmVyc2lvbiI6ICIxNiIsCisgICAgICAgICJ0YXJnZXRTZGtWZXJzaW9uIjogIjI3IiwKKyAgICB9LAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpFaXRoZXIiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJGdXR1cmVzVXRpbFRlc3QiLAorICAgIHNyY3MgPSBbIkZ1dHVyZXNVdGlsVGVzdC5qYXZhIl0sCisgICAgbWFuaWZlc3RfdmFsdWVzID0geworICAgICAgICAibWluU2RrVmVyc2lvbiI6ICIxNiIsCisgICAgICAgICJ0YXJnZXRTZGtWZXJzaW9uIjogIjI3IiwKKyAgICB9LAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpGdXR1cmVzVXRpbCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK2FuZHJvaWRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIlByb3RvQ29udmVyc2lvblV0aWxUZXN0IiwKKyAgICBzcmNzID0gWyJQcm90b0NvbnZlcnNpb25VdGlsVGVzdC5qYXZhIl0sCisgICAgZGF0YSA9IFsKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvdGVzdGRhdGE6cmF3X2dyb3VwIiwKKyAgICBdLAorICAgIG1hbmlmZXN0X3ZhbHVlcyA9IHsKKyAgICAgICAgIm1pblNka1ZlcnNpb24iOiAiMTYiLAorICAgICAgICAidGFyZ2V0U2RrVmVyc2lvbiI6ICIyNyIsCisgICAgfSwKKyAgICBkZXBzID0gWworICAgICAgICAiOmdyb3VwX29wdGlvbmFsX3Vuc2V0X3Byb3RvX2RhdGEiLAorICAgICAgICAiOmdyb3VwX3Byb3RvX2RhdGEiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvYmFja2VuZHM6YW5kcm9pZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6Ynl0ZXMiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbDpQcm90b0NvbnZlcnNpb25VdGlsIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsOk1kZFRlc3RVdGlsIiwKKyAgICAgICAgIi8vcHJvdG86ZG93bmxvYWRfY29uZmlnX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL3Byb3RvOnRyYW5zZm9ybV9qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzpwYXJzZXJzIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86cHJvdG9idWZfbGl0ZSIsCisgICAgICAgICJAY29tX2dvb2dsZV90ZXN0aW5nLy86dGVzdF91dGlsIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiZ3JvdXBfcHJvdG9fZGF0YSIsCisgICAgbWFuaWZlc3QgPSAiQW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgcmVzb3VyY2VfZmlsZXMgPSBbCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL3Rlc3RkYXRhOmdyb3VwLnBiIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvdGVzdGRhdGE6Z3JvdXBfaW50ZXJuYWwucGIiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gImdyb3VwX29wdGlvbmFsX3Vuc2V0X3Byb3RvX2RhdGEiLAorICAgIG1hbmlmZXN0ID0gIkFuZHJvaWRNYW5pZmVzdC54bWwiLAorICAgIHJlc291cmNlX2ZpbGVzID0gWworICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC90ZXN0ZGF0YTpncm91cF9vcHRpb25hbF91bnNldC5wYiIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL3Rlc3RkYXRhOmdyb3VwX2ludGVybmFsX29wdGlvbmFsX3Vuc2V0LnBiIiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRGlyZWN0b3J5VXRpbFRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL0RpcmVjdG9yeVV0aWxUZXN0LmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGM2NjU3NgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL0RpcmVjdG9yeVV0aWxUZXN0LmphdmEKQEAgLTAsMCArMSw3MSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5BbmRyb2lkVXJpOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworLyoqIFVuaXQgdGVzdHMgZm9yIHtAbGluayBEaXJlY3RvcnlVdGlsfS4gKi8KK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBEaXJlY3RvcnlVdGlsVGVzdCB7CisKKyAgcHJpdmF0ZSBDb250ZXh0IGNvbnRleHQ7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHsKKyAgICBjb250ZXh0ID0gQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdldEJhc2VEb3dubG9hZERpcmVjdG9yeSgpIHsKKyAgICAvLyBObyBpbnN0YW5jZWlkCisgICAgVXJpIHVyaSA9IEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KS5zZXRNb2R1bGUoRGlyZWN0b3J5VXRpbC5NRERfU1RPUkFHRV9NT0RVTEUpLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChEaXJlY3RvcnlVdGlsLmdldEJhc2VEb3dubG9hZERpcmVjdG9yeShjb250ZXh0LCBPcHRpb25hbC5hYnNlbnQoKSkpLmlzRXF1YWxUbyh1cmkpOworCisgICAgLy8gdmFsaWQgaW5zdGFuY2VpZAorICAgIHVyaSA9CisgICAgICAgIEFuZHJvaWRVcmkuYnVpbGRlcihjb250ZXh0KQorICAgICAgICAgICAgLnNldE1vZHVsZSgiaW5zdGFuY2VpZCIpCisgICAgICAgICAgICAuc2V0UmVsYXRpdmVQYXRoKERpcmVjdG9yeVV0aWwuTUREX1NUT1JBR0VfTU9EVUxFKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgYXNzZXJ0VGhhdChEaXJlY3RvcnlVdGlsLmdldEJhc2VEb3dubG9hZERpcmVjdG9yeShjb250ZXh0LCBPcHRpb25hbC5vZigiaW5zdGFuY2VpZCIpKSkKKyAgICAgICAgLmlzRXF1YWxUbyh1cmkpOworCisgICAgLy8gaW52YWxpZCBpbnN0YW5jZWlkLiBJbnN0YW5jZUlkIG11c3QgYmUgW2Etel0uCisgICAgYXNzZXJ0VGhyb3dzKAorICAgICAgICBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uY2xhc3MsCisgICAgICAgICgpIC0+IERpcmVjdG9yeVV0aWwuZ2V0QmFzZURvd25sb2FkRGlyZWN0b3J5KGNvbnRleHQsIE9wdGlvbmFsLm9mKCJJbnN0YW5jZUlkIikpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ1aWxkRmlsZW5hbWVfYnVpbGRzRmlsZW5hbWVXaXRoSW5zdGFuY2VJZCgpIHsKKyAgICBhc3NlcnRUaGF0KERpcmVjdG9yeVV0aWwuYnVpbGRGaWxlbmFtZSgicHJlZml4IiwgInN1ZmZpeCIsIE9wdGlvbmFsLmFic2VudCgpKSkKKyAgICAgICAgLmlzRXF1YWxUbygicHJlZml4LnN1ZmZpeCIpOworCisgICAgYXNzZXJ0VGhhdChEaXJlY3RvcnlVdGlsLmJ1aWxkRmlsZW5hbWUoInByZWZpeCIsICJzdWZmaXgiLCBPcHRpb25hbC5vZigibXlpbnN0YW5jZSIpKSkKKyAgICAgICAgLmlzRXF1YWxUbygicHJlZml4bXlpbnN0YW5jZS5zdWZmaXgiKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRWl0aGVyVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvRWl0aGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0NTdjNTkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9FaXRoZXJUZXN0LmphdmEKQEAgLTAsMCArMSw1OSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworCitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuT3JkZXJpbmc7CitpbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBmaW5hbCBjbGFzcyBFaXRoZXJUZXN0IHsKKworICAvLyBJbW11dGFibGVMaXN0IGVuc3VyZXMgdGhlIEVpdGhlciBMaXN0IGlzbid0IG1vZGlmaWVkIGJ5IHNvcnRlZEVxdWFscy4KKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW1tdXRhYmxlTGlzdDxTdHJpbmc+IExJU1QgPSBJbW11dGFibGVMaXN0Lm9mKCJhIiwgImIiLCAiYyIpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJbW11dGFibGVMaXN0PFN0cmluZz4gSlVNQkxFRF9MSVNUID0gSW1tdXRhYmxlTGlzdC5vZigiYyIsICJhIiwgImIiKTsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW1tdXRhYmxlTGlzdDxTdHJpbmc+IE9USEVSX0xJU1QgPSBJbW11dGFibGVMaXN0Lm9mKCJjIik7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQ29tcGFyYXRvcjxTdHJpbmc+IENPTVBBUkFUT1IgPSBPcmRlcmluZy5uYXR1cmFsKCk7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgc29ydGVkRXF1YWxzX2NvbXBhcmVzU29ydGVkTGlzdCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRoYXQoRWl0aGVyLnNvcnRlZEVxdWFscyhFaXRoZXIubWFrZUxlZnQoTElTVCksIEVpdGhlci5tYWtlTGVmdChMSVNUKSwgQ09NUEFSQVRPUikpCisgICAgICAgIC5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KAorICAgICAgICAgICAgRWl0aGVyLnNvcnRlZEVxdWFscyhFaXRoZXIubWFrZUxlZnQoTElTVCksIEVpdGhlci5tYWtlTGVmdChKVU1CTEVEX0xJU1QpLCBDT01QQVJBVE9SKSkKKyAgICAgICAgLmlzVHJ1ZSgpOworCisgICAgYXNzZXJ0VGhhdChFaXRoZXIuc29ydGVkRXF1YWxzKEVpdGhlci5tYWtlTGVmdChMSVNUKSwgRWl0aGVyLm1ha2VMZWZ0KE9USEVSX0xJU1QpLCBDT01QQVJBVE9SKSkKKyAgICAgICAgLmlzRmFsc2UoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHNvcnRlZEVxdWFsc19oYW5kbGVzTnVsbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGFzc2VydFRoYXQoRWl0aGVyLnNvcnRlZEVxdWFscyhFaXRoZXIubWFrZUxlZnQoTElTVCksIG51bGwsIENPTVBBUkFUT1IpKS5pc0ZhbHNlKCk7CisgICAgYXNzZXJ0VGhhdChFaXRoZXIuc29ydGVkRXF1YWxzKEVpdGhlci5tYWtlTGVmdChMSVNUKSwgRWl0aGVyLm1ha2VMZWZ0KG51bGwpLCBDT01QQVJBVE9SKSkKKyAgICAgICAgLmlzRmFsc2UoKTsKKworICAgIGFzc2VydFRoYXQoRWl0aGVyLnNvcnRlZEVxdWFscyhFaXRoZXIubWFrZUxlZnQobnVsbCksIEVpdGhlci5tYWtlTGVmdChudWxsKSwgQ09NUEFSQVRPUikpCisgICAgICAgIC5pc1RydWUoKTsKKyAgICBhc3NlcnRUaGF0KEVpdGhlci5zb3J0ZWRFcXVhbHMobnVsbCwgbnVsbCwgQ09NUEFSQVRPUikpLmlzVHJ1ZSgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9GdXR1cmVzVXRpbFRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL0Z1dHVyZXNVdGlsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUzMDJmMDkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9GdXR1cmVzVXRpbFRlc3QuamF2YQpAQCAtMCwwICsxLDE2MiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLnV0aWwuRnV0dXJlc1V0aWwuU2VxdWVudGlhbEZ1dHVyZUNoYWluOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuRnVuY3Rpb247CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXJzLkpVbml0NDsKKworQFJ1bldpdGgoSlVuaXQ0LmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIEZ1dHVyZXNVdGlsVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRXhlY3V0b3IgU0VRVUVOVElBTF9FWEVDVVRPUiA9CisgICAgICBNb3JlRXhlY3V0b3JzLm5ld1NlcXVlbnRpYWxFeGVjdXRvcihFeGVjdXRvcnMubmV3Q2FjaGVkVGhyZWFkUG9vbCgpKTsKKworICBwcml2YXRlIEZ1dHVyZXNVdGlsIGZ1dHVyZXNVdGlsOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB7CisgICAgZnV0dXJlc1V0aWwgPSBuZXcgRnV0dXJlc1V0aWwoU0VRVUVOVElBTF9FWEVDVVRPUik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjaGFpbl9wcmVzZXJ2ZXNPcmRlcigpIHRocm93cyBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBTZXF1ZW50aWFsRnV0dXJlQ2hhaW48U3RyaW5nPiBjaGFpbiA9IGZ1dHVyZXNVdGlsLm5ld1NlcXVlbnRpYWxDaGFpbigiIik7CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxMDsgaSsrKSB7CisgICAgICAvLyBWYXJpYWJsZXMgY2FwdHVyZWQgaW4gbGFtYmRhcyBtdXN0IGJlIGVmZmVjdGl2ZWx5IGZpbmFsLgorICAgICAgaW50IGluZGV4ID0gaTsKKyAgICAgIGNoYWluLmNoYWluQXN5bmMoc3RyIC0+IEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKHN0ciArIGluZGV4KSk7CisgICAgfQorICAgIFN0cmluZyByZXN1bHQgPSBjaGFpbi5zdGFydCgpLmdldCgpOworICAgIGFzc2VydFRoYXQocmVzdWx0KS5pc0VxdWFsVG8oIjAxMjM0NTY3ODkiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNoYWluX21peGVkT3BlcmF0aW9uVHlwZXNfcHJlc2VydmVzT3JkZXIoKQorICAgICAgdGhyb3dzIEV4ZWN1dGlvbkV4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgIFN0cmluZyByZXN1bHQgPQorICAgICAgICBmdXR1cmVzVXRpbAorICAgICAgICAgICAgLm5ld1NlcXVlbnRpYWxDaGFpbigiIikKKyAgICAgICAgICAgIC5jaGFpbkFzeW5jKHN0ciAtPiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShzdHIgKyAwKSkKKyAgICAgICAgICAgIC5jaGFpbihzdHIgLT4gc3RyICsgMSkKKyAgICAgICAgICAgIC5jaGFpbkFzeW5jKHN0ciAtPiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShzdHIgKyAyKSkKKyAgICAgICAgICAgIC5jaGFpbihzdHIgLT4gc3RyICsgMykKKyAgICAgICAgICAgIC5jaGFpbihzdHIgLT4gc3RyICsgNCkKKyAgICAgICAgICAgIC5jaGFpbkFzeW5jKHN0ciAtPiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShzdHIgKyA1KSkKKyAgICAgICAgICAgIC5zdGFydCgpCisgICAgICAgICAgICAuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChyZXN1bHQpLmlzRXF1YWxUbygiMDEyMzQ1Iik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjaGFpbl9wcmVzZXJ2ZXNPcmRlcl9zaWRlRWZmZWN0cygpIHRocm93cyBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIiIpOworICAgIFNlcXVlbnRpYWxGdXR1cmVDaGFpbjxWb2lkPiBjaGFpbiA9IGZ1dHVyZXNVdGlsLm5ld1NlcXVlbnRpYWxDaGFpbigpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTA7IGkrKykgeworICAgICAgY2hhaW4uY2hhaW5Bc3luYyhhcHBlbmRJbnRBc3luYyhzYiwgaSkpOworICAgIH0KKyAgICBjaGFpbi5zdGFydCgpLmdldCgpOworICAgIGFzc2VydFRoYXQoc2IudG9TdHJpbmcoKSkuaXNFcXVhbFRvKCIwMTIzNDU2Nzg5Iik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjaGFpbl9taXhlZE9wZXJhdGlvblR5cGVzX3ByZXNlcnZlc09yZGVyX3NpZGVFZmZlY3RzKCkKKyAgICAgIHRocm93cyBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIiIpOworICAgIGZ1dHVyZXNVdGlsCisgICAgICAgIC5uZXdTZXF1ZW50aWFsQ2hhaW4oKQorICAgICAgICAuY2hhaW4oYXBwZW5kSW50RGlyZWN0KHNiLCAwKSkKKyAgICAgICAgLmNoYWluQXN5bmMoYXBwZW5kSW50QXN5bmMoc2IsIDEpKQorICAgICAgICAuY2hhaW4oYXBwZW5kSW50RGlyZWN0KHNiLCAyKSkKKyAgICAgICAgLmNoYWluQXN5bmMoYXBwZW5kSW50QXN5bmMoc2IsIDMpKQorICAgICAgICAuY2hhaW5Bc3luYyhhcHBlbmRJbnRBc3luYyhzYiwgNCkpCisgICAgICAgIC5jaGFpbihhcHBlbmRJbnREaXJlY3Qoc2IsIDUpKQorICAgICAgICAuc3RhcnQoKQorICAgICAgICAuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChzYi50b1N0cmluZygpKS5pc0VxdWFsVG8oIjAxMjM0NSIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY2hhaW5fbm9PcF9wcmVzZXJ2ZXNJbml0aWFsU3RhdGUoKSB0aHJvd3MgRXhlY3V0aW9uRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCJJbml0aWFsIHN0YXRlLiIpOworICAgIFNlcXVlbnRpYWxGdXR1cmVDaGFpbjxWb2lkPiBjaGFpbiA9IGZ1dHVyZXNVdGlsLm5ld1NlcXVlbnRpYWxDaGFpbigpOworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMDsgaSsrKSB7CisgICAgICBjaGFpbi5jaGFpbkFzeW5jKGFwcGVuZEludEFzeW5jKHNiLCBpKSk7CisgICAgfQorICAgIGNoYWluLnN0YXJ0KCkuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChzYi50b1N0cmluZygpKS5pc0VxdWFsVG8oIkluaXRpYWwgc3RhdGUuIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjaGFpbl9wcm9wYWdhdGVzRmFpbHVyZSgpIHsKKyAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIiIpOworICAgIFNlcXVlbnRpYWxGdXR1cmVDaGFpbjxWb2lkPiBjaGFpbiA9IGZ1dHVyZXNVdGlsLm5ld1NlcXVlbnRpYWxDaGFpbigpOworICAgIGNoYWluCisgICAgICAgIC5jaGFpbkFzeW5jKGFwcGVuZEludEFzeW5jKHNiLCAwKSkKKyAgICAgICAgLmNoYWluQXN5bmMoYXBwZW5kSW50QXN5bmMoc2IsIDEpKQorICAgICAgICAuY2hhaW5Bc3luYyh2b2lkQXJnIC0+IEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKG5ldyBJT0V4Y2VwdGlvbigiVGhlIGVycm9yIG1lc3NhZ2UuIikpKQorICAgICAgICAuY2hhaW5Bc3luYyhhcHBlbmRJbnRBc3luYyhzYiwgMikpCisgICAgICAgIC5jaGFpbkFzeW5jKGFwcGVuZEludEFzeW5jKHNiLCAzKSk7CisgICAgRXhlY3V0aW9uRXhjZXB0aW9uIGV4ID0gYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgY2hhaW4uc3RhcnQoKTo6Z2V0KTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoSU9FeGNlcHRpb24uY2xhc3MpOworICAgIGFzc2VydFRoYXQoZXgpLmhhc01lc3NhZ2VUaGF0KCkuY29udGFpbnMoIlRoZSBlcnJvciBtZXNzYWdlLiIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY2hhaW5fbWl4ZWRPcGVyYXRpb25UeXBlc19wcm9wYWdhdGVzRmFpbHVyZSgpIHsKKyAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIiIpOworICAgIFNlcXVlbnRpYWxGdXR1cmVDaGFpbjxWb2lkPiBjaGFpbiA9IGZ1dHVyZXNVdGlsLm5ld1NlcXVlbnRpYWxDaGFpbigpOworICAgIGNoYWluCisgICAgICAgIC5jaGFpbkFzeW5jKGFwcGVuZEludEFzeW5jKHNiLCAwKSkKKyAgICAgICAgLmNoYWluKGFwcGVuZEludERpcmVjdChzYiwgMSkpCisgICAgICAgIC5jaGFpbigKKyAgICAgICAgICAgIHZvaWRBcmcgLT4geworICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigiVGhlIGVycm9yIG1lc3NhZ2UuIik7CisgICAgICAgICAgICB9KQorICAgICAgICAuY2hhaW4oYXBwZW5kSW50RGlyZWN0KHNiLCAyKSkKKyAgICAgICAgLmNoYWluQXN5bmMoYXBwZW5kSW50QXN5bmMoc2IsIDMpKTsKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZXggPSBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCBjaGFpbi5zdGFydCgpOjpnZXQpOworICAgIGFzc2VydFRoYXQoZXgpLmhhc0NhdXNlVGhhdCgpLmlzSW5zdGFuY2VPZihSdW50aW1lRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBhc3NlcnRUaGF0KGV4KS5oYXNNZXNzYWdlVGhhdCgpLmNvbnRhaW5zKCJUaGUgZXJyb3IgbWVzc2FnZS4iKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIEZ1bmN0aW9uPFZvaWQsIFZvaWQ+IGFwcGVuZEludERpcmVjdChTdHJpbmdCdWlsZGVyIHNiLCBpbnQgaSkgeworICAgIHJldHVybiB2b2lkQXJnIC0+IHsKKyAgICAgIHNiLmFwcGVuZChpKTsKKyAgICAgIHJldHVybiBudWxsOworICAgIH07CisgIH0KKworICBwcml2YXRlIHN0YXRpYyBGdW5jdGlvbjxWb2lkLCBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+PiBhcHBlbmRJbnRBc3luYyhTdHJpbmdCdWlsZGVyIHNiLCBpbnQgaSkgeworICAgIHJldHVybiB2b2lkQXJnIC0+IHsKKyAgICAgIHNiLmFwcGVuZChpKTsKKyAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKTsKKyAgICB9OworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC9Qcm90b0NvbnZlcnNpb25VdGlsVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvUHJvdG9Db252ZXJzaW9uVXRpbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZGQzNjZkCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvUHJvdG9Db252ZXJzaW9uVXRpbFRlc3QuamF2YQpAQCAtMCwwICsxLDI3NSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwudXRpbDsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworCitpbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWR4LnRlc3QuY29yZS5hcHAuQXBwbGljYXRpb25Qcm92aWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5BbmRyb2lkRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5KYXZhRmlsZUJhY2tlbmQ7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLlJlYWRCeXRlQXJyYXlPcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWRkVGVzdFV0aWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnRydXRoLkNvcnJlc3BvbmRlbmNlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uQmFzZUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlR3JvdXA7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZUdyb3VwLkFsbG93ZWRSZWFkZXJzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGVsdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRG93bmxvYWRDb25kaXRpb25zOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRG93bmxvYWRDb25kaXRpb25zLkRldmljZU5ldHdvcmtQb2xpY3k7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5Eb3dubG9hZENvbmRpdGlvbnMuRGV2aWNlU3RvcmFnZVBvbGljeTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkV4dHJhSHR0cEhlYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5Db21wcmVzc1RyYW5zZm9ybTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5UcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuVHJhbnNmb3JtUHJvdG8uVHJhbnNmb3JtczsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5UcmFuc2Zvcm1Qcm90by5aaXBUcmFuc2Zvcm07CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwuTWV0YWRhdGFQcm90bzsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBCb29ra2VlcGluZzsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkRhdGFGaWxlR3JvdXBJbnRlcm5hbDsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZTsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLmNvbnRyaWIuYW5kcm9pZC5Qcm90b1BhcnNlcnM7CitpbXBvcnQgY29tLmdvb2dsZS50ZXN0aW5nLnV0aWwuVGVzdFV0aWw7CitpbXBvcnQgamF2YS5pby5GaWxlOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9KVW5pdDsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvUnVsZTsKK2ltcG9ydCBvcmcucm9ib2xlY3RyaWMuUm9ib2xlY3RyaWNUZXN0UnVubmVyOworCisvKiogVW5pdCB0ZXN0cyBmb3Ige0BsaW5rIFByb3RvQ29udmVyc2lvblV0aWx9LiAqLworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIFByb3RvQ29udmVyc2lvblV0aWxUZXN0IHsKKworICBAUnVsZSBwdWJsaWMgZmluYWwgTW9ja2l0b1J1bGUgbW9ja3MgPSBNb2NraXRvSlVuaXQucnVsZSgpOworCisgIHByaXZhdGUgU3luY2hyb25vdXNGaWxlU3RvcmFnZSBmaWxlU3RvcmFnZTsKKyAgcHJpdmF0ZSBDb250ZXh0IGNvbnRleHQ7CisKKyAgLy8gVGhlIHJhdyB0ZXN0IGRhdGEgZm9sZGVyIGluIGdvb2dsZTMuCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBURVNUX0RBVEFfRElSID0KKyAgICAgIFRlc3RVdGlsLmdldFJ1bmZpbGVzRGlyKCkKKyAgICAgICAgICArICIvZ29vZ2xlMy90aGlyZF9wYXJ0eS9qYXZhX3NyYy9hbmRyb2lkX2xpYnMvbW9iaWxlZGF0YWRvd25sb2FkL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL3Rlc3RkYXRhLyI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpbGUgUkFXX0dST1VQX1dJVEhfRVhURU5TSU9OID0KKyAgICAgIG5ldyBGaWxlKFRFU1RfREFUQV9ESVIsICJyYXdfZ3JvdXBfd2l0aF9leHRlbnNpb24iKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgY29udGV4dCA9IEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCk7CisgICAgZmlsZVN0b3JhZ2UgPQorICAgICAgICBuZXcgU3luY2hyb25vdXNGaWxlU3RvcmFnZSgKKyAgICAgICAgICAgIEltbXV0YWJsZUxpc3Qub2YoQW5kcm9pZEZpbGVCYWNrZW5kLmJ1aWxkZXIoY29udGV4dCkuYnVpbGQoKSwgbmV3IEphdmFGaWxlQmFja2VuZCgpKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjb252ZXJ0X2Zyb21EYXRhRmlsZUdyb3VwX3RvRGF0YUZpbGVHcm91cEludGVybmFsX25vVGhyb3coKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEYXRhRmlsZUdyb3VwIGdyb3VwID0KKyAgICAgICAgRGF0YUZpbGVHcm91cC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoInRlc3QtZ3JvdXAiKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZSgiY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQiKQorICAgICAgICAgICAgLnNldEZpbGVHcm91cFZlcnNpb25OdW1iZXIoMTIpCisgICAgICAgICAgICAuc2V0QWxsb3dlZFJlYWRlcnNFbnVtKEFsbG93ZWRSZWFkZXJzLkFMTF9HT09HTEVfQVBQUykKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbmRpdGlvbnMoCisgICAgICAgICAgICAgICAgRG93bmxvYWRDb25kaXRpb25zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RGV2aWNlTmV0d29ya1BvbGljeShEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKQorICAgICAgICAgICAgICAgICAgICAuc2V0RGV2aWNlU3RvcmFnZVBvbGljeShEZXZpY2VTdG9yYWdlUG9saWN5LkJMT0NLX0RPV05MT0FEX0xPV0VSX1RIUkVTSE9MRCkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuc2V0RXhwaXJhdGlvbkRhdGUoMTIzNDU2Nzg5MCkKKyAgICAgICAgICAgIC5zZXRTdGFsZUxpZmV0aW1lU2VjcygxMjM0NTYpCisgICAgICAgICAgICAuc2V0VHJhZmZpY1RhZygzKQorICAgICAgICAgICAgLnNldFByZXNlcnZlRmlsZW5hbWVzQW5kSXNvbGF0ZUZpbGVzKHRydWUpCisgICAgICAgICAgICAuYWRkQWxsRmlsZSgKKyAgICAgICAgICAgICAgICBJbW11dGFibGVMaXN0Lm9mKAorICAgICAgICAgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoIm9uZSIpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0Qnl0ZVNpemUoMjAwKQorICAgICAgICAgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vIikKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bSgiY2hlY2tzdW0xIikKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpLAorICAgICAgICAgICAgICAgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRGaWxlSWQoInR3byIpCisgICAgICAgICAgICAgICAgICAgICAgICAuc2V0Qnl0ZVNpemUoNTAwKQorICAgICAgICAgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoImh0dHBzOi8vd3d3Lmluc3RhZ3JhbS5jb20vIikKKyAgICAgICAgICAgICAgICAgICAgICAgIC5zZXRDaGVja3N1bSgiY2hlY2tzdW0yIikKKyAgICAgICAgICAgICAgICAgICAgICAgIC5idWlsZCgpKSkKKyAgICAgICAgICAgIC5hZGRBbGxHcm91cEV4dHJhSHR0cEhlYWRlcnMoCisgICAgICAgICAgICAgICAgSW1tdXRhYmxlTGlzdC5vZigKKyAgICAgICAgICAgICAgICAgICAgRXh0cmFIdHRwSGVhZGVyLm5ld0J1aWxkZXIoKS5zZXRLZXkoImsxIikuc2V0VmFsdWUoInYxIikuYnVpbGQoKSwKKyAgICAgICAgICAgICAgICAgICAgRXh0cmFIdHRwSGVhZGVyLm5ld0J1aWxkZXIoKS5zZXRLZXkoImsyIikuc2V0VmFsdWUoInYyIikuYnVpbGQoKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgdW51c2VkID0gUHJvdG9Db252ZXJzaW9uVXRpbC5jb252ZXJ0KGdyb3VwKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNvbnZlcnRfZnJvbURhdGFGaWxlR3JvdXBfdG9EYXRhRmlsZUdyb3VwSW50ZXJuYWxfcGFyc2VGcm9tVGV4dFByb3RvKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cCA9IGdldERhdGFGaWxlR3JvdXBGcm9tVGV4dFByb3RvKFIucmF3Lmdyb3VwX2RhdGFfcGIpOworICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbCBkYXRhRmlsZUdyb3VwSW50ZXJuYWwgPQorICAgICAgICBnZXREYXRhRmlsZUdyb3VwSW50ZXJuYWxGcm9tVGV4dFByb3RvKFIucmF3Lmdyb3VwX2ludGVybmFsX2RhdGFfcGIpOworICAgIGFzc2VydFRoYXQoUHJvdG9Db252ZXJzaW9uVXRpbC5jb252ZXJ0KGRhdGFGaWxlR3JvdXApKS5pc0VxdWFsVG8oZGF0YUZpbGVHcm91cEludGVybmFsKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNvbnZlcnRfZnJvbURhdGFGaWxlR3JvdXBfdG9EYXRhRmlsZUdyb3VwSW50ZXJuYWxfcGFyc2VGcm9tVGV4dFByb3RvX29wdGlvbmFsVW5zZXQoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cCBkYXRhRmlsZUdyb3VwID0gZ2V0RGF0YUZpbGVHcm91cEZyb21UZXh0UHJvdG8oUi5yYXcuZ3JvdXBfb3B0aW9uYWxfdW5zZXRfZGF0YV9wYik7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGRhdGFGaWxlR3JvdXBJbnRlcm5hbCA9CisgICAgICAgIGdldERhdGFGaWxlR3JvdXBJbnRlcm5hbEZyb21UZXh0UHJvdG8oUi5yYXcuZ3JvdXBfaW50ZXJuYWxfb3B0aW9uYWxfdW5zZXRfZGF0YV9wYik7CisgICAgYXNzZXJ0VGhhdChQcm90b0NvbnZlcnNpb25VdGlsLmNvbnZlcnQoZGF0YUZpbGVHcm91cCkpLmlzRXF1YWxUbyhkYXRhRmlsZUdyb3VwSW50ZXJuYWwpOworICB9CisKKyAgLyoqCisgICAqIFRoZSBtYWluIHB1cnBvc2Ugb2YgdGhpcyB0ZXN0IGlzIHRvIG1ha2Ugc3VyZSB0aGF0IGFmdGVyIG1pZ3JhdGlvbiwgd2UgYXJlIHN0aWxsIGFibGUgdG8KKyAgICogaW50ZXJwcmV0IGFuZCBwYXJzZSB0aGUgZ3JvdXAgbWV0YWRhdGEgY29ycmVjdGx5LiBUaGUgcmF3IG1ldGFkYXRhIHdhcyBnZW5lcmF0ZWQgYnkgdGhlIHByb3RvCisgICAqIHtAbGluayBEYXRhRmlsZUdyb3VwfSB3aXRoIGV4dGVuc2lvbnMgYmVmb3JlIHRoZSBtaWdyYXRpb24uIFNpbmNlIHdlIHJldXNlIHRoZSBzYW1lIHRhZyBudW1iZXIsCisgICAqIHRoZSBleHRlbnNpb24gc2hvdWxkIG5vdyBiZSBwYXJzZWQgaW50byB7QGxpbmsgRGF0YUZpbGVHcm91cEJvb2trZWVwaW5nfS4KKyAgICovCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGNvbnZlcnRfcGFyc2VSYXdQcm90b1dpdGhFeHRlbnNpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIGV4cGVjdGVkID0KKyAgICAgICAgUHJvdG9Db252ZXJzaW9uVXRpbC5jb252ZXJ0KAorICAgICAgICAgICAgICAgIE1kZFRlc3RVdGlsLmNyZWF0ZURhdGFGaWxlR3JvdXAoLypmaWxlR3JvdXBOYW1lPSovICJ0ZXN0LWdyb3VwIiwgMikpCisgICAgICAgICAgICAudG9CdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRCb29ra2VlcGluZygKKyAgICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRHcm91cE5ld0ZpbGVzUmVjZWl2ZWRUaW1lc3RhbXAoMTAwMCkKKyAgICAgICAgICAgICAgICAgICAgLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIFJlYWQgdGhlIHJhdyBncm91cCB3aXRoIGV4dGVuc2lvbiBmcm9tIGZpbGUuCisgICAgVXJpIHVyaSA9IFVyaS5mcm9tRmlsZShSQVdfR1JPVVBfV0lUSF9FWFRFTlNJT04pOworICAgIGJ5dGVbXSBieXRlcyA9IGZpbGVTdG9yYWdlLm9wZW4odXJpLCBSZWFkQnl0ZUFycmF5T3BlbmVyLmNyZWF0ZSgpKTsKKworICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBwcm90byB3aXRoIGV4dGVuc2lvbiBpcyBjb3JyZWNseSBwYXJzZWQuCisgICAgRGF0YUZpbGVHcm91cEludGVybmFsIHBhcnNlZEZyb21SYXdQcm90byA9CisgICAgICAgIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5wYXJzZUZyb20oYnl0ZXMsIEV4dGVuc2lvblJlZ2lzdHJ5TGl0ZS5nZXRFbXB0eVJlZ2lzdHJ5KCkpOworICAgIGFzc2VydFRoYXQocGFyc2VkRnJvbVJhd1Byb3RvKS5pc0VxdWFsVG8oZXhwZWN0ZWQpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY29udmVydF9vbkRvd25sb2FkQ29uZGl0aW9ucygpIHRocm93cyBFeGNlcHRpb24geworICAgIERvd25sb2FkQ29uZGl0aW9ucyBkb3dubG9hZENvbmRpdGlvbnMgPQorICAgICAgICBEb3dubG9hZENvbmRpdGlvbnMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGV2aWNlTmV0d29ya1BvbGljeShEZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKQorICAgICAgICAgICAgLnNldERldmljZVN0b3JhZ2VQb2xpY3koRGV2aWNlU3RvcmFnZVBvbGljeS5CTE9DS19ET1dOTE9BRF9MT1dFUl9USFJFU0hPTEQpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBNZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9ucyBjb252ZXJ0ZWREb3dubG9hZENvbmRpdGlvbnMgPQorICAgICAgICBQcm90b0NvbnZlcnNpb25VdGlsLmNvbnZlcnQoZG93bmxvYWRDb25kaXRpb25zKTsKKyAgICBhc3NlcnRUaGF0KGNvbnZlcnRlZERvd25sb2FkQ29uZGl0aW9ucy5oYXNEZXZpY2VTdG9yYWdlUG9saWN5KCkpLmlzVHJ1ZSgpOworICAgIGFzc2VydFRoYXQoY29udmVydGVkRG93bmxvYWRDb25kaXRpb25zLmhhc0RldmljZU5ldHdvcmtQb2xpY3koKSkuaXNUcnVlKCk7CisgICAgYXNzZXJ0VGhhdChjb252ZXJ0ZWREb3dubG9hZENvbmRpdGlvbnMuaGFzRG93bmxvYWRGaXJzdE9uV2lmaVBlcmlvZFNlY3MoKSkuaXNGYWxzZSgpOworICAgIGFzc2VydFRoYXQoY29udmVydGVkRG93bmxvYWRDb25kaXRpb25zLmdldERldmljZU5ldHdvcmtQb2xpY3koKSkKKyAgICAgICAgLmlzRXF1YWxUbyhNZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VOZXR3b3JrUG9saWN5LkRPV05MT0FEX09OX0FOWV9ORVRXT1JLKTsKKyAgICBhc3NlcnRUaGF0KGNvbnZlcnRlZERvd25sb2FkQ29uZGl0aW9ucy5nZXREZXZpY2VTdG9yYWdlUG9saWN5KCkpCisgICAgICAgIC5pc0VxdWFsVG8oCisgICAgICAgICAgICBNZXRhZGF0YVByb3RvLkRvd25sb2FkQ29uZGl0aW9ucy5EZXZpY2VTdG9yYWdlUG9saWN5LkJMT0NLX0RPV05MT0FEX0xPV0VSX1RIUkVTSE9MRCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjb252ZXJ0RGF0YUZpbGVfY29udmVydHNGaWVsZHMoKSB7CisgICAgVHJhbnNmb3JtcyBkb3dubG9hZFRyYW5zZm9ybXMgPQorICAgICAgICBUcmFuc2Zvcm1zLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZFRyYW5zZm9ybSgKKyAgICAgICAgICAgICAgICBUcmFuc2Zvcm0ubmV3QnVpbGRlcigpLnNldENvbXByZXNzKENvbXByZXNzVHJhbnNmb3JtLmdldERlZmF1bHRJbnN0YW5jZSgpKS5idWlsZCgpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgVHJhbnNmb3JtcyByZWFkVHJhbnNmb3JtcyA9CisgICAgICAgIFRyYW5zZm9ybXMubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkVHJhbnNmb3JtKFRyYW5zZm9ybS5uZXdCdWlsZGVyKCkuc2V0WmlwKFppcFRyYW5zZm9ybS5nZXREZWZhdWx0SW5zdGFuY2UoKSkuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgRGF0YUZpbGUgZGF0YUZpbGVFeHRlcm5hbCA9CisgICAgICAgIERhdGFGaWxlLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVJZCgidGVzdC1maWxlIikKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJodHRwczovL3VybC50by5kb3dubG9hZCIpCisgICAgICAgICAgICAuc2V0Qnl0ZVNpemUoMTApCisgICAgICAgICAgICAuc2V0Q2hlY2tzdW1UeXBlKERhdGFGaWxlLkNoZWNrc3VtVHlwZS5OT05FKQorICAgICAgICAgICAgLnNldENoZWNrc3VtKCJ0ZXN0Y2hlY2tzdW0iKQorICAgICAgICAgICAgLnNldERvd25sb2FkVHJhbnNmb3Jtcyhkb3dubG9hZFRyYW5zZm9ybXMpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bSgidGVzdGRvd25sb2FkZWRjaGVja3N1bSIpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRlZEZpbGVCeXRlU2l6ZSgxMDApCisgICAgICAgICAgICAuc2V0UmVhZFRyYW5zZm9ybXMocmVhZFRyYW5zZm9ybXMpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJpbmdUeXBlKERhdGFGaWxlLkFuZHJvaWRTaGFyaW5nVHlwZS5BTkRST0lEX0JMT0JfV0hFTl9BVkFJTEFCTEUpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bVR5cGUoRGF0YUZpbGUuQW5kcm9pZFNoYXJpbmdDaGVja3N1bVR5cGUuU0hBMl8yNTYpCisgICAgICAgICAgICAuc2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgidGVzdGFuZHJvaWRzaGFyaW5nY2hlY2tzdW0iKQorICAgICAgICAgICAgLnNldFJlbGF0aXZlRmlsZVBhdGgoInJlbGF0aXZlL2ZpbGUvcGF0aCIpCisgICAgICAgICAgICAuYWRkRGVsdGFGaWxlKERlbHRhRmlsZS5uZXdCdWlsZGVyKCkuc2V0VXJsVG9Eb3dubG9hZCgidXJsMSIpLmJ1aWxkKCkpCisgICAgICAgICAgICAuYWRkRGVsdGFGaWxlKERlbHRhRmlsZS5uZXdCdWlsZGVyKCkuc2V0VXJsVG9Eb3dubG9hZCgidXJsMiIpLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIE1ldGFkYXRhUHJvdG8uRGF0YUZpbGUgZGF0YUZpbGVJbnRlcm5hbCA9IFByb3RvQ29udmVyc2lvblV0aWwuY29udmVydERhdGFGaWxlKGRhdGFGaWxlRXh0ZXJuYWwpOworCisgICAgYXNzZXJ0VGhhdChkYXRhRmlsZUludGVybmFsLmdldEZpbGVJZCgpKS5pc0VxdWFsVG8oInRlc3QtZmlsZSIpOworICAgIGFzc2VydFRoYXQoZGF0YUZpbGVJbnRlcm5hbC5nZXRVcmxUb0Rvd25sb2FkKCkpLmlzRXF1YWxUbygiaHR0cHM6Ly91cmwudG8uZG93bmxvYWQiKTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlSW50ZXJuYWwuZ2V0Qnl0ZVNpemUoKSkuaXNFcXVhbFRvKDEwKTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlSW50ZXJuYWwuZ2V0Q2hlY2tzdW1UeXBlKCkpCisgICAgICAgIC5pc0VxdWFsVG8oTWV0YWRhdGFQcm90by5EYXRhRmlsZS5DaGVja3N1bVR5cGUuTk9ORSk7CisgICAgYXNzZXJ0VGhhdChkYXRhRmlsZUludGVybmFsLmdldENoZWNrc3VtKCkpLmlzRXF1YWxUbygidGVzdGNoZWNrc3VtIik7CisgICAgYXNzZXJ0VGhhdChkYXRhRmlsZUludGVybmFsLmdldERvd25sb2FkVHJhbnNmb3JtcygpKS5pc0VxdWFsVG8oZG93bmxvYWRUcmFuc2Zvcm1zKTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlSW50ZXJuYWwuZ2V0RG93bmxvYWRlZEZpbGVDaGVja3N1bSgpKS5pc0VxdWFsVG8oInRlc3Rkb3dubG9hZGVkY2hlY2tzdW0iKTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlSW50ZXJuYWwuZ2V0RG93bmxvYWRlZEZpbGVCeXRlU2l6ZSgpKS5pc0VxdWFsVG8oMTAwKTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlSW50ZXJuYWwuZ2V0UmVhZFRyYW5zZm9ybXMoKSkuaXNFcXVhbFRvKHJlYWRUcmFuc2Zvcm1zKTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlSW50ZXJuYWwuZ2V0QW5kcm9pZFNoYXJpbmdUeXBlKCkpCisgICAgICAgIC5pc0VxdWFsVG8oTWV0YWRhdGFQcm90by5EYXRhRmlsZS5BbmRyb2lkU2hhcmluZ1R5cGUuQU5EUk9JRF9CTE9CX1dIRU5fQVZBSUxBQkxFKTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlSW50ZXJuYWwuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bVR5cGUoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhNZXRhZGF0YVByb3RvLkRhdGFGaWxlLkFuZHJvaWRTaGFyaW5nQ2hlY2tzdW1UeXBlLlNIQTJfMjU2KTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlSW50ZXJuYWwuZ2V0QW5kcm9pZFNoYXJpbmdDaGVja3N1bSgpKQorICAgICAgICAuaXNFcXVhbFRvKCJ0ZXN0YW5kcm9pZHNoYXJpbmdjaGVja3N1bSIpOworICAgIGFzc2VydFRoYXQoZGF0YUZpbGVJbnRlcm5hbC5nZXRSZWxhdGl2ZUZpbGVQYXRoKCkpLmlzRXF1YWxUbygicmVsYXRpdmUvZmlsZS9wYXRoIik7CisKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlSW50ZXJuYWwuZ2V0RGVsdGFGaWxlQ291bnQoKSkuaXNFcXVhbFRvKDIpOworICAgIGFzc2VydFRoYXQoZGF0YUZpbGVJbnRlcm5hbC5nZXREZWx0YUZpbGVMaXN0KCkpCisgICAgICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKAorICAgICAgICAgICAgQ29ycmVzcG9uZGVuY2UudHJhbnNmb3JtaW5nKE1ldGFkYXRhUHJvdG8uRGVsdGFGaWxlOjpnZXRVcmxUb0Rvd25sb2FkLCAidXNpbmcgdXJsIikpCisgICAgICAgIC5jb250YWluc0V4YWN0bHkoInVybDEiLCAidXJsMiIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY29udmVydERlbHRhRmlsZV9jb252ZXJ0c0ZpZWxkcygpIHsKKyAgICBEZWx0YUZpbGUgZGVsdGFGaWxlRXh0ZXJuYWwgPQorICAgICAgICBEZWx0YUZpbGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaHR0cHM6Ly91cmwudG8uZG93bmxvYWQiKQorICAgICAgICAgICAgLnNldEJ5dGVTaXplKDEwKQorICAgICAgICAgICAgLnNldENoZWNrc3VtKCJ0ZXN0Y2hlY2tzdW0iKQorICAgICAgICAgICAgLnNldERpZmZEZWNvZGVyKERlbHRhRmlsZS5EaWZmRGVjb2Rlci5WQ19ESUZGKQorICAgICAgICAgICAgLnNldEJhc2VGaWxlKEJhc2VGaWxlLm5ld0J1aWxkZXIoKS5zZXRDaGVja3N1bSgidGVzdGJhc2VjaGVja3N1bSIpLmJ1aWxkKCkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIE1ldGFkYXRhUHJvdG8uRGVsdGFGaWxlIGRlbHRhRmlsZUludGVybmFsID0KKyAgICAgICAgUHJvdG9Db252ZXJzaW9uVXRpbC5jb252ZXJ0RGVsdGFGaWxlKGRlbHRhRmlsZUV4dGVybmFsKTsKKworICAgIGFzc2VydFRoYXQoZGVsdGFGaWxlSW50ZXJuYWwuZ2V0VXJsVG9Eb3dubG9hZCgpKS5pc0VxdWFsVG8oImh0dHBzOi8vdXJsLnRvLmRvd25sb2FkIik7CisgICAgYXNzZXJ0VGhhdChkZWx0YUZpbGVJbnRlcm5hbC5nZXRCeXRlU2l6ZSgpKS5pc0VxdWFsVG8oMTApOworICAgIGFzc2VydFRoYXQoZGVsdGFGaWxlSW50ZXJuYWwuZ2V0Q2hlY2tzdW0oKSkuaXNFcXVhbFRvKCJ0ZXN0Y2hlY2tzdW0iKTsKKyAgICBhc3NlcnRUaGF0KGRlbHRhRmlsZUludGVybmFsLmdldERpZmZEZWNvZGVyKCkpCisgICAgICAgIC5pc0VxdWFsVG8oTWV0YWRhdGFQcm90by5EZWx0YUZpbGUuRGlmZkRlY29kZXIuVkNfRElGRik7CisgICAgYXNzZXJ0VGhhdChkZWx0YUZpbGVJbnRlcm5hbC5nZXRCYXNlRmlsZSgpLmdldENoZWNrc3VtKCkpLmlzRXF1YWxUbygidGVzdGJhc2VjaGVja3N1bSIpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgRGF0YUZpbGVHcm91cCBnZXREYXRhRmlsZUdyb3VwRnJvbVRleHRQcm90byhpbnQgcmF3UmVzSWQpIHsKKyAgICByZXR1cm4gUHJvdG9QYXJzZXJzLnBhcnNlRnJvbVJhd1JlcygKKyAgICAgICAgQXBwbGljYXRpb25Qcm92aWRlci5nZXRBcHBsaWNhdGlvbkNvbnRleHQoKSwgRGF0YUZpbGVHcm91cC5wYXJzZXIoKSwgcmF3UmVzSWQpOworICB9CisKKyAgcHJpdmF0ZSBzdGF0aWMgRGF0YUZpbGVHcm91cEludGVybmFsIGdldERhdGFGaWxlR3JvdXBJbnRlcm5hbEZyb21UZXh0UHJvdG8oaW50IHJhd1Jlc0lkKSB7CisgICAgcmV0dXJuIFByb3RvUGFyc2Vycy5wYXJzZUZyb21SYXdSZXMoCisgICAgICAgIEFwcGxpY2F0aW9uUHJvdmlkZXIuZ2V0QXBwbGljYXRpb25Db250ZXh0KCksIERhdGFGaWxlR3JvdXBJbnRlcm5hbC5wYXJzZXIoKSwgcmF3UmVzSWQpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC90ZXN0ZGF0YS9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL3Rlc3RkYXRhL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdiOGI4ZWIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC90ZXN0ZGF0YS9CVUlMRApAQCAtMCwwICsxLDY3IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCIvL3Rvb2xzL2J1aWxkX3J1bGVzL3RleHRfdG9fYmluYXJ5OmRlZi5iemwiLCAicHJvdG9fZGF0YSIpCisKK3BhY2thZ2UoCisgICAgZGVmYXVsdF92aXNpYmlsaXR5ID0gWyIvLzpfX3N1YnBhY2thZ2VzX18iXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK2ZpbGVncm91cCgKKyAgICBuYW1lID0gInJhd19ncm91cCIsCisgICAgdGVzdG9ubHkgPSAxLAorICAgIHNyY3MgPSBbCisgICAgICAgICJyYXdfZ3JvdXBfd2l0aF9leHRlbnNpb24iLAorICAgIF0sCispCisKK3Byb3RvX2RhdGEoCisgICAgbmFtZSA9ICJncm91cC5wYiIsCisgICAgc3JjID0gImdyb3VwLnBiLnR4dCIsCisgICAgb3V0ID0gInJlcy9yYXcvZ3JvdXBfZGF0YV9wYiIsCisgICAgcHJvdG9fZGVwcyA9IFsKKyAgICAgICAgIi8vcHJvdG86ZG93bmxvYWRfY29uZmlnX3Byb3RvIiwKKyAgICBdLAorICAgIHByb3RvX25hbWUgPSAibWRpLmRvd25sb2FkLkRhdGFGaWxlR3JvdXAiLAorKQorCitwcm90b19kYXRhKAorICAgIG5hbWUgPSAiZ3JvdXBfaW50ZXJuYWwucGIiLAorICAgIHNyYyA9ICJncm91cF9pbnRlcm5hbC5wYi50eHQiLAorICAgIG91dCA9ICJyZXMvcmF3L2dyb3VwX2ludGVybmFsX2RhdGFfcGIiLAorICAgIHByb3RvX2RlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvcHJvdG86bWV0YWRhdGFfcHJvdG8iLAorICAgIF0sCisgICAgcHJvdG9fbmFtZSA9ICJtZGkuZG93bmxvYWQuaW50ZXJuYWwuRGF0YUZpbGVHcm91cEludGVybmFsIiwKKykKKworcHJvdG9fZGF0YSgKKyAgICBuYW1lID0gImdyb3VwX29wdGlvbmFsX3Vuc2V0LnBiIiwKKyAgICBzcmMgPSAiZ3JvdXBfb3B0aW9uYWxfdW5zZXQucGIudHh0IiwKKyAgICBvdXQgPSAicmVzL3Jhdy9ncm91cF9vcHRpb25hbF91bnNldF9kYXRhX3BiIiwKKyAgICBwcm90b19kZXBzID0gWworICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfcHJvdG8iLAorICAgIF0sCisgICAgcHJvdG9fbmFtZSA9ICJtZGkuZG93bmxvYWQuRGF0YUZpbGVHcm91cCIsCispCisKK3Byb3RvX2RhdGEoCisgICAgbmFtZSA9ICJncm91cF9pbnRlcm5hbF9vcHRpb25hbF91bnNldC5wYiIsCisgICAgc3JjID0gImdyb3VwX2ludGVybmFsX29wdGlvbmFsX3Vuc2V0LnBiLnR4dCIsCisgICAgb3V0ID0gInJlcy9yYXcvZ3JvdXBfaW50ZXJuYWxfb3B0aW9uYWxfdW5zZXRfZGF0YV9wYiIsCisgICAgcHJvdG9fZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9wcm90bzptZXRhZGF0YV9wcm90byIsCisgICAgXSwKKyAgICBwcm90b19uYW1lID0gIm1kaS5kb3dubG9hZC5pbnRlcm5hbC5EYXRhRmlsZUdyb3VwSW50ZXJuYWwiLAorKQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvdGVzdGRhdGEvZ3JvdXAucGIudHh0IGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvdGVzdGRhdGEvZ3JvdXAucGIudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2Mjc1ZDMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC90ZXN0ZGF0YS9ncm91cC5wYi50eHQKQEAgLTAsMCArMSwyMSBAQAorYWxsb3dlZF9yZWFkZXJzX2VudW06IEFMTF9HT09HTEVfQVBQUworZG93bmxvYWRfY29uZGl0aW9ucyB7CisgIGRldmljZV9uZXR3b3JrX3BvbGljeTogRE9XTkxPQURfRklSU1RfT05fV0lGSV9USEVOX09OX0FOWV9ORVRXT1JLCit9CitmaWxlX2dyb3VwX3ZlcnNpb25fbnVtYmVyOiAxMgorZmlsZSB7CisgIGJ5dGVfc2l6ZTogMjAwCisgIGNoZWNrc3VtOiAiY2hlY2tzdW0xIgorICBmaWxlX2lkOiAib25lIgorICB1cmxfdG9fZG93bmxvYWQ6ICJodHRwczovL3d3dy5nb29nbGUuY29tLyIKK30KK2ZpbGUgeworICBieXRlX3NpemU6IDUwMAorICBjaGVja3N1bTogImNoZWNrc3VtMiIKKyAgZmlsZV9pZDogInR3byIKKyAgdXJsX3RvX2Rvd25sb2FkOiAiaHR0cHM6Ly93d3cuaW5zdGFncmFtLmNvbS8iCit9Citncm91cF9uYW1lOiAidGVzdC1ncm91cCIKK293bmVyX3BhY2thZ2U6ICJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZCIKK3N0YWxlX2xpZmV0aW1lX3NlY3M6IDEyMzQ1NgordHJhZmZpY190YWc6IDMKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL3Rlc3RkYXRhL2dyb3VwX2ludGVybmFsLnBiLnR4dCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL3Rlc3RkYXRhL2dyb3VwX2ludGVybmFsLnBiLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjI3NWQzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvdGVzdGRhdGEvZ3JvdXBfaW50ZXJuYWwucGIudHh0CkBAIC0wLDAgKzEsMjEgQEAKK2FsbG93ZWRfcmVhZGVyc19lbnVtOiBBTExfR09PR0xFX0FQUFMKK2Rvd25sb2FkX2NvbmRpdGlvbnMgeworICBkZXZpY2VfbmV0d29ya19wb2xpY3k6IERPV05MT0FEX0ZJUlNUX09OX1dJRklfVEhFTl9PTl9BTllfTkVUV09SSworfQorZmlsZV9ncm91cF92ZXJzaW9uX251bWJlcjogMTIKK2ZpbGUgeworICBieXRlX3NpemU6IDIwMAorICBjaGVja3N1bTogImNoZWNrc3VtMSIKKyAgZmlsZV9pZDogIm9uZSIKKyAgdXJsX3RvX2Rvd25sb2FkOiAiaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS8iCit9CitmaWxlIHsKKyAgYnl0ZV9zaXplOiA1MDAKKyAgY2hlY2tzdW06ICJjaGVja3N1bTIiCisgIGZpbGVfaWQ6ICJ0d28iCisgIHVybF90b19kb3dubG9hZDogImh0dHBzOi8vd3d3Lmluc3RhZ3JhbS5jb20vIgorfQorZ3JvdXBfbmFtZTogInRlc3QtZ3JvdXAiCitvd25lcl9wYWNrYWdlOiAiY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQiCitzdGFsZV9saWZldGltZV9zZWNzOiAxMjM0NTYKK3RyYWZmaWNfdGFnOiAzCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC90ZXN0ZGF0YS9ncm91cF9pbnRlcm5hbF9vcHRpb25hbF91bnNldC5wYi50eHQgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC90ZXN0ZGF0YS9ncm91cF9pbnRlcm5hbF9vcHRpb25hbF91bnNldC5wYi50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmVkNzFhOQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL3Rlc3RkYXRhL2dyb3VwX2ludGVybmFsX29wdGlvbmFsX3Vuc2V0LnBiLnR4dApAQCAtMCwwICsxLDE4IEBACithbGxvd2VkX3JlYWRlcnNfZW51bTogQUxMX0dPT0dMRV9BUFBTCitmaWxlIHsKKyAgY2hlY2tzdW1fdHlwZTogTk9ORQorICBmaWxlX2lkOiAib25lIgorICB1cmxfdG9fZG93bmxvYWQ6ICJodHRwczovL3d3dy5nb29nbGUuY29tLyIKK30KK2ZpbGUgeworICBjaGVja3N1bV90eXBlOiBOT05FCisgIGZpbGVfaWQ6ICJ0d28iCisgIHVybF90b19kb3dubG9hZDogImh0dHBzOi8vd3d3Lmluc3RhZ3JhbS5jb20vIgorfQorZmlsZSB7CisgIGNoZWNrc3VtX3R5cGU6IE5PTkUKKyAgZmlsZV9pZDogInRocmVlIgorICB1cmxfdG9fZG93bmxvYWQ6ICJodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tLyIKK30KK2dyb3VwX25hbWU6ICJ0ZXN0LWdyb3VwIgorb3duZXJfcGFja2FnZTogImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkIgpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvdGVzdGRhdGEvZ3JvdXBfb3B0aW9uYWxfdW5zZXQucGIudHh0IGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvdGVzdGRhdGEvZ3JvdXBfb3B0aW9uYWxfdW5zZXQucGIudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJlZDcxYTkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvaW50ZXJuYWwvdXRpbC90ZXN0ZGF0YS9ncm91cF9vcHRpb25hbF91bnNldC5wYi50eHQKQEAgLTAsMCArMSwxOCBAQAorYWxsb3dlZF9yZWFkZXJzX2VudW06IEFMTF9HT09HTEVfQVBQUworZmlsZSB7CisgIGNoZWNrc3VtX3R5cGU6IE5PTkUKKyAgZmlsZV9pZDogIm9uZSIKKyAgdXJsX3RvX2Rvd25sb2FkOiAiaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS8iCit9CitmaWxlIHsKKyAgY2hlY2tzdW1fdHlwZTogTk9ORQorICBmaWxlX2lkOiAidHdvIgorICB1cmxfdG9fZG93bmxvYWQ6ICJodHRwczovL3d3dy5pbnN0YWdyYW0uY29tLyIKK30KK2ZpbGUgeworICBjaGVja3N1bV90eXBlOiBOT05FCisgIGZpbGVfaWQ6ICJ0aHJlZSIKKyAgdXJsX3RvX2Rvd25sb2FkOiAiaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS8iCit9Citncm91cF9uYW1lOiAidGVzdC1ncm91cCIKK293bmVyX3BhY2thZ2U6ICJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZCIKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL3Rlc3RkYXRhL3Jhd19ncm91cF93aXRoX2V4dGVuc2lvbiBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC91dGlsL3Rlc3RkYXRhL3Jhd19ncm91cF93aXRoX2V4dGVuc2lvbgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNTRmOGY0Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3V0aWwvdGVzdGRhdGEvcmF3X2dyb3VwX3dpdGhfZXh0ZW5zaW9uCkBAIC0wLDAgKzEsNCBAQAorCisKK3Rlc3QtZ3JvdXASLBIUaHR0cHM6Ly90ZXN0LWdyb3VwXzAgCisqBDEyMzA6DHRlc3QtZ3JvdXBfMBIsEhRodHRwczovL3Rlc3QtZ3JvdXBfMSALKgQxMjMxOgx0ZXN0LWdyb3VwXzHymJO1BwMQ6AcKXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9BbmRyb2lkTWFuaWZlc3QueG1sIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvQW5kcm9pZE1hbmlmZXN0LnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMDgzOTQxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGUvQW5kcm9pZE1hbmlmZXN0LnhtbApAQCAtMCwwICsxLDM2IEBACis8IS0tCisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLS0+Cis8bWFuaWZlc3QKKyAgICB4bWxuczphbmRyb2lkPSJodHRwOi8vc2NoZW1hcy5hbmRyb2lkLmNvbS9hcGsvcmVzL2FuZHJvaWQiCisgICAgcGFja2FnZT0iY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubGl0ZSI+CisKKyAgPHVzZXMtc2RrIGFuZHJvaWQ6bWluU2RrVmVyc2lvbj0iMTYiLz4KKworICA8dXNlcy1wZXJtaXNzaW9uIGFuZHJvaWQ6bmFtZT0iYW5kcm9pZC5wZXJtaXNzaW9uLklOVEVSTkVUIi8+CisgIDx1c2VzLXBlcm1pc3Npb24KKyAgICAgIGFuZHJvaWQ6bmFtZT0iY29tLmdvb2dsZS5hbmRyb2lkLmdtcy5wZXJtaXNzaW9uLkJJTkRfTkVUV09SS19UQVNLX1NFUlZJQ0UiLz4KKyAgPHVzZXMtcGVybWlzc2lvbiBhbmRyb2lkOm5hbWU9ImFuZHJvaWQucGVybWlzc2lvbi5BQ0NFU1NfTkVUV09SS19TVEFURSIvPgorCisgIDxhcHBsaWNhdGlvbiBhbmRyb2lkOm5hbWU9ImFuZHJvaWQuc3VwcG9ydC5tdWx0aWRleC5NdWx0aURleEFwcGxpY2F0aW9uIj4KKyAgPC9hcHBsaWNhdGlvbj4KKworICA8aW5zdHJ1bWVudGF0aW9uCisgICAgICBhbmRyb2lkOm5hbWU9ImNvbS5nb29nbGUuYW5kcm9pZC5hcHBzLmNvbW1vbi50ZXN0aW5nLnRlc3RydW5uZXIuR29vZ2xlM0luc3RydW1lbnRhdGlvblRlc3RSdW5uZXIiCisgICAgICBhbmRyb2lkOnRhcmdldFBhY2thZ2U9ImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmxpdGUiIC8+CisKKzwvbWFuaWZlc3Q+CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9CVUlMRCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ0NDMyN2EKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9CVUlMRApAQCAtMCwwICsxLDU2IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDp0ZXN0X2RlZnMuYnpsIiwgIm1kZF9sb2NhbF90ZXN0IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworbWRkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJEb3dubG9hZFByb2dyZXNzTW9uaXRvclRlc3QiLAorICAgIHNyY3MgPSBbIkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yVGVzdC5qYXZhIl0sCisgICAgdGVzdF9jbGFzcyA9ICJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlLkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yVGVzdCIsCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL3NwaSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZTpEb3dubG9hZExpc3RlbmVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlOkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6RmFrZVRpbWVTb3VyY2UiLAorICAgICAgICAiQGFuZHJvaWRfc2RrX2xpbnV4IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworbWRkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJEb3dubG9hZGVySW1wbFRlc3QiLAorICAgIHNyY3MgPSBbIkRvd25sb2FkZXJJbXBsVGVzdC5qYXZhIl0sCisgICAgbWFuaWZlc3QgPSAiQW5kcm9pZE1hbmlmZXN0LnhtbCIsCisgICAgdGVzdF9jbGFzcyA9ICJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlLkRvd25sb2FkZXJJbXBsVGVzdCIsCisgICAgcnVudGltZV9kZXBzID0gWyIvL3RoaXJkX3BhcnR5L2phdmEvcm9ib2xlY3RyaWM6bXVsdGlkZXgiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyOkZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlOkRvd25sb2FkTGlzdGVuZXIiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGU6RG93bmxvYWRQcm9ncmVzc01vbml0b3IiLAorICAgICAgICAiLy9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZzpCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIkBhbmRyb2lkX3Nka19saW51eCIsCisgICAgICAgICJAYW5kcm9pZHhfdGVzdCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAbW9ja2l0byIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9Eb3dubG9hZFByb2dyZXNzTW9uaXRvclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRhODViMDIKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9Eb3dubG9hZFByb2dyZXNzTW9uaXRvclRlc3QuamF2YQpAQCAtMCwwICsxLDEzNSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubGl0ZTsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlLkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLkJVRkZFUkVEX1RJTUVfTVM7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0Lk1JTExJU0VDT05EUzsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5Tm9JbnRlcmFjdGlvbnM7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5Tm9Nb3JlSW50ZXJhY3Rpb25zOworCitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLk1vbml0b3IuT3V0cHV0TW9uaXRvcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nLkZha2VUaW1lU291cmNlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBEb3dubG9hZFByb2dyZXNzTW9uaXRvclRlc3QgeworCisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgLy8gVXNlIGRpcmVjdEV4ZWN1dG9yIHRvIGVuc3VyZSB0aGUgb3JkZXIgb2YgdGVzdCB2ZXJpZmljYXRpb24uCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEV4ZWN1dG9yIENPTlRST0xfRVhFQ1VUT1IgPSBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfVVJJXzEgPQorICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQuZ21zL2ZpbGVzL2RhdGFkb3dubG9hZC9zaGFyZWQvcHVibGljL2ZpbGVfMSI7CisKKyAgLy8gTm90ZTogV2UgY2FuJ3QgbWFrZSB0aG9zZSBhbmRyb2lkIHVyaXMgc3RhdGljIHZhcmlhYmxlIHNpbmNlIHRoZSBVcmkucGFyc2Ugd2lsbCBmYWlsCisgIC8vIHdpdGggaW5pdGlhbGl6YXRpb24uCisgIHByaXZhdGUgZmluYWwgVXJpIHVyaTEgPSBVcmkucGFyc2UoRklMRV9VUklfMSk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfVVJJXzIgPQorICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQuZ21zL2ZpbGVzL2RhdGFkb3dubG9hZC9zaGFyZWQvcHVibGljL2ZpbGVfMiI7CisgIHByaXZhdGUgZmluYWwgVXJpIHVyaTIgPSBVcmkucGFyc2UoRklMRV9VUklfMik7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEZJTEVfVVJJXzMgPQorICAgICAgImFuZHJvaWQ6Ly9jb20uZ29vZ2xlLmFuZHJvaWQuZ21zL2ZpbGVzL2RhdGFkb3dubG9hZC9zaGFyZWQvcHVibGljL2ZpbGVfMyI7CisgIHByaXZhdGUgZmluYWwgVXJpIHVyaTMgPSBVcmkucGFyc2UoRklMRV9VUklfMyk7CisKKyAgcHJpdmF0ZSBEb3dubG9hZFByb2dyZXNzTW9uaXRvciBkb3dubG9hZE1vbml0b3I7CisgIHByaXZhdGUgZmluYWwgRmFrZVRpbWVTb3VyY2UgY2xvY2sgPSBuZXcgRmFrZVRpbWVTb3VyY2UoKTsKKworICBATW9jayBwcml2YXRlIERvd25sb2FkTGlzdGVuZXIgbW9ja0Rvd25sb2FkTGlzdGVuZXIxOworICBATW9jayBwcml2YXRlIERvd25sb2FkTGlzdGVuZXIgbW9ja0Rvd25sb2FkTGlzdGVuZXIyOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBkb3dubG9hZE1vbml0b3IgPSBEb3dubG9hZFByb2dyZXNzTW9uaXRvci5jcmVhdGUoY2xvY2ssIENPTlRST0xfRVhFQ1VUT1IpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnl0ZXNXcml0dGVuX2NsZWFuU2xhdGUoKSB7CisgICAgZG93bmxvYWRNb25pdG9yLmFkZERvd25sb2FkTGlzdGVuZXIodXJpMSwgbW9ja0Rvd25sb2FkTGlzdGVuZXIxKTsKKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcih1cmkyLCBtb2NrRG93bmxvYWRMaXN0ZW5lcjIpOworCisgICAgT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yMSA9IGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSk7CisgICAgT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yMiA9IGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSk7CisgICAgT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yMyA9IGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMyk7CisKKyAgICAvLyBvdXRwdXRNb25pdG9yMSBpcyBzYW1lIGFzIG91dHB1dE1vbml0b3IyIHNpbmNlIHRoZXkgYm90aCBtb25pdG9yIGZvciB1cmkxLgorICAgIGFzc2VydFRoYXQob3V0cHV0TW9uaXRvcjEpLmlzU2FtZUluc3RhbmNlQXMob3V0cHV0TW9uaXRvcjIpOworICAgIGFzc2VydFRoYXQob3V0cHV0TW9uaXRvcjEpLmlzTm90U2FtZUluc3RhbmNlQXMob3V0cHV0TW9uaXRvcjMpOworCisgICAgLy8gVGhlIDFzdCBieXRlc1dyaXR0ZW4gd2FzIGJ1ZmZlcmVkLgorICAgIG91dHB1dE1vbml0b3IxLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxXSwgMCwgMSk7CisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0Rvd25sb2FkTGlzdGVuZXIxKTsKKworICAgIC8vIE5vdyB0aGUgYnVmZmVyZWQgdGltZSBwYXNzZWQuCisgICAgY2xvY2suYWR2YW5jZShCVUZGRVJFRF9USU1FX01TICsgMTAwLCBNSUxMSVNFQ09ORFMpOworCisgICAgLy8gVGhlIDJuZCBieXRlc1dyaXR0ZW4gbm93IHRyaWdnZXJlZCBvblByb2dyZXNzLgorICAgIG91dHB1dE1vbml0b3IxLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxXSwgMSwgMik7CisgICAgLy8gMSAoZmlyc3QgYnl0ZXNXcml0dGVuKSArIDIgKDJuZCBieXRlc1dyaXR0ZW4pCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyMSkub25Qcm9ncmVzcygxICsgMik7CisKKyAgICAvLyBUaGUgM3JkIGJ5dGVzV3JpdHRlbiB3YXMgYnVmZmVyZWQKKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDMsIDQpOworICAgIHZlcmlmeU5vTW9yZUludGVyYWN0aW9ucyhtb2NrRG93bmxvYWRMaXN0ZW5lcjEpOworCisgICAgLy8gTm93IHRoZSBidWZmZXJlZCB0aW1lIHBhc3NlZCBhZ2Fpbi4KKyAgICBjbG9jay5hZHZhbmNlKEJVRkZFUkVEX1RJTUVfTVMgKyAxMDAsIE1JTExJU0VDT05EUyk7CisKKyAgICAvLyBUaGUgNHRoIGJ5dGVzV3JpdHRlbiBub3cgdHJpZ2dlcmVkIG9uUHJvZ3Jlc3MuCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCA3LCA4KTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIxKS5vblByb2dyZXNzKDEgKyAyICsgNCArIDgpOworCisgICAgLy8gTm8gYnl0ZXMgd2VyZSBkb3dubG9hZGVkIGZvciBGaWxlR3JvdXAyLgorICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tEb3dubG9hZExpc3RlbmVyMik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBieXRlc1dyaXR0ZW5fYWRkQW5kUmVtb3ZlRG93bmxvYWRMaXN0ZW5lcigpIHsKKworICAgIC8vIFRoZXJlIGlzIG5vIGRvd25sb2FkIGxpc3RlbmVyIGZvciB1cmkxLgorICAgIGFzc2VydFRoYXQoZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKSkuaXNOdWxsKCk7CisKKyAgICAvLyBBZGRpbmcgYSBsaXN0ZW5lciBub3cuCisgICAgZG93bmxvYWRNb25pdG9yLmFkZERvd25sb2FkTGlzdGVuZXIodXJpMSwgbW9ja0Rvd25sb2FkTGlzdGVuZXIxKTsKKworICAgIC8vIFJlbW92aW5nIHRoZSBsaXN0ZW5lci4KKyAgICBkb3dubG9hZE1vbml0b3IucmVtb3ZlRG93bmxvYWRMaXN0ZW5lcih1cmkxKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSkpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRlckxpZmVjeWNsZUNhbGxiYWNrKCkgeworICAgIGRvd25sb2FkTW9uaXRvci5hZGREb3dubG9hZExpc3RlbmVyKHVyaTEsIG1vY2tEb3dubG9hZExpc3RlbmVyMSk7CisgICAgZG93bmxvYWRNb25pdG9yLmFkZERvd25sb2FkTGlzdGVuZXIodXJpMiwgbW9ja0Rvd25sb2FkTGlzdGVuZXIyKTsKKyAgICBkb3dubG9hZE1vbml0b3IucGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyMSkub25QYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIyKS5vblBhdXNlZEZvckNvbm5lY3Rpdml0eSgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9Eb3dubG9hZGVySW1wbFRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9saXRlL0Rvd25sb2FkZXJJbXBsVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiZDJjMDcKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbGl0ZS9Eb3dubG9hZGVySW1wbFRlc3QuamF2YQpAQCAtMCwwICsxLDEwMzEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmxpdGU7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb24uRG93bmxvYWRSZXN1bHRDb2RlLkFORFJPSURfRE9XTkxPQURFUl9VTktOT1dOOworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi50cnV0aC5UcnV0aC5hc3NlcnRUaGF0OworaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRocm93czsKK2ltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5lcTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by50aW1lczsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ud2hlbjsKKworaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0OworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBhbmRyb2lkeC50ZXN0LmNvcmUuYXBwLkFwcGxpY2F0aW9uUHJvdmlkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRFeGNlcHRpb247CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZENvbnN0cmFpbnRzOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRmlsZURvd25sb2FkZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5CbG9ja2luZ0ZpbGVEb3dubG9hZGVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uYmFzZS5TdXBwbGllcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5sYWJzLmNvbmN1cnJlbnQuTGFic0Z1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTW9yZUV4ZWN1dG9yczsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db3VudERvd25MYXRjaDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3JzOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlNjaGVkdWxlZEV4ZWN1dG9yU2VydmljZTsKK2ltcG9ydCBvcmcuanVuaXQuQmVmb3JlOworaW1wb3J0IG9yZy5qdW5pdC5SdWxlOworaW1wb3J0IG9yZy5qdW5pdC5UZXN0OworaW1wb3J0IG9yZy5qdW5pdC5ydW5uZXIuUnVuV2l0aDsKK2ltcG9ydCBvcmcubW9ja2l0by5Bcmd1bWVudENhcHRvcjsKK2ltcG9ydCBvcmcubW9ja2l0by5DYXB0b3I7CitpbXBvcnQgb3JnLm1vY2tpdG8uTW9jazsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvSlVuaXQ7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b1J1bGU7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGZpbmFsIGNsYXNzIERvd25sb2FkZXJJbXBsVGVzdCB7CisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgLy8gVXNlIGRpcmVjdEV4ZWN1dG9yIHRvIGVuc3VyZSB0aGUgb3JkZXIgb2YgdGVzdCB2ZXJpZmljYXRpb24uCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEV4ZWN1dG9yIENPTlRST0xfRVhFQ1VUT1IgPSBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCk7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEV4ZWN1dG9yIEJBQ0tHUk9VTkRfRVhFQ1VUT1IgPSBFeGVjdXRvcnMubmV3Q2FjaGVkVGhyZWFkUG9vbCgpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTY2hlZHVsZWRFeGVjdXRvclNlcnZpY2UgRE9XTkxPQURfRVhFQ1VUT1IgPQorICAgICAgRXhlY3V0b3JzLm5ld1NjaGVkdWxlZFRocmVhZFBvb2woMik7CisgIExpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSBsaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2UgPQorICAgICAgTW9yZUV4ZWN1dG9ycy5saXN0ZW5pbmdEZWNvcmF0b3IoRE9XTkxPQURfRVhFQ1VUT1IpOworCisgIC8vIDFNQiBmaWxlLgorICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9VUkwgPQorICAgICAgImh0dHBzOi8vd3d3LmdzdGF0aWMuY29tL2ljaW5nL2lkZC9zYW1wbGVfZ3JvdXAvc2FtcGxlX2ZpbGVfM18xNTE5MjQwNzAxIjsKKworICBATW9jayBwcml2YXRlIFNpbmdsZUZpbGVEb3dubG9hZFByb2dyZXNzTW9uaXRvciBtb2NrRG93bmxvYWRNb25pdG9yOworICBATW9jayBwcml2YXRlIERvd25sb2FkTGlzdGVuZXIgbW9ja0Rvd25sb2FkTGlzdGVuZXI7CisgIHByaXZhdGUgRG93bmxvYWRlciBkb3dubG9hZGVyOworICBwcml2YXRlIENvbnRleHQgY29udGV4dDsKKyAgcHJpdmF0ZSBEb3dubG9hZFJlcXVlc3QgZG93bmxvYWRSZXF1ZXN0OworICBwcml2YXRlIGZpbmFsIFVyaSBkZXN0aW5hdGlvbkZpbGVVcmkgPQorICAgICAgVXJpLnBhcnNlKAorICAgICAgICAgICJhbmRyb2lkOi8vY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8xIik7CisKKyAgQE1vY2sgcHJpdmF0ZSBGaWxlRG93bmxvYWRlciBmaWxlRG93bmxvYWRlcjsKKworICBAQ2FwdG9yIEFyZ3VtZW50Q2FwdG9yPERvd25sb2FkTGlzdGVuZXI+IGRvd25sb2FkTGlzdGVuZXJDYXB0b3I7CisKKyAgQENhcHRvcgorICBBcmd1bWVudENhcHRvcjxjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdD4KKyAgICAgIGRvd25sb2FkUmVxdWVzdENhcHRvcjsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgIGNvbnRleHQgPSBBcHBsaWNhdGlvblByb3ZpZGVyLmdldEFwcGxpY2F0aW9uQ29udGV4dCgpOworICAgIGRvd25sb2FkZXIgPQorICAgICAgICBEb3dubG9hZGVyLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldENvbnRleHQoY29udGV4dCkKKyAgICAgICAgICAgIC5zZXRDb250cm9sRXhlY3V0b3IoQ09OVFJPTF9FWEVDVVRPUikKKyAgICAgICAgICAgIC5zZXREb3dubG9hZE1vbml0b3IobW9ja0Rvd25sb2FkTW9uaXRvcikKKyAgICAgICAgICAgIC5zZXRGaWxlRG93bmxvYWRlclN1cHBsaWVyKCgpIC0+IGZpbGVEb3dubG9hZGVyKQorICAgICAgICAgICAgLnNldEZvcmVncm91bmREb3dubG9hZFNlcnZpY2UodGhpcy5nZXRDbGFzcygpKSAvLyBkb24ndCBuZWVkIHRvIHVzZSB0aGUgcmVhbCBvbmUuCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGRvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIERvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREZXN0aW5hdGlvbkZpbGVVcmkoZGVzdGluYXRpb25GaWxlVXJpKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKQorICAgICAgICAgICAgLnNldE5vdGlmaWNhdGlvbkNvbnRlbnRUaXRsZSgiRmlsZSB1cmw6ICIgKyBGSUxFX1VSTCkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgd2hlbihtb2NrRG93bmxvYWRMaXN0ZW5lci5vbkNvbXBsZXRlKCkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVGdXR1cmUobnVsbCkpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRfd2hlblJlcXVlc3RBbHJlYWR5TWFkZV9kZWR1cHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBVc2UgQmxvY2tpbmdGaWxlRG93bmxvYWRlciB0byBlbnN1cmUgZmlyc3QgZG93bmxvYWQgaXMgaW4gcHJvZ3Jlc3MuCisgICAgQmxvY2tpbmdGaWxlRG93bmxvYWRlciBibG9ja2luZ0ZpbGVEb3dubG9hZGVyID0KKyAgICAgICAgbmV3IEJsb2NraW5nRmlsZURvd25sb2FkZXIobGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlKTsKKyAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gYmxvY2tpbmdEb3dubG9hZGVyU3VwcGxpZXIgPSAoKSAtPiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyOworCisgICAgRG93bmxvYWRlckltcGwgZG93bmxvYWRlckltcGwgPQorICAgICAgICBuZXcgRG93bmxvYWRlckltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgT3B0aW9uYWwuYWJzZW50KCksCisgICAgICAgICAgICBDT05UUk9MX0VYRUNVVE9SLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICBibG9ja2luZ0Rvd25sb2FkZXJTdXBwbGllcik7CisKKyAgICBpbnQgZG93bmxvYWRGdXR1cmVzSW5GbGlnaHRDb3VudEJlZm9yZSA9IGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZS5zaXplKCk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlMSA9IGRvd25sb2FkZXJJbXBsLmRvd25sb2FkKGRvd25sb2FkUmVxdWVzdCk7CisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZTIgPSBkb3dubG9hZGVySW1wbC5kb3dubG9hZChkb3dubG9hZFJlcXVlc3QpOworCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpLmNvbnRhaW5zS2V5KGRlc3RpbmF0aW9uRmlsZVVyaS50b1N0cmluZygpKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZS5zaXplKCkgLSBkb3dubG9hZEZ1dHVyZXNJbkZsaWdodENvdW50QmVmb3JlKQorICAgICAgICAuaXNFcXVhbFRvKDEpOworCisgICAgLy8gQWxsb3cgYmxvY2tpbmcgZG93bmxvYWQgdG8gZmluaXNoCisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci5maW5pc2hEb3dubG9hZGluZygpOworCisgICAgLy8gRmluaXNoIGZ1dHVyZSAyIGFuZCBhc3NlcnQgdGhhdCBmdXR1cmUgMSBoYXMgY29tcGxldGVkIGFzIHdlbGwKKyAgICBkb3dubG9hZEZ1dHVyZTIuZ2V0KCk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZEZ1dHVyZTEuaXNEb25lKCkpLmlzVHJ1ZSgpOworCisgICAgLy8gVE9ETyhiLzE1NTkxODQwNik6IENvbnZlcnQgdG8gRnJhbWV3b3JrIHRlc3QgYW5kIHVzZSBUZXN0aW5nVGFza0JhcnJpZXIgdG8gYXZvaWQgc2xlZXAuCisgICAgLy8gU2xlZXAgZm9yIDEgc2VjIHRvIHdhaXQgZm9yIHRoZSBGdXR1cmUncyBjYWxsYmFjayB0byBmaW5pc2guCisgICAgVGhyZWFkLnNsZWVwKC8qIG1pbGxpcyA9ICovIDEwMDApOworCisgICAgLy8gVGhlIGNvbXBsZXRlZCBkb3dubG9hZCBzaG91bGQgYmUgcmVtb3ZlZCBmcm9tIGtleVRvTGlzdGVuYWJsZUZ1dHVyZSBtYXAuCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpCisgICAgICAgIC5kb2VzTm90Q29udGFpbktleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpLmhhc1NpemUoZG93bmxvYWRGdXR1cmVzSW5GbGlnaHRDb3VudEJlZm9yZSk7CisKKyAgICAvLyBSZXNldCBzdGF0ZSBvZiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyIHRvIHByZXZlbnQgZGVhZGxvY2tzCisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci5yZXNldFN0YXRlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZF93aGVuUmVxdWVzdEFscmVhZHlNYWRlVXNpbmdGb3JlZ3JvdW5kU2VydmljZV9kZWR1cHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBVc2UgQmxvY2tpbmdGaWxlRG93bmxvYWRlciB0byBlbnN1cmUgZmlyc3QgZG93bmxvYWQgaXMgaW4gcHJvZ3Jlc3MuCisgICAgQmxvY2tpbmdGaWxlRG93bmxvYWRlciBibG9ja2luZ0ZpbGVEb3dubG9hZGVyID0KKyAgICAgICAgbmV3IEJsb2NraW5nRmlsZURvd25sb2FkZXIobGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlKTsKKyAgICBTdXBwbGllcjxGaWxlRG93bmxvYWRlcj4gYmxvY2tpbmdEb3dubG9hZGVyU3VwcGxpZXIgPSAoKSAtPiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyOworCisgICAgRG93bmxvYWRlckltcGwgZG93bmxvYWRlckltcGwgPQorICAgICAgICBuZXcgRG93bmxvYWRlckltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgQ09OVFJPTF9FWEVDVVRPUiwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZE1vbml0b3IpLAorICAgICAgICAgICAgYmxvY2tpbmdEb3dubG9hZGVyU3VwcGxpZXIpOworCisgICAgaW50IGRvd25sb2FkRnV0dXJlc0luRmxpZ2h0Q291bnRCZWZvcmUgPSBkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUuc2l6ZSgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZTEgPQorICAgICAgICBkb3dubG9hZGVySW1wbC5kb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZShkb3dubG9hZFJlcXVlc3QpOworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUyID0gZG93bmxvYWRlckltcGwuZG93bmxvYWQoZG93bmxvYWRSZXF1ZXN0KTsKKworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlKS5jb250YWluc0tleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUuc2l6ZSgpIC0gZG93bmxvYWRGdXR1cmVzSW5GbGlnaHRDb3VudEJlZm9yZSkKKyAgICAgICAgLmlzRXF1YWxUbygxKTsKKworICAgIC8vIEFsbG93IGJsb2NraW5nIGRvd25sb2FkIHRvIGZpbmlzaAorICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIuZmluaXNoRG93bmxvYWRpbmcoKTsKKworICAgIC8vIEZpbmlzaCBmdXR1cmUgMiBhbmQgYXNzZXJ0IHRoYXQgZnV0dXJlIDEgaGFzIGNvbXBsZXRlZCBhcyB3ZWxsCisgICAgZG93bmxvYWRGdXR1cmUyLmdldCgpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRGdXR1cmUxLmlzRG9uZSgpKS5pc1RydWUoKTsKKworICAgIC8vIFRPRE8oYi8xNTU5MTg0MDYpOiBDb252ZXJ0IHRvIEZyYW1ld29yayB0ZXN0IGFuZCB1c2UgVGVzdGluZ1Rhc2tCYXJyaWVyIHRvIGF2b2lkIHNsZWVwLgorICAgIC8vIFNsZWVwIGZvciAxIHNlYyB0byB3YWl0IGZvciB0aGUgRnV0dXJlJ3MgY2FsbGJhY2sgdG8gZmluaXNoLgorICAgIFRocmVhZC5zbGVlcCgvKiBtaWxsaXMgPSAqLyAxMDAwKTsKKworICAgIC8vIFRoZSBjb21wbGV0ZWQgZG93bmxvYWQgc2hvdWxkIGJlIHJlbW92ZWQgZnJvbSBrZXlUb0xpc3RlbmFibGVGdXR1cmUgbWFwLgorICAgIGFzc2VydFRoYXQoZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlKQorICAgICAgICAuZG9lc05vdENvbnRhaW5LZXkoZGVzdGluYXRpb25GaWxlVXJpLnRvU3RyaW5nKCkpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlKS5oYXNTaXplKGRvd25sb2FkRnV0dXJlc0luRmxpZ2h0Q291bnRCZWZvcmUpOworCisgICAgLy8gUmVzZXQgc3RhdGUgb2YgYmxvY2tpbmdGaWxlRG93bmxvYWRlciB0byBwcmV2ZW50IGRlYWRsb2NrcworICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIucmVzZXRTdGF0ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRfYmVnaW5zRG93bmxvYWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICB3aGVuKGZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoZG93bmxvYWRSZXF1ZXN0Q2FwdG9yLmNhcHR1cmUoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpKTsKKworICAgIERvd25sb2FkZXJJbXBsIGRvd25sb2FkZXJJbXBsID0KKyAgICAgICAgbmV3IERvd25sb2FkZXJJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgQ09OVFJPTF9FWEVDVVRPUiwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZE1vbml0b3IpLAorICAgICAgICAgICAgKCkgLT4gZmlsZURvd25sb2FkZXIpOworCisgICAgZG93bmxvYWRSZXF1ZXN0ID0KKyAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERlc3RpbmF0aW9uRmlsZVVyaShkZXN0aW5hdGlvbkZpbGVVcmkpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChGSUxFX1VSTCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpCisgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbChPcHRpb25hbC5vZihtb2NrRG93bmxvYWRMaXN0ZW5lcikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPSBkb3dubG9hZGVySW1wbC5kb3dubG9hZChkb3dubG9hZFJlcXVlc3QpOworICAgIGRvd25sb2FkRnV0dXJlLmdldCgpOworCisgICAgLy8gVE9ETyhiLzE1NTkxODQwNik6IENvbnZlcnQgdG8gRnJhbWV3b3JrIHRlc3QgYW5kIHVzZSBUZXN0aW5nVGFza0JhcnJpZXIgdG8gYXZvaWQgc2xlZXAuCisgICAgLy8gU2xlZXAgZm9yIDEgc2VjIHRvIHdhaXQgZm9yIHRoZSBGdXR1cmUncyBjYWxsYmFjayB0byBmaW5pc2guCisgICAgVGhyZWFkLnNsZWVwKC8qIG1pbGxpcyA9ICovIDEwMDApOworCisgICAgLy8gVmVyaWZ5IHRoYXQgY29ycmVjdCBEb3dubG9hZFJlcXVlc3QgaXMgc2VudCB0byB1bmRlcmx5aW5nIEZpbGVEb3dubG9hZGVyCisgICAgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3QKKyAgICAgICAgYWN0dWFsRG93bmxvYWRSZXF1ZXN0ID0gZG93bmxvYWRSZXF1ZXN0Q2FwdG9yLmdldFZhbHVlKCk7CisgICAgYXNzZXJ0VGhhdChhY3R1YWxEb3dubG9hZFJlcXVlc3QuZmlsZVVyaSgpKS5pc0VxdWFsVG8oZGVzdGluYXRpb25GaWxlVXJpKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbERvd25sb2FkUmVxdWVzdC51cmxUb0Rvd25sb2FkKCkpLmlzRXF1YWxUbyhGSUxFX1VSTCk7CisgICAgYXNzZXJ0VGhhdChhY3R1YWxEb3dubG9hZFJlcXVlc3QuZG93bmxvYWRDb25zdHJhaW50cygpKQorICAgICAgICAuaXNFcXVhbFRvKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgZG93bmxvYWRNb25pdG9yIGFkZHMgdGhlIGxpc3RlbmVyCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZE1vbml0b3IpCisgICAgICAgIC5hZGREb3dubG9hZExpc3RlbmVyKGFueShVcmkuY2xhc3MpLCBkb3dubG9hZExpc3RlbmVyQ2FwdG9yLmNhcHR1cmUoKSk7CisgICAgdmVyaWZ5KGZpbGVEb3dubG9hZGVyKQorICAgICAgICAuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIGFueShjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdC5jbGFzcykpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZE1vbml0b3IpLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoZGVzdGluYXRpb25GaWxlVXJpKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIpLm9uQ29tcGxldGUoKTsKKworICAgIC8vIEVuc3VyZSB0aGF0IGdpdmVuIGRvd25sb2FkIGxpc3RlbmVyIGlzIHRoZSBzYW1lIG9uZSBwYXNzZWQgdG8gZG93bmxvYWQgbW9uaXRvcgorICAgIERvd25sb2FkTGlzdGVuZXIgY2FwdHVyZWREb3dubG9hZExpc3RlbmVyID0gZG93bmxvYWRMaXN0ZW5lckNhcHRvci5nZXRWYWx1ZSgpOworICAgIERvd25sb2FkRXhjZXB0aW9uIHRlc3RFeGNlcHRpb24gPQorICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkuc2V0RG93bmxvYWRSZXN1bHRDb2RlKEFORFJPSURfRE9XTkxPQURFUl9VTktOT1dOKS5idWlsZCgpOworCisgICAgY2FwdHVyZWREb3dubG9hZExpc3RlbmVyLm9uUHJvZ3Jlc3MoMTApOworICAgIGNhcHR1cmVkRG93bmxvYWRMaXN0ZW5lci5vbkZhaWx1cmUodGVzdEV4Y2VwdGlvbik7CisgICAgY2FwdHVyZWREb3dubG9hZExpc3RlbmVyLm9uUGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7CisKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIpLm9uUHJvZ3Jlc3MoMTApOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcikub25GYWlsdXJlKHRlc3RFeGNlcHRpb24pOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcikub25QYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkX3doZW5MaXN0ZW5lclByb3ZpZGVkX2hhbmRsZXNPbkNvbXBsZXRlRmFpbGVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgd2hlbihmaWxlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKGRvd25sb2FkUmVxdWVzdENhcHRvci5jYXB0dXJlKCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKSk7CisgICAgd2hlbihtb2NrRG93bmxvYWRMaXN0ZW5lci5vbkNvbXBsZXRlKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKG5ldyBFeGNlcHRpb24oInRlc3QgZmFpbHVyZSIpKSk7CisKKyAgICBEb3dubG9hZGVySW1wbCBkb3dubG9hZGVySW1wbCA9CisgICAgICAgIG5ldyBEb3dubG9hZGVySW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIENPTlRST0xfRVhFQ1VUT1IsCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrRG93bmxvYWRNb25pdG9yKSwKKyAgICAgICAgICAgICgpIC0+IGZpbGVEb3dubG9hZGVyKTsKKworICAgIGRvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIERvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREZXN0aW5hdGlvbkZpbGVVcmkoZGVzdGluYXRpb25GaWxlVXJpKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKQorICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTGlzdGVuZXIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBkb3dubG9hZGVyLmRvd25sb2FkKGRvd25sb2FkUmVxdWVzdCkuZ2V0KCk7CisKKyAgICAvLyBUT0RPKGIvMTU1OTE4NDA2KTogQ29udmVydCB0byBGcmFtZXdvcmsgdGVzdCBhbmQgdXNlIFRlc3RpbmdUYXNrQmFycmllciB0byBhdm9pZCBzbGVlcC4KKyAgICAvLyBTbGVlcCBmb3IgMSBzZWMgdG8gd2FpdCBmb3IgdGhlIEZ1dHVyZSdzIGNhbGxiYWNrIHRvIGZpbmlzaC4KKyAgICBUaHJlYWQuc2xlZXAoLyogbWlsbGlzID0gKi8gMTAwMCk7CisKKyAgICAvLyBFbnN1cmUgdGhhdCBmdXR1cmUgaXMgc3RpbGwgcmVtb3ZlZCBmcm9tIGludGVybmFsIG1hcAorICAgIGFzc2VydFRoYXQoZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlKQorICAgICAgICAuZG9lc05vdENvbnRhaW5LZXkoZG93bmxvYWRSZXF1ZXN0LmRlc3RpbmF0aW9uRmlsZVVyaSgpLnRvU3RyaW5nKCkpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgRG93bmxvYWRNb25pdG9yIGhhbmRsZWQgRG93bmxvYWRMaXN0ZW5lciBwcm9wZXJseQorICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5hZGREb3dubG9hZExpc3RlbmVyKGRlc3RpbmF0aW9uRmlsZVVyaSwgbW9ja0Rvd25sb2FkTGlzdGVuZXIpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGRlc3RpbmF0aW9uRmlsZVVyaSk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBkb3dubG9hZCB3YXMgc3RhcnRlZAorICAgIHZlcmlmeShmaWxlRG93bmxvYWRlcikuc3RhcnREb3dubG9hZGluZyhhbnkoKSk7CisKKyAgICAvLyBWZXJpZnkgdGhlIERvd25sb2FkTGlzdGVuZXJzIG9uQ29tcGxldGUgd2FzIGludm9rZWQKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIpLm9uQ29tcGxldGUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkX3doZW5MaXN0ZW5lclByb3ZpZGVkX3dhaXRzRm9yT25Db21wbGV0ZVRvRmluaXNoKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgd2hlbihmaWxlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKGFueSgpKSkudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKSk7CisKKyAgICAvLyBVc2UgYSBsYXRjaCB0byBzaW11bGF0ZSBhIGxvbmcgcnVubmluZyBEb3dubG9hZExpc3RlbmVyLm9uQ29tcGxldGUKKyAgICBDb3VudERvd25MYXRjaCBibG9ja2luZ09uQ29tcGxldGVMYXRjaCA9IG5ldyBDb3VudERvd25MYXRjaCgxKTsKKworICAgIERvd25sb2FkZXJJbXBsIGRvd25sb2FkZXJJbXBsID0KKyAgICAgICAgbmV3IERvd25sb2FkZXJJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIE9wdGlvbmFsLmFic2VudCgpLAorICAgICAgICAgICAgQ09OVFJPTF9FWEVDVVRPUiwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZE1vbml0b3IpLAorICAgICAgICAgICAgKCkgLT4gZmlsZURvd25sb2FkZXIpOworCisgICAgZG93bmxvYWRSZXF1ZXN0ID0KKyAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERlc3RpbmF0aW9uRmlsZVVyaShkZXN0aW5hdGlvbkZpbGVVcmkpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChGSUxFX1VSTCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpCisgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbCgKKyAgICAgICAgICAgICAgICBPcHRpb25hbC5vZigKKyAgICAgICAgICAgICAgICAgICAgbmV3IERvd25sb2FkTGlzdGVuZXIoKSB7CisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25QYXVzZWRGb3JDb25uZWN0aXZpdHkoKSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gb25Db21wbGV0ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLnN1Ym1pdEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZlcmlmeSB0aGF0IGZ1dHVyZSBtYXAgc3RpbGwgY29udGFpbnMgZG93bmxvYWQgZnV0dXJlLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb250YWluc0tleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NraW5nT25Db21wbGV0ZUxhdGNoLmF3YWl0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJBQ0tHUk9VTkRfRVhFQ1VUT1IpOworICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGRvd25sb2FkZXJJbXBsLmRvd25sb2FkKGRvd25sb2FkUmVxdWVzdCkuZ2V0KCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgZG93bmxvYWQgZnV0dXJlIG1hcCBzdGlsbCBjb250YWlucyB0aGUgZG93bmxvYWQgZnV0dXJlLgorICAgIGFzc2VydFRoYXQoZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlKS5jb250YWluc0tleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisKKyAgICAvLyBUT0RPKGIvMTU1OTE4NDA2KTogQ29udmVydCB0byBGcmFtZXdvcmsgdGVzdCBhbmQgdXNlIFRlc3RpbmdUYXNrQmFycmllciB0byBhdm9pZCBzbGVlcC4KKyAgICAvLyBTbGVlcCBmb3IgMSBzZWMgdG8gd2FpdCBmb3IgdGhlIEZ1dHVyZSdzIGNhbGxiYWNrIHRvIGZpbmlzaC4KKyAgICBUaHJlYWQuc2xlZXAoLyogbWlsbGlzID0gKi8gMTAwMCk7CisKKyAgICAvLyBGaW5pc2ggdGhlIG9uQ29tcGxldGUgbWV0aG9kLgorICAgIGJsb2NraW5nT25Db21wbGV0ZUxhdGNoLmNvdW50RG93bigpOworCisgICAgLy8gVE9ETyhiLzE1NTkxODQwNik6IENvbnZlcnQgdG8gRnJhbWV3b3JrIHRlc3QgYW5kIHVzZSBUZXN0aW5nVGFza0JhcnJpZXIgdG8gYXZvaWQgc2xlZXAuCisgICAgLy8gU2xlZXAgZm9yIDEgc2VjIHRvIHdhaXQgZm9yIHRoZSBGdXR1cmUncyBjYWxsYmFjayB0byBmaW5pc2guCisgICAgVGhyZWFkLnNsZWVwKC8qIG1pbGxpcyA9ICovIDEwMDApOworCisgICAgLy8gVGhlIGNvbXBsZXRlZCBkb3dubG9hZCBzaG91bGQgYmUgcmVtb3ZlZCBmcm9tIGtleVRvTGlzdGVuYWJsZUZ1dHVyZSBtYXAuCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpCisgICAgICAgIC5kb2VzTm90Q29udGFpbktleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpLmlzRW1wdHkoKTsKKworICAgIC8vIFZlcmlmeSBEb3dubG9hZExpc3RlbmVyIHdhcyBhZGRlZC9yZW1vdmVkCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZE1vbml0b3IpLmFkZERvd25sb2FkTGlzdGVuZXIoZXEoZGVzdGluYXRpb25GaWxlVXJpKSwgYW55KCkpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGRlc3RpbmF0aW9uRmlsZVVyaSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZF93aGVuRG93bmxvYWRGYWlsc19yZXBvcnRzRmFpbHVyZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIERvd25sb2FkRXhjZXB0aW9uIGRvd25sb2FkRXhjZXB0aW9uID0KKyAgICAgICAgRG93bmxvYWRFeGNlcHRpb24uYnVpbGRlcigpLnNldERvd25sb2FkUmVzdWx0Q29kZShBTkRST0lEX0RPV05MT0FERVJfVU5LTk9XTikuYnVpbGQoKTsKKyAgICB3aGVuKGZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoZG93bmxvYWRSZXF1ZXN0Q2FwdG9yLmNhcHR1cmUoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGRvd25sb2FkRXhjZXB0aW9uKSk7CisKKyAgICBEb3dubG9hZGVySW1wbCBkb3dubG9hZGVySW1wbCA9CisgICAgICAgIG5ldyBEb3dubG9hZGVySW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIENPTlRST0xfRVhFQ1VUT1IsCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrRG93bmxvYWRNb25pdG9yKSwKKyAgICAgICAgICAgICgpIC0+IGZpbGVEb3dubG9hZGVyKTsKKworICAgIGRvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIERvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREZXN0aW5hdGlvbkZpbGVVcmkoZGVzdGluYXRpb25GaWxlVXJpKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKQorICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTGlzdGVuZXIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0gZG93bmxvYWRlckltcGwuZG93bmxvYWQoZG93bmxvYWRSZXF1ZXN0KTsKKyAgICBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCBkb3dubG9hZEZ1dHVyZTo6Z2V0KTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBlID0gTGFic0Z1dHVyZXMuZ2V0RmFpbHVyZUNhdXNlQXMoZG93bmxvYWRGdXR1cmUsIERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBhc3NlcnRUaGF0KGUuZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpLmlzRXF1YWxUbyhBTkRST0lEX0RPV05MT0FERVJfVU5LTk9XTik7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBmaWxlIGRvd25sb2FkIHdhcyBzdGFydGVkIGFuZCBmYWlsZWQKKyAgICB2ZXJpZnkoZmlsZURvd25sb2FkZXIpLnN0YXJ0RG93bmxvYWRpbmcoYW55KCkpOworICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0CisgICAgICAgIGFjdHVhbERvd25sb2FkUmVxdWVzdCA9IGRvd25sb2FkUmVxdWVzdENhcHRvci5nZXRWYWx1ZSgpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LmZpbGVVcmkoKSkuaXNFcXVhbFRvKGRlc3RpbmF0aW9uRmlsZVVyaSk7CisgICAgYXNzZXJ0VGhhdChhY3R1YWxEb3dubG9hZFJlcXVlc3QudXJsVG9Eb3dubG9hZCgpKS5pc0VxdWFsVG8oRklMRV9VUkwpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LmRvd25sb2FkQ29uc3RyYWludHMoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IERvd25sb2FkTW9uaXRvciBhZGRlZC9yZW1vdmVkIERvd25sb2FkTGlzdGVuZXIKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTW9uaXRvcikuYWRkRG93bmxvYWRMaXN0ZW5lcihkZXN0aW5hdGlvbkZpbGVVcmksIG1vY2tEb3dubG9hZExpc3RlbmVyKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTW9uaXRvcikucmVtb3ZlRG93bmxvYWRMaXN0ZW5lcihkZXN0aW5hdGlvbkZpbGVVcmkpOworCisgICAgLy8gVmVyaWZ5IHRoYXQgRG93bmxvYWRMaXN0ZW5lci5vbkZhaWx1cmUgd2FzIGludm9rZWQgd2l0aCBmYWlsdXJlCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyKS5vbkZhaWx1cmUoZG93bmxvYWRFeGNlcHRpb24pOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lciwgdGltZXMoMCkpLm9uQ29tcGxldGUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkX3doZW5SZXR1cm5lZEZ1dHVyZUlzQ2FuY2VsZWRfY2FuY2Vsc0Rvd25sb2FkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVXNlIEJsb2NraW5nRmlsZURvd25sb2FkZXIgdG8gc2ltdWxhdGUgbG9uZyBkb3dubG9hZAorICAgIEJsb2NraW5nRmlsZURvd25sb2FkZXIgYmxvY2tpbmdGaWxlRG93bmxvYWRlciA9CisgICAgICAgIG5ldyBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyKGxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSk7CisKKyAgICBEb3dubG9hZGVySW1wbCBkb3dubG9hZGVySW1wbCA9CisgICAgICAgIG5ldyBEb3dubG9hZGVySW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsCisgICAgICAgICAgICBPcHRpb25hbC5hYnNlbnQoKSwKKyAgICAgICAgICAgIENPTlRST0xfRVhFQ1VUT1IsCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrRG93bmxvYWRNb25pdG9yKSwKKyAgICAgICAgICAgICgpIC0+IGJsb2NraW5nRmlsZURvd25sb2FkZXIpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9IGRvd25sb2FkZXJJbXBsLmRvd25sb2FkKGRvd25sb2FkUmVxdWVzdCk7CisKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZSkKKyAgICAgICAgLmNvbnRhaW5zS2V5KGRvd25sb2FkUmVxdWVzdC5kZXN0aW5hdGlvbkZpbGVVcmkoKS50b1N0cmluZygpKTsKKworICAgIGRvd25sb2FkRnV0dXJlLmNhbmNlbCh0cnVlKTsKKworICAgIC8vIFRoZSBkb3dubG9hZCBmdXR1cmUgc2hvdWxkIG5vIGxvbmdlciBiZSBpbmNsdWRlZCBpbiB0aGUgZnV0dXJlIG1hcAorICAgIGFzc2VydFRoYXQoZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlKQorICAgICAgICAuZG9lc05vdENvbnRhaW5LZXkoZG93bmxvYWRSZXF1ZXN0LmRlc3RpbmF0aW9uRmlsZVVyaSgpLnRvU3RyaW5nKCkpOworCisgICAgLy8gUmVzZXQgc3RhdGUgb2YgYmxvY2tpbmcgZmlsZSBkb3dubG9hZGVyIHRvIHByZXZlbnQgZGVhZGxvY2tzCisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci5yZXNldFN0YXRlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZF93aGVuTW9uaXRvck5vdFByb3ZpZGVkX3doZW5Eb3dubG9hZFN1Y2NlZWRzX3dhaXRzRm9yTGlzdGVuZXJPbkNvbXBsZXRlKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIHdoZW4oZmlsZURvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZyhhbnkoKSkpLnRoZW5SZXR1cm4oRnV0dXJlcy5pbW1lZGlhdGVWb2lkRnV0dXJlKCkpOworCisgICAgLy8gVXNlIGEgbGF0Y2ggdG8gc2ltdWxhdGUgYSBsb25nIHJ1bm5pbmcgRG93bmxvYWRMaXN0ZW5lci5vbkNvbXBsZXRlCisgICAgQ291bnREb3duTGF0Y2ggYmxvY2tpbmdPbkNvbXBsZXRlTGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKyAgICBEb3dubG9hZGVySW1wbCBkb3dubG9hZGVySW1wbCA9CisgICAgICAgIG5ldyBEb3dubG9hZGVySW1wbCgKKyAgICAgICAgICAgIGNvbnRleHQsIE9wdGlvbmFsLmFic2VudCgpLCBDT05UUk9MX0VYRUNVVE9SLCBPcHRpb25hbC5hYnNlbnQoKSwgKCkgLT4gZmlsZURvd25sb2FkZXIpOworCisgICAgZG93bmxvYWRSZXF1ZXN0ID0KKyAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERlc3RpbmF0aW9uRmlsZVVyaShkZXN0aW5hdGlvbkZpbGVVcmkpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChGSUxFX1VSTCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpCisgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbCgKKyAgICAgICAgICAgICAgICBPcHRpb25hbC5vZigKKyAgICAgICAgICAgICAgICAgICAgbmV3IERvd25sb2FkTGlzdGVuZXIoKSB7CisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25QYXVzZWRGb3JDb25uZWN0aXZpdHkoKSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gb25Db21wbGV0ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLnN1Ym1pdEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZlcmlmeSB0aGF0IGZ1dHVyZSBtYXAgc3RpbGwgY29udGFpbnMgZG93bmxvYWQgZnV0dXJlLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jb250YWluc0tleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NraW5nT25Db21wbGV0ZUxhdGNoLmF3YWl0KCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmUoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJBQ0tHUk9VTkRfRVhFQ1VUT1IpOworICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGRvd25sb2FkZXJJbXBsLmRvd25sb2FkKGRvd25sb2FkUmVxdWVzdCkuZ2V0KCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgZG93bmxvYWQgZnV0dXJlIG1hcCBzdGlsbCBjb250YWlucyB0aGUgZG93bmxvYWQgZnV0dXJlLgorICAgIGFzc2VydFRoYXQoZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlKS5jb250YWluc0tleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisKKyAgICAvLyBUT0RPKGIvMTU1OTE4NDA2KTogQ29udmVydCB0byBGcmFtZXdvcmsgdGVzdCBhbmQgdXNlIFRlc3RpbmdUYXNrQmFycmllciB0byBhdm9pZCBzbGVlcC4KKyAgICAvLyBTbGVlcCBmb3IgMSBzZWMgdG8gd2FpdCBmb3IgdGhlIEZ1dHVyZSdzIGNhbGxiYWNrIHRvIGZpbmlzaC4KKyAgICBUaHJlYWQuc2xlZXAoLyogbWlsbGlzID0gKi8gMTAwMCk7CisKKyAgICAvLyBGaW5pc2ggdGhlIG9uQ29tcGxldGUgbWV0aG9kLgorICAgIGJsb2NraW5nT25Db21wbGV0ZUxhdGNoLmNvdW50RG93bigpOworCisgICAgLy8gVE9ETyhiLzE1NTkxODQwNik6IENvbnZlcnQgdG8gRnJhbWV3b3JrIHRlc3QgYW5kIHVzZSBUZXN0aW5nVGFza0JhcnJpZXIgdG8gYXZvaWQgc2xlZXAuCisgICAgLy8gU2xlZXAgZm9yIDEgc2VjIHRvIHdhaXQgZm9yIHRoZSBGdXR1cmUncyBjYWxsYmFjayB0byBmaW5pc2guCisgICAgVGhyZWFkLnNsZWVwKC8qIG1pbGxpcyA9ICovIDEwMDApOworCisgICAgLy8gVGhlIGNvbXBsZXRlZCBkb3dubG9hZCBzaG91bGQgYmUgcmVtb3ZlZCBmcm9tIGtleVRvTGlzdGVuYWJsZUZ1dHVyZSBtYXAuCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpCisgICAgICAgIC5kb2VzTm90Q29udGFpbktleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpLmlzRW1wdHkoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkX3doZW5Nb25pdG9yTm90UHJvdmlkZWRfd2hlbkRvd25sb2FkRmFpbHNfcmVwb3J0c0ZhaWx1cmUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkb3dubG9hZEV4Y2VwdGlvbiA9CisgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKS5zZXREb3dubG9hZFJlc3VsdENvZGUoQU5EUk9JRF9ET1dOTE9BREVSX1VOS05PV04pLmJ1aWxkKCk7CisgICAgd2hlbihmaWxlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKGRvd25sb2FkUmVxdWVzdENhcHRvci5jYXB0dXJlKCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZShkb3dubG9hZEV4Y2VwdGlvbikpOworCisgICAgRG93bmxvYWRlckltcGwgZG93bmxvYWRlckltcGwgPQorICAgICAgICBuZXcgRG93bmxvYWRlckltcGwoCisgICAgICAgICAgICBjb250ZXh0LCBPcHRpb25hbC5hYnNlbnQoKSwgQ09OVFJPTF9FWEVDVVRPUiwgT3B0aW9uYWwuYWJzZW50KCksICgpIC0+IGZpbGVEb3dubG9hZGVyKTsKKworICAgIGRvd25sb2FkUmVxdWVzdCA9CisgICAgICAgIERvd25sb2FkUmVxdWVzdC5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXREZXN0aW5hdGlvbkZpbGVVcmkoZGVzdGluYXRpb25GaWxlVXJpKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKQorICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTGlzdGVuZXIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0gZG93bmxvYWRlckltcGwuZG93bmxvYWQoZG93bmxvYWRSZXF1ZXN0KTsKKyAgICBhc3NlcnRUaHJvd3MoRXhlY3V0aW9uRXhjZXB0aW9uLmNsYXNzLCBkb3dubG9hZEZ1dHVyZTo6Z2V0KTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBlID0gTGFic0Z1dHVyZXMuZ2V0RmFpbHVyZUNhdXNlQXMoZG93bmxvYWRGdXR1cmUsIERvd25sb2FkRXhjZXB0aW9uLmNsYXNzKTsKKyAgICBhc3NlcnRUaGF0KGUuZ2V0RG93bmxvYWRSZXN1bHRDb2RlKCkpLmlzRXF1YWxUbyhBTkRST0lEX0RPV05MT0FERVJfVU5LTk9XTik7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBmaWxlIGRvd25sb2FkIHdhcyBzdGFydGVkIGFuZCBmYWlsZWQKKyAgICB2ZXJpZnkoZmlsZURvd25sb2FkZXIpLnN0YXJ0RG93bmxvYWRpbmcoYW55KCkpOworICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0CisgICAgICAgIGFjdHVhbERvd25sb2FkUmVxdWVzdCA9IGRvd25sb2FkUmVxdWVzdENhcHRvci5nZXRWYWx1ZSgpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LmZpbGVVcmkoKSkuaXNFcXVhbFRvKGRlc3RpbmF0aW9uRmlsZVVyaSk7CisgICAgYXNzZXJ0VGhhdChhY3R1YWxEb3dubG9hZFJlcXVlc3QudXJsVG9Eb3dubG9hZCgpKS5pc0VxdWFsVG8oRklMRV9VUkwpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LmRvd25sb2FkQ29uc3RyYWludHMoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IERvd25sb2FkTGlzdGVuZXIub25GYWlsdXJlIHdhcyBpbnZva2VkIHdpdGggZmFpbHVyZQorICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcikub25GYWlsdXJlKGRvd25sb2FkRXhjZXB0aW9uKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIsIHRpbWVzKDApKS5vbkNvbXBsZXRlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZV9yZXF1aXJlc0ZvcmVncm91bmREb3dubG9hZFNlcnZpY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBDcmVhdGUgZG93bmxvYWRlciB3aXRob3V0IHByb3ZpZGluZyBmb3JlZ3JvdW5kIHNlcnZpY2UKKyAgICBkb3dubG9hZGVyID0KKyAgICAgICAgRG93bmxvYWRlci5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRDb250ZXh0KGNvbnRleHQpCisgICAgICAgICAgICAuc2V0Q29udHJvbEV4ZWN1dG9yKENPTlRST0xfRVhFQ1VUT1IpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRNb25pdG9yKG1vY2tEb3dubG9hZE1vbml0b3IpCisgICAgICAgICAgICAuc2V0RmlsZURvd25sb2FkZXJTdXBwbGllcigoKSAtPiBmaWxlRG93bmxvYWRlcikKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgLy8gV2l0aG91dCBmb3JlZ3JvdW5kIHNlcnZpY2UsIGRvd25sb2FkIGNhbGwgc2hvdWxkIGZhaWwgd2l0aCBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgZG93bmxvYWRlci5kb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZShkb3dubG9hZFJlcXVlc3QpOworICAgIEV4ZWN1dGlvbkV4Y2VwdGlvbiBlID0gYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgZG93bmxvYWRGdXR1cmU6OmdldCk7CisgICAgYXNzZXJ0VGhhdChlKS5oYXNDYXVzZVRoYXQoKS5pc0luc3RhbmNlT2YoSWxsZWdhbFN0YXRlRXhjZXB0aW9uLmNsYXNzKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IHVuZGVybHlpbmcgZG93bmxvYWQgaXMgbm90IHN0YXJ0ZWQKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTW9uaXRvciwgdGltZXMoMCkpCisgICAgICAgIC5hZGREb3dubG9hZExpc3RlbmVyKGFueShVcmkuY2xhc3MpLCBhbnkoRG93bmxvYWRMaXN0ZW5lci5jbGFzcykpOworICAgIHZlcmlmeShmaWxlRG93bmxvYWRlciwgdGltZXMoMCkpCisgICAgICAgIC5zdGFydERvd25sb2FkaW5nKAorICAgICAgICAgICAgYW55KGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0LmNsYXNzKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZV9yZXF1aXJlc0Rvd25sb2FkTW9uaXRvcigpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIENyZWF0ZSBkb3dubG9hZGVyIHdpdGhvdXQgcHJvdmlkaW5nIERvd25sb2FkTW9uaXRvcgorICAgIGRvd25sb2FkZXIgPQorICAgICAgICBEb3dubG9hZGVyLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldENvbnRleHQoY29udGV4dCkKKyAgICAgICAgICAgIC5zZXRDb250cm9sRXhlY3V0b3IoQ09OVFJPTF9FWEVDVVRPUikKKyAgICAgICAgICAgIC5zZXRGb3JlZ3JvdW5kRG93bmxvYWRTZXJ2aWNlKAorICAgICAgICAgICAgICAgIHRoaXMuZ2V0Q2xhc3MoKSkgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlLgorICAgICAgICAgICAgLnNldEZpbGVEb3dubG9hZGVyU3VwcGxpZXIoKCkgLT4gZmlsZURvd25sb2FkZXIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIC8vIFdpdGhvdXQgZm9yZWdyb3VuZCBzZXJ2aWNlLCBkb3dubG9hZCBjYWxsIHNob3VsZCBmYWlsIHdpdGggSWxsZWdhbFN0YXRlRXhjZXB0aW9uCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIGRvd25sb2FkZXIuZG93bmxvYWRXaXRoRm9yZWdyb3VuZFNlcnZpY2UoZG93bmxvYWRSZXF1ZXN0KTsKKyAgICBFeGVjdXRpb25FeGNlcHRpb24gZSA9IGFzc2VydFRocm93cyhFeGVjdXRpb25FeGNlcHRpb24uY2xhc3MsIGRvd25sb2FkRnV0dXJlOjpnZXQpOworICAgIGFzc2VydFRoYXQoZSkuaGFzQ2F1c2VUaGF0KCkuaXNJbnN0YW5jZU9mKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbi5jbGFzcyk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB1bmRlcmx5aW5nIGRvd25sb2FkIGlzIG5vdCBzdGFydGVkCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZE1vbml0b3IsIHRpbWVzKDApKQorICAgICAgICAuYWRkRG93bmxvYWRMaXN0ZW5lcihhbnkoVXJpLmNsYXNzKSwgYW55KERvd25sb2FkTGlzdGVuZXIuY2xhc3MpKTsKKyAgICB2ZXJpZnkoZmlsZURvd25sb2FkZXIsIHRpbWVzKDApKQorICAgICAgICAuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIGFueShjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdC5jbGFzcykpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZG93bmxvYWRXaXRoRm9yZWdyb3VuZFNlcnZpY2Vfd2hlblJlcXVlc3RBbHJlYWR5TWFkZV9kZWR1cHMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBVc2UgQmxvY2tpbmdGaWxlRG93bmxvYWRlciB0byBjb250cm9sIHdoZW4gdGhlIGRvd25sb2FkIHdpbGwgZmluaXNoLgorICAgIEJsb2NraW5nRmlsZURvd25sb2FkZXIgYmxvY2tpbmdGaWxlRG93bmxvYWRlciA9CisgICAgICAgIG5ldyBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyKGxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSk7CisgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGJsb2NraW5nRG93bmxvYWRlclN1cHBsaWVyID0gKCkgLT4gYmxvY2tpbmdGaWxlRG93bmxvYWRlcjsKKworICAgIERvd25sb2FkZXJJbXBsIGRvd25sb2FkZXJJbXBsID0KKyAgICAgICAgbmV3IERvd25sb2FkZXJJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIENPTlRST0xfRVhFQ1VUT1IsCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrRG93bmxvYWRNb25pdG9yKSwKKyAgICAgICAgICAgIGJsb2NraW5nRG93bmxvYWRlclN1cHBsaWVyKTsKKworICAgIGludCBkb3dubG9hZEZ1dHVyZXNJbkZsaWdodENvdW50QmVmb3JlID0gZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlLnNpemUoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUxID0KKyAgICAgICAgZG93bmxvYWRlckltcGwuZG93bmxvYWRXaXRoRm9yZWdyb3VuZFNlcnZpY2UoZG93bmxvYWRSZXF1ZXN0KTsKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlMiA9CisgICAgICAgIGRvd25sb2FkZXJJbXBsLmRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlKGRvd25sb2FkUmVxdWVzdCk7CisKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZSkuY29udGFpbnNLZXkoZGVzdGluYXRpb25GaWxlVXJpLnRvU3RyaW5nKCkpOworCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUuc2l6ZSgpIC0gZG93bmxvYWRGdXR1cmVzSW5GbGlnaHRDb3VudEJlZm9yZSkKKyAgICAgICAgLmlzRXF1YWxUbygxKTsKKworICAgIC8vIE5vdyB3ZSBsZXQgdGhlIDIgZnV0dXJlcyBkb3dubG9hZEZ1dHVyZTEgZG93bmxvYWRGdXR1cmUyIHRvIHJ1biBieSBvcGVuaW5nIHRoZSBsYXRjaC4KKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLmZpbmlzaERvd25sb2FkaW5nKCk7CisKKyAgICAvLyBOb3cgZmluaXNoIGZ1dHVyZSAyLCBmdXR1cmUgMSBzaG91bGQgZmluaXNoIHRvbyBhbmQgdGhlIGNhY2hlIGNsZWFycyB0aGUgZnV0dXJlLgorICAgIGRvd25sb2FkRnV0dXJlMi5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkRnV0dXJlMS5pc0RvbmUoKSkuaXNUcnVlKCk7CisKKyAgICAvLyBUT0RPKGIvMTQ3NTgzMDU5KTogQ29udmVydCB0byBGcmFtZXdvcmsgdGVzdCBhbmQgdXNlIFRlc3RpbmdUYXNrQmFycmllciB0byBhdm9pZCBzbGVlcC4KKyAgICAvLyBTbGVlcCBmb3IgMSBzZWMgdG8gd2FpdCBmb3IgdGhlIEZ1dHVyZSdzIGNhbGxiYWNrIHRvIGZpbmlzaC4KKyAgICBUaHJlYWQuc2xlZXAoLyptaWxsaXM9Ki8gMTAwMCk7CisgICAgLy8gVGhlIGNvbXBsZXRlZCBkb3dubG9hZCBpcyByZW1vdmVkIGZyb20gdGhlIHVyaVRvTGlzdGVuYWJsZUZ1dHVyZSBNYXAuCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpCisgICAgICAgIC5kb2VzTm90Q29udGFpbktleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpLmhhc1NpemUoZG93bmxvYWRGdXR1cmVzSW5GbGlnaHRDb3VudEJlZm9yZSk7CisKKyAgICAvLyBSZXNldCBzdGF0ZSBvZiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyIHRvIHByZXZlbnQgZGVhZGxvY2tzCisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci5yZXNldFN0YXRlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZV93aGVuUmVxdWVzdEFscmVhZHlNYWRlV2l0aG91dEZvcmVncm91bmRTZXJ2aWNlX2RlZHVwcygpCisgICAgICB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBVc2UgQmxvY2tpbmdGaWxlRG93bmxvYWRlciB0byBjb250cm9sIHdoZW4gdGhlIGRvd25sb2FkIHdpbGwgZmluaXNoLgorICAgIEJsb2NraW5nRmlsZURvd25sb2FkZXIgYmxvY2tpbmdGaWxlRG93bmxvYWRlciA9CisgICAgICAgIG5ldyBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyKGxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSk7CisgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGJsb2NraW5nRG93bmxvYWRlclN1cHBsaWVyID0gKCkgLT4gYmxvY2tpbmdGaWxlRG93bmxvYWRlcjsKKworICAgIERvd25sb2FkZXJJbXBsIGRvd25sb2FkZXJJbXBsID0KKyAgICAgICAgbmV3IERvd25sb2FkZXJJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZS4KKyAgICAgICAgICAgIENPTlRST0xfRVhFQ1VUT1IsCisgICAgICAgICAgICBPcHRpb25hbC5vZihtb2NrRG93bmxvYWRNb25pdG9yKSwKKyAgICAgICAgICAgIGJsb2NraW5nRG93bmxvYWRlclN1cHBsaWVyKTsKKworICAgIGludCBkb3dubG9hZEZ1dHVyZXNJbkZsaWdodENvdW50QmVmb3JlID0gZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlLnNpemUoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUxID0gZG93bmxvYWRlckltcGwuZG93bmxvYWQoZG93bmxvYWRSZXF1ZXN0KTsKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlMiA9CisgICAgICAgIGRvd25sb2FkZXJJbXBsLmRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlKGRvd25sb2FkUmVxdWVzdCk7CisKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZSkuY29udGFpbnNLZXkoZGVzdGluYXRpb25GaWxlVXJpLnRvU3RyaW5nKCkpOworCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUuc2l6ZSgpIC0gZG93bmxvYWRGdXR1cmVzSW5GbGlnaHRDb3VudEJlZm9yZSkKKyAgICAgICAgLmlzRXF1YWxUbygxKTsKKworICAgIC8vIE5vdyB3ZSBsZXQgdGhlIDIgZnV0dXJlcyBkb3dubG9hZEZ1dHVyZTEgZG93bmxvYWRGdXR1cmUyIHRvIHJ1biBieSBvcGVuaW5nIHRoZSBsYXRjaC4KKyAgICBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLmZpbmlzaERvd25sb2FkaW5nKCk7CisKKyAgICAvLyBOb3cgZmluaXNoIGZ1dHVyZSAyLCBmdXR1cmUgMSBzaG91bGQgZmluaXNoIHRvbyBhbmQgdGhlIGNhY2hlIGNsZWFycyB0aGUgZnV0dXJlLgorICAgIGRvd25sb2FkRnV0dXJlMi5nZXQoKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkRnV0dXJlMS5pc0RvbmUoKSkuaXNUcnVlKCk7CisKKyAgICAvLyBUT0RPKGIvMTU1OTE4NDA2KTogQ29udmVydCB0byBGcmFtZXdvcmsgdGVzdCBhbmQgdXNlIFRlc3RpbmdUYXNrQmFycmllciB0byBhdm9pZCBzbGVlcC4KKyAgICAvLyBTbGVlcCBmb3IgMSBzZWMgdG8gd2FpdCBmb3IgdGhlIEZ1dHVyZSdzIGNhbGxiYWNrIHRvIGZpbmlzaC4KKyAgICBUaHJlYWQuc2xlZXAoLyptaWxsaXM9Ki8gMTAwMCk7CisgICAgLy8gVGhlIGNvbXBsZXRlZCBkb3dubG9hZCBpcyByZW1vdmVkIGZyb20gdGhlIHVyaVRvTGlzdGVuYWJsZUZ1dHVyZSBNYXAuCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpCisgICAgICAgIC5kb2VzTm90Q29udGFpbktleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpLmhhc1NpemUoZG93bmxvYWRGdXR1cmVzSW5GbGlnaHRDb3VudEJlZm9yZSk7CisKKyAgICAvLyBSZXNldCBzdGF0ZSBvZiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyIHRvIHByZXZlbnQgZGVhZGxvY2tzCisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci5yZXNldFN0YXRlKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZSgpIHRocm93cyBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBBcmd1bWVudENhcHRvcjxEb3dubG9hZExpc3RlbmVyPiBkb3dubG9hZExpc3RlbmVyQ2FwdG9yID0KKyAgICAgICAgQXJndW1lbnRDYXB0b3IuZm9yQ2xhc3MoRG93bmxvYWRMaXN0ZW5lci5jbGFzcyk7CisgICAgQXJndW1lbnRDYXB0b3I8Y29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3Q+CisgICAgICAgIGRvd25sb2FkUmVxdWVzdENhcHRvciA9CisgICAgICAgICAgICBBcmd1bWVudENhcHRvci5mb3JDbGFzcygKKyAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdC5jbGFzcyk7CisgICAgd2hlbihmaWxlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKGRvd25sb2FkUmVxdWVzdENhcHRvci5jYXB0dXJlKCkpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShudWxsKSk7CisKKyAgICBkb3dubG9hZFJlcXVlc3QgPQorICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGVzdGluYXRpb25GaWxlVXJpKGRlc3RpbmF0aW9uRmlsZVVyaSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCkKKyAgICAgICAgICAgIC5zZXROb3RpZmljYXRpb25Db250ZW50VGl0bGUoIkZpbGUgdXJsOiAiICsgRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbChPcHRpb25hbC5vZihtb2NrRG93bmxvYWRMaXN0ZW5lcikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBkb3dubG9hZGVyLmRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlKGRvd25sb2FkUmVxdWVzdCk7CisgICAgZG93bmxvYWRGdXR1cmUuZ2V0KCk7CisKKyAgICAvLyBUT0RPKGIvMTQ3NTgzMDU5KTogQ29udmVydCB0byBGcmFtZXdvcmsgdGVzdCBhbmQgdXNlIFRlc3RpbmdUYXNrQmFycmllciB0byBhdm9pZCBzbGVlcC4KKyAgICAvLyBTbGVlcCBmb3IgMSBzZWMgdG8gd2FpdCBmb3IgdGhlIEZ1dHVyZSdzIGNhbGxiYWNrIHRvIGZpbmlzaC4KKyAgICBUaHJlYWQuc2xlZXAoLyptaWxsaXM9Ki8gMTAwMCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGUgY29ycmVjdCBEb3dubG9hZFJlcXVlc3QgaXMgc2VudCB0byB1bmRlcmRlcmx5aW5nIEZpbGVEb3dubG9hZGVyLgorICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0CisgICAgICAgIGFjdHVhbERvd25sb2FkUmVxdWVzdCA9IGRvd25sb2FkUmVxdWVzdENhcHRvci5nZXRWYWx1ZSgpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LmZpbGVVcmkoKSkuaXNFcXVhbFRvKGRlc3RpbmF0aW9uRmlsZVVyaSk7CisgICAgYXNzZXJ0VGhhdChhY3R1YWxEb3dubG9hZFJlcXVlc3QudXJsVG9Eb3dubG9hZCgpKS5pc0VxdWFsVG8oRklMRV9VUkwpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LmRvd25sb2FkQ29uc3RyYWludHMoKSkKKyAgICAgICAgLmlzRXF1YWxUbyhEb3dubG9hZENvbnN0cmFpbnRzLk5FVFdPUktfQ09OTkVDVEVEKTsKKworICAgIC8vIFZlcmlmeSB0aGF0IGRvd25sb2FkTW9uaXRvciB3aWxsIGFkZCBhIERvd25sb2FkTGlzdGVuZXIuCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZE1vbml0b3IpCisgICAgICAgIC5hZGREb3dubG9hZExpc3RlbmVyKGFueShVcmkuY2xhc3MpLCBkb3dubG9hZExpc3RlbmVyQ2FwdG9yLmNhcHR1cmUoKSk7CisgICAgdmVyaWZ5KGZpbGVEb3dubG9hZGVyKQorICAgICAgICAuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgICAgIGFueShjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdC5jbGFzcykpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZE1vbml0b3IpLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoZGVzdGluYXRpb25GaWxlVXJpKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcikub25Db21wbGV0ZSgpOworCisgICAgLy8gTm93IHNpbXVsYXRlIG90aGVyIERvd25sb2FkTGlzdGVuZXIncyBjYWxsYmFja3M6CisgICAgZG93bmxvYWRMaXN0ZW5lckNhcHRvci5nZXRWYWx1ZSgpLm9uUHJvZ3Jlc3MoMTApOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcikub25Qcm9ncmVzcygxMCk7CisgICAgZG93bmxvYWRMaXN0ZW5lckNhcHRvci5nZXRWYWx1ZSgpLm9uUGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gZG93bmxvYWRFeGNlcHRpb24gPQorICAgICAgICBEb3dubG9hZEV4Y2VwdGlvbi5idWlsZGVyKCkuc2V0RG93bmxvYWRSZXN1bHRDb2RlKEFORFJPSURfRE9XTkxPQURFUl9VTktOT1dOKS5idWlsZCgpOworICAgIGRvd25sb2FkTGlzdGVuZXJDYXB0b3IuZ2V0VmFsdWUoKS5vbkZhaWx1cmUoZG93bmxvYWRFeGNlcHRpb24pOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyKS5vblBhdXNlZEZvckNvbm5lY3Rpdml0eSgpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcikub25GYWlsdXJlKGRvd25sb2FkRXhjZXB0aW9uKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlX2NsaWVudE9uQ29tcGxldGVGYWlsZWQoKQorICAgICAgdGhyb3dzIEV4ZWN1dGlvbkV4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgIEFyZ3VtZW50Q2FwdG9yPERvd25sb2FkTGlzdGVuZXI+IGRvd25sb2FkTGlzdGVuZXJDYXB0b3IgPQorICAgICAgICBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhEb3dubG9hZExpc3RlbmVyLmNsYXNzKTsKKyAgICBBcmd1bWVudENhcHRvcjxjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdD4KKyAgICAgICAgZG93bmxvYWRSZXF1ZXN0Q2FwdG9yID0KKyAgICAgICAgICAgIEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKAorICAgICAgICAgICAgICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0LmNsYXNzKTsKKyAgICB3aGVuKGZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoZG93bmxvYWRSZXF1ZXN0Q2FwdG9yLmNhcHR1cmUoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKworICAgIC8vIENsaWVudCdzIHByb3ZpZGVkIERvd25sb2FkTGlzdGVuZXIub25Db21wbGV0ZSBmYWlsZWQuCisgICAgd2hlbihtb2NrRG93bmxvYWRMaXN0ZW5lci5vbkNvbXBsZXRlKCkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKG5ldyBFeGNlcHRpb24oKSkpOworCisgICAgZG93bmxvYWRSZXF1ZXN0ID0KKyAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldERlc3RpbmF0aW9uRmlsZVVyaShkZXN0aW5hdGlvbkZpbGVVcmkpCisgICAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZChGSUxFX1VSTCkKKyAgICAgICAgICAgIC5zZXREb3dubG9hZENvbnN0cmFpbnRzKERvd25sb2FkQ29uc3RyYWludHMuTkVUV09SS19DT05ORUNURUQpCisgICAgICAgICAgICAuc2V0Tm90aWZpY2F0aW9uQ29udGVudFRpdGxlKCJGaWxlIHVybDogIiArIEZJTEVfVVJMKQorICAgICAgICAgICAgLnNldExpc3RlbmVyT3B0aW9uYWwoT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTGlzdGVuZXIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IGRvd25sb2FkRnV0dXJlID0KKyAgICAgICAgZG93bmxvYWRlci5kb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZShkb3dubG9hZFJlcXVlc3QpOworICAgIGRvd25sb2FkRnV0dXJlLmdldCgpOworCisgICAgLy8gVE9ETyhiLzE0NzU4MzA1OSk6IENvbnZlcnQgdG8gRnJhbWV3b3JrIHRlc3QgYW5kIHVzZSBUZXN0aW5nVGFza0JhcnJpZXIgdG8gYXZvaWQgc2xlZXAuCisgICAgLy8gU2xlZXAgZm9yIDEgc2VjIHRvIHdhaXQgZm9yIHRoZSBGdXR1cmUncyBjYWxsYmFjayB0byBmaW5pc2guCisgICAgVGhyZWFkLnNsZWVwKC8qbWlsbGlzPSovIDEwMDApOworCisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGNvcnJlY3QgRG93bmxvYWRSZXF1ZXN0IGlzIHNlbnQgdG8gdW5kZXJkZXJseWluZyBGaWxlRG93bmxvYWRlci4KKyAgICBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdAorICAgICAgICBhY3R1YWxEb3dubG9hZFJlcXVlc3QgPSBkb3dubG9hZFJlcXVlc3RDYXB0b3IuZ2V0VmFsdWUoKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbERvd25sb2FkUmVxdWVzdC5maWxlVXJpKCkpLmlzRXF1YWxUbyhkZXN0aW5hdGlvbkZpbGVVcmkpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LnVybFRvRG93bmxvYWQoKSkuaXNFcXVhbFRvKEZJTEVfVVJMKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbERvd25sb2FkUmVxdWVzdC5kb3dubG9hZENvbnN0cmFpbnRzKCkpCisgICAgICAgIC5pc0VxdWFsVG8oRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBkb3dubG9hZE1vbml0b3Igd2lsbCBhZGQgYSBEb3dubG9hZExpc3RlbmVyLgorICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKQorICAgICAgICAuYWRkRG93bmxvYWRMaXN0ZW5lcihhbnkoVXJpLmNsYXNzKSwgZG93bmxvYWRMaXN0ZW5lckNhcHRvci5jYXB0dXJlKCkpOworICAgIHZlcmlmeShmaWxlRG93bmxvYWRlcikKKyAgICAgICAgLnN0YXJ0RG93bmxvYWRpbmcoCisgICAgICAgICAgICBhbnkoY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3QuY2xhc3MpKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGRlc3RpbmF0aW9uRmlsZVVyaSk7CisKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIpLm9uQ29tcGxldGUoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlX2NsaWVudE9uQ29tcGxldGVCbG9ja2VkKCkKKyAgICAgIHRocm93cyBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBBcmd1bWVudENhcHRvcjxjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdD4KKyAgICAgICAgZG93bmxvYWRSZXF1ZXN0Q2FwdG9yID0KKyAgICAgICAgICAgIEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKAorICAgICAgICAgICAgICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0LmNsYXNzKTsKKyAgICB3aGVuKGZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoZG93bmxvYWRSZXF1ZXN0Q2FwdG9yLmNhcHR1cmUoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpKTsKKworICAgIC8vIFVzaW5nIGxhdGNoIHRvIGJsb2NrIG9uIGNsaWVudCdzIG9uQ29tcGxldGUgdG8gc2ltdWxhdGUgYSB2ZXJ5IGxvbmcgcnVubmluZyBvbkNvbXBsZXRlLgorICAgIENvdW50RG93bkxhdGNoIGJsb2NraW5nT25Db21wbGV0ZUxhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworCisgICAgRG93bmxvYWRlckltcGwgZG93bmxvYWRlckltcGwgPQorICAgICAgICBuZXcgRG93bmxvYWRlckltcGwoCisgICAgICAgICAgICBjb250ZXh0LAorICAgICAgICAgICAgT3B0aW9uYWwub2YodGhpcy5nZXRDbGFzcygpKSwgLy8gZG9uJ3QgbmVlZCB0byB1c2UgdGhlIHJlYWwgZm9yZWdyb3VuZCBkb3dubG9hZCBzZXJ2aWNlCisgICAgICAgICAgICBDT05UUk9MX0VYRUNVVE9SLAorICAgICAgICAgICAgT3B0aW9uYWwub2YobW9ja0Rvd25sb2FkTW9uaXRvciksCisgICAgICAgICAgICAoKSAtPiBmaWxlRG93bmxvYWRlcik7CisKKyAgICBkb3dubG9hZFJlcXVlc3QgPQorICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGVzdGluYXRpb25GaWxlVXJpKGRlc3RpbmF0aW9uRmlsZVVyaSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCkKKyAgICAgICAgICAgIC5zZXROb3RpZmljYXRpb25Db250ZW50VGl0bGUoIkZpbGUgdXJsOiAiICsgRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbCgKKyAgICAgICAgICAgICAgICBPcHRpb25hbC5vZigKKyAgICAgICAgICAgICAgICAgICAgbmV3IERvd25sb2FkTGlzdGVuZXIoKSB7CisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25Qcm9ncmVzcyhsb25nIGN1cnJlbnRTaXplKSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gb25Db21wbGV0ZSgpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLnN1Ym1pdEFzeW5jKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICgpIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJsb2NrIHRoZSBvbkNvbXBsZXRlIHRhc2suCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZlcmlmeSB0aGF0IGJlZm9yZSBjbGllbnQncyBvbkNvbXBsZXRlIGZpbmlzaGVzLCB0aGUgb24tZ29pbmcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZG93bmxvYWQgZnV0dXJlIG1hcCBzdGlsbCBjb250YWluIHRoaXMgZG93bmxvYWQuIFRoaXMgbWVhbnMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIEZvcmVncm91bmQgRG93bmxvYWQgU2VydmljZSBoYXMgbm90IGJlIHNodXQgZG93biB5ZXQuCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc2VydFRoYXQoZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbnRhaW5zS2V5KGRlc3RpbmF0aW9uRmlsZVVyaS50b1N0cmluZygpKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tpbmdPbkNvbXBsZXRlTGF0Y2guYXdhaXQoKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlLgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG51bGwpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQkFDS0dST1VORF9FWEVDVVRPUik7CisgICAgICAgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25GYWlsdXJlKFRocm93YWJsZSB0KSB7fQorCisgICAgICAgICAgICAgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgICAgICAgICAgICAgcHVibGljIHZvaWQgb25QYXVzZWRGb3JDb25uZWN0aXZpdHkoKSB7fQorICAgICAgICAgICAgICAgICAgICB9KSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIGRvd25sb2FkZXJJbXBsLmRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlKGRvd25sb2FkUmVxdWVzdCk7CisgICAgZG93bmxvYWRGdXR1cmUuZ2V0KCk7CisKKyAgICAvLyBUT0RPKGIvMTQ3NTgzMDU5KTogQ29udmVydCB0byBGcmFtZXdvcmsgdGVzdCBhbmQgdXNlIFRlc3RpbmdUYXNrQmFycmllciB0byBhdm9pZCBzbGVlcC4KKyAgICAvLyBTbGVlcCBmb3IgMSBzZWMgdG8gd2FpdCBmb3IgdGhlIEZ1dHVyZSdzIGNhbGxiYWNrIHRvIGZpbmlzaC4KKyAgICBUaHJlYWQuc2xlZXAoLyptaWxsaXM9Ki8gMTAwMCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCB0aGlzIGRvd25sb2FkIGZ1dHVyZSBoYXMgbm90IGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSBrZXlUb0xpc3RlbmFibGVGdXR1cmUgbWFwIHlldC4KKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZSkuY29udGFpbnNLZXkoZGVzdGluYXRpb25GaWxlVXJpLnRvU3RyaW5nKCkpOworCisgICAgLy8gTm93IGxldCdzIHRoZSBvbkNvbXBsZXRlIGZpbmlzaGVzLgorICAgIGJsb2NraW5nT25Db21wbGV0ZUxhdGNoLmNvdW50RG93bigpOworCisgICAgLy8gVE9ETyhiLzE0NzU4MzA1OSk6IENvbnZlcnQgdG8gRnJhbWV3b3JrIHRlc3QgYW5kIHVzZSBUZXN0aW5nVGFza0JhcnJpZXIgdG8gYXZvaWQgc2xlZXAuCisgICAgLy8gU2xlZXAgZm9yIDEgc2VjIHRvIHdhaXQgZm9yIHRoZSBGdXR1cmUncyBjYWxsYmFjayBvbiBvbkNvbXBsZXRlIHRvIGZpbmlzaC4KKyAgICBUaHJlYWQuc2xlZXAoLyptaWxsaXM9Ki8gMTAwMCk7CisKKyAgICAvLyBUaGUgY29tcGxldGVkIGRvd25sb2FkIGlzIHJlbW92ZWQgZnJvbSB0aGUga2V5VG9MaXN0ZW5hYmxlRnV0dXJlIE1hcC4KKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZSkKKyAgICAgICAgLmRvZXNOb3RDb250YWluS2V5KGRlc3RpbmF0aW9uRmlsZVVyaS50b1N0cmluZygpKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZSkuaXNFbXB0eSgpOworCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZE1vbml0b3IpLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoZGVzdGluYXRpb25GaWxlVXJpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlX2ZhaWx1cmUoKQorICAgICAgdGhyb3dzIEV4ZWN1dGlvbkV4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgIEFyZ3VtZW50Q2FwdG9yPERvd25sb2FkTGlzdGVuZXI+IGRvd25sb2FkTGlzdGVuZXJDYXB0b3IgPQorICAgICAgICBBcmd1bWVudENhcHRvci5mb3JDbGFzcyhEb3dubG9hZExpc3RlbmVyLmNsYXNzKTsKKyAgICBBcmd1bWVudENhcHRvcjxjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdD4KKyAgICAgICAgZG93bmxvYWRSZXF1ZXN0Q2FwdG9yID0KKyAgICAgICAgICAgIEFyZ3VtZW50Q2FwdG9yLmZvckNsYXNzKAorICAgICAgICAgICAgICAgIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmRvd25sb2FkZXIuRG93bmxvYWRSZXF1ZXN0LmNsYXNzKTsKKyAgICBEb3dubG9hZEV4Y2VwdGlvbiBkb3dubG9hZEV4Y2VwdGlvbiA9CisgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKS5zZXREb3dubG9hZFJlc3VsdENvZGUoQU5EUk9JRF9ET1dOTE9BREVSX1VOS05PV04pLmJ1aWxkKCk7CisKKyAgICB3aGVuKGZpbGVEb3dubG9hZGVyLnN0YXJ0RG93bmxvYWRpbmcoZG93bmxvYWRSZXF1ZXN0Q2FwdG9yLmNhcHR1cmUoKSkpCisgICAgICAgIC50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRmFpbGVkRnV0dXJlKGRvd25sb2FkRXhjZXB0aW9uKSk7CisKKyAgICBkb3dubG9hZFJlcXVlc3QgPQorICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RGVzdGluYXRpb25GaWxlVXJpKGRlc3RpbmF0aW9uRmlsZVVyaSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKEZJTEVfVVJMKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCkKKyAgICAgICAgICAgIC5zZXROb3RpZmljYXRpb25Db250ZW50VGl0bGUoIkZpbGUgdXJsOiAiICsgRklMRV9VUkwpCisgICAgICAgICAgICAuc2V0TGlzdGVuZXJPcHRpb25hbChPcHRpb25hbC5vZihtb2NrRG93bmxvYWRMaXN0ZW5lcikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBkb3dubG9hZGVyLmRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlKGRvd25sb2FkUmVxdWVzdCk7CisgICAgYXNzZXJ0VGhyb3dzKEV4ZWN1dGlvbkV4Y2VwdGlvbi5jbGFzcywgZG93bmxvYWRGdXR1cmU6OmdldCk7CisgICAgRG93bmxvYWRFeGNlcHRpb24gZSA9IExhYnNGdXR1cmVzLmdldEZhaWx1cmVDYXVzZUFzKGRvd25sb2FkRnV0dXJlLCBEb3dubG9hZEV4Y2VwdGlvbi5jbGFzcyk7CisgICAgYXNzZXJ0VGhhdChlLmdldERvd25sb2FkUmVzdWx0Q29kZSgpKS5pc0VxdWFsVG8oQU5EUk9JRF9ET1dOTE9BREVSX1VOS05PV04pOworCisgICAgLy8gVE9ETyhiLzE0NzU4MzA1OSk6IENvbnZlcnQgdG8gRnJhbWV3b3JrIHRlc3QgYW5kIHVzZSBUZXN0aW5nVGFza0JhcnJpZXIgdG8gYXZvaWQgc2xlZXAuCisgICAgLy8gU2xlZXAgZm9yIDEgc2VjIHRvIHdhaXQgZm9yIHRoZSBsaXN0ZW5lciB0byBmaW5pc2guCisgICAgVGhyZWFkLnNsZWVwKC8qbWlsbGlzPSovIDEwMDApOworCisgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGNvcnJlY3QgRG93bmxvYWRSZXF1ZXN0IGlzIHNlbnQgdG8gdW5kZXJkZXJseWluZyBGaWxlRG93bmxvYWRlci4KKyAgICBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkUmVxdWVzdAorICAgICAgICBhY3R1YWxEb3dubG9hZFJlcXVlc3QgPSBkb3dubG9hZFJlcXVlc3RDYXB0b3IuZ2V0VmFsdWUoKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbERvd25sb2FkUmVxdWVzdC5maWxlVXJpKCkpLmlzRXF1YWxUbyhkZXN0aW5hdGlvbkZpbGVVcmkpOworICAgIGFzc2VydFRoYXQoYWN0dWFsRG93bmxvYWRSZXF1ZXN0LnVybFRvRG93bmxvYWQoKSkuaXNFcXVhbFRvKEZJTEVfVVJMKTsKKyAgICBhc3NlcnRUaGF0KGFjdHVhbERvd25sb2FkUmVxdWVzdC5kb3dubG9hZENvbnN0cmFpbnRzKCkpCisgICAgICAgIC5pc0VxdWFsVG8oRG93bmxvYWRDb25zdHJhaW50cy5ORVRXT1JLX0NPTk5FQ1RFRCk7CisKKyAgICAvLyBWZXJpZnkgdGhhdCBkb3dubG9hZE1vbml0b3Igd2lsbCBhZGQgYSBEb3dubG9hZExpc3RlbmVyLgorICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKQorICAgICAgICAuYWRkRG93bmxvYWRMaXN0ZW5lcihhbnkoVXJpLmNsYXNzKSwgZG93bmxvYWRMaXN0ZW5lckNhcHRvci5jYXB0dXJlKCkpOworICAgIHZlcmlmeShmaWxlRG93bmxvYWRlcikKKyAgICAgICAgLnN0YXJ0RG93bmxvYWRpbmcoCisgICAgICAgICAgICBhbnkoY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3QuY2xhc3MpKTsKKworICAgIHZlcmlmeShtb2NrRG93bmxvYWRNb25pdG9yKS5yZW1vdmVEb3dubG9hZExpc3RlbmVyKGRlc3RpbmF0aW9uRmlsZVVyaSk7CisKKyAgICAvLyBTaW5jZSB0aGUgZG93bmxvYWQgZmFpbGVkLCBvbkNvbXBsZXRlIHdpbGwgbm90IGJlIGNhbGxlZCBidXQgb25GYWlsdXJlLgorICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lciwgdGltZXMoMCkpLm9uQ29tcGxldGUoKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIpLm9uRmFpbHVyZShkb3dubG9hZEV4Y2VwdGlvbik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBjYW5jZWxEb3dubG9hZFdpdGhGb3JlZ3JvdW5kU2VydmljZSgpIHsKKyAgICAvLyBVc2UgQmxvY2tpbmdGaWxlRG93bmxvYWRlciB0byBjb250cm9sIHdoZW4gdGhlIGRvd25sb2FkIHdpbGwgZmluaXNoLgorICAgIEJsb2NraW5nRmlsZURvd25sb2FkZXIgYmxvY2tpbmdGaWxlRG93bmxvYWRlciA9CisgICAgICAgIG5ldyBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyKGxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSk7CisgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGJsb2NraW5nRG93bmxvYWRlclN1cHBsaWVyID0gKCkgLT4gYmxvY2tpbmdGaWxlRG93bmxvYWRlcjsKKworICAgIERvd25sb2FkZXJJbXBsIGRvd25sb2FkZXJJbXBsID0KKyAgICAgICAgbmV3IERvd25sb2FkZXJJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZQorICAgICAgICAgICAgQ09OVFJPTF9FWEVDVVRPUiwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZE1vbml0b3IpLAorICAgICAgICAgICAgYmxvY2tpbmdEb3dubG9hZGVyU3VwcGxpZXIpOworCisgICAgaW50IGRvd25sb2FkRnV0dXJlc0luRmxpZ2h0Q291bnRCZWZvcmUgPSBkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUuc2l6ZSgpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIGRvd25sb2FkZXJJbXBsLmRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlKGRvd25sb2FkUmVxdWVzdCk7CisKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZSkuY29udGFpbnNLZXkoZGVzdGluYXRpb25GaWxlVXJpLnRvU3RyaW5nKCkpOworCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUuc2l6ZSgpIC0gZG93bmxvYWRGdXR1cmVzSW5GbGlnaHRDb3VudEJlZm9yZSkKKyAgICAgICAgLmlzRXF1YWxUbygxKTsKKworICAgIGRvd25sb2FkZXJJbXBsLmNhbmNlbEZvcmVncm91bmREb3dubG9hZChkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisgICAgYXNzZXJ0VHJ1ZShkb3dubG9hZEZ1dHVyZS5pc0NhbmNlbGxlZCgpKTsKKworICAgIC8vIFRoZSBjb21wbGV0ZWQgZG93bmxvYWQgaXMgcmVtb3ZlZCBmcm9tIHRoZSB1cmlUb0xpc3RlbmFibGVGdXR1cmUgTWFwLgorICAgIGFzc2VydFRoYXQoZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlKQorICAgICAgICAuZG9lc05vdENvbnRhaW5LZXkoZGVzdGluYXRpb25GaWxlVXJpLnRvU3RyaW5nKCkpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRlckltcGwua2V5VG9MaXN0ZW5hYmxlRnV0dXJlKS5oYXNTaXplKGRvd25sb2FkRnV0dXJlc0luRmxpZ2h0Q291bnRCZWZvcmUpOworCisgICAgLy8gUmVzZXQgc3RhdGUgb2YgYmxvY2tpbmdGaWxlRG93bmxvYWRlciB0byBwcmV2ZW50IGRlYWRsb2NrcworICAgIGJsb2NraW5nRmlsZURvd25sb2FkZXIucmVzZXRTdGF0ZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgY2FuY2VsTGlzdGVuYWJsZUZ1dHVyZSgpIHsKKyAgICAvLyBVc2UgQmxvY2tpbmdGaWxlRG93bmxvYWRlciB0byBjb250cm9sIHdoZW4gdGhlIGRvd25sb2FkIHdpbGwgZmluaXNoLgorICAgIEJsb2NraW5nRmlsZURvd25sb2FkZXIgYmxvY2tpbmdGaWxlRG93bmxvYWRlciA9CisgICAgICAgIG5ldyBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyKGxpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSk7CisgICAgU3VwcGxpZXI8RmlsZURvd25sb2FkZXI+IGJsb2NraW5nRG93bmxvYWRlclN1cHBsaWVyID0gKCkgLT4gYmxvY2tpbmdGaWxlRG93bmxvYWRlcjsKKworICAgIERvd25sb2FkZXJJbXBsIGRvd25sb2FkZXJJbXBsID0KKyAgICAgICAgbmV3IERvd25sb2FkZXJJbXBsKAorICAgICAgICAgICAgY29udGV4dCwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKHRoaXMuZ2V0Q2xhc3MoKSksIC8vIGRvbid0IG5lZWQgdG8gdXNlIHRoZSByZWFsIGZvcmVncm91bmQgZG93bmxvYWQgc2VydmljZQorICAgICAgICAgICAgQ09OVFJPTF9FWEVDVVRPUiwKKyAgICAgICAgICAgIE9wdGlvbmFsLm9mKG1vY2tEb3dubG9hZE1vbml0b3IpLAorICAgICAgICAgICAgYmxvY2tpbmdEb3dubG9hZGVyU3VwcGxpZXIpOworCisgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiBkb3dubG9hZEZ1dHVyZSA9CisgICAgICAgIGRvd25sb2FkZXJJbXBsLmRvd25sb2FkV2l0aEZvcmVncm91bmRTZXJ2aWNlKGRvd25sb2FkUmVxdWVzdCk7CisKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkZXJJbXBsLmtleVRvTGlzdGVuYWJsZUZ1dHVyZSkuY29udGFpbnNLZXkoZGVzdGluYXRpb25GaWxlVXJpLnRvU3RyaW5nKCkpOworCisgICAgZG93bmxvYWRGdXR1cmUuY2FuY2VsKHRydWUpOworCisgICAgLy8gVGhlIGNvbXBsZXRlZCBkb3dubG9hZCBpcyByZW1vdmVkIGZyb20gdGhlIHVyaVRvTGlzdGVuYWJsZUZ1dHVyZSBNYXAuCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZGVySW1wbC5rZXlUb0xpc3RlbmFibGVGdXR1cmUpCisgICAgICAgIC5kb2VzTm90Q29udGFpbktleShkZXN0aW5hdGlvbkZpbGVVcmkudG9TdHJpbmcoKSk7CisKKyAgICAvLyBSZXNldCBzdGF0ZSBvZiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyIHRvIHByZXZlbnQgZGVhZGxvY2tzCisgICAgYmxvY2tpbmdGaWxlRG93bmxvYWRlci5yZXNldFN0YXRlKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yL0JVSUxEIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL21vbml0b3IvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDg0YjZiZQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yL0JVSUxECkBAIC0wLDAgKzEsNTQgQEAKKyMgQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworIworIyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyMgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorIyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyMKKyMgICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyMKKyMgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorIyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorIyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyMgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorIyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK2xvYWQoIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOnRlc3RfZGVmcy5iemwiLCAibWRkX2xvY2FsX3Rlc3QiKQorCitwYWNrYWdlKAorICAgIGRlZmF1bHRfdmlzaWJpbGl0eSA9IFsiLy86X19zdWJwYWNrYWdlc19fIl0sCisgICAgbGljZW5zZXMgPSBbIm5vdGljZSJdLAorKQorCittZGRfbG9jYWxfdGVzdCgKKyAgICBuYW1lID0gIk5ldHdvcmtVc2FnZU1vbml0b3JUZXN0IiwKKyAgICBzcmNzID0gWyJOZXR3b3JrVXNhZ2VNb25pdG9yVGVzdC5qYXZhIl0sCisgICAgdGVzdF9jbGFzcyA9ICJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLk5ldHdvcmtVc2FnZU1vbml0b3JUZXN0IiwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvY29tbW9uL3Rlc3RpbmciLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZpbGUvc3BpIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ2dpbmdTdGF0ZVN0b3JlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOk5vT3BMb2dnaW5nU3RhdGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL3Byb3RvOm1ldGFkYXRhX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpOZXR3b3JrVXNhZ2VNb25pdG9yIiwKKyAgICAgICAgIi8vamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3Rpbmc6RmFrZVRpbWVTb3VyY2UiLAorICAgICAgICAiQGFuZHJvaWRfc2RrX2xpbnV4IiwKKyAgICAgICAgIkByb2JvbGVjdHJpYyIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCisKK21kZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiRG93bmxvYWRQcm9ncmVzc01vbml0b3JUZXN0IiwKKyAgICBzcmNzID0gWyJEb3dubG9hZFByb2dyZXNzTW9uaXRvclRlc3QuamF2YSJdLAorICAgIHRlc3RfY2xhc3MgPSAiY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubW9uaXRvci5Eb3dubG9hZFByb2dyZXNzTW9uaXRvclRlc3QiLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RG93bmxvYWRMaXN0ZW5lciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9zcGkiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2xpdGU6RG93bmxvYWRMaXN0ZW5lciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvcjpEb3dubG9hZFByb2dyZXNzTW9uaXRvciIsCisgICAgICAgICIvL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nOkZha2VUaW1lU291cmNlIiwKKyAgICAgICAgIkBhbmRyb2lkX3Nka19saW51eCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgICAgICJAbW9ja2l0byIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvci9Eb3dubG9hZFByb2dyZXNzTW9uaXRvclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yL0Rvd25sb2FkUHJvZ3Jlc3NNb25pdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg3OTE5ODcKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvci9Eb3dubG9hZFByb2dyZXNzTW9uaXRvclRlc3QuamF2YQpAQCAtMCwwICsxLDQzMiBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQubW9uaXRvcjsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yLkRvd25sb2FkUHJvZ3Jlc3NNb25pdG9yLkxPR19GUkVRVUVOQ1k7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLkFyZ3VtZW50TWF0Y2hlcnMuYW55TG9uZzsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by5uZXZlcjsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by50aW1lczsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5Tm9JbnRlcmFjdGlvbnM7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRMaXN0ZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLnNwaS5Nb25pdG9yOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRlc3RpbmcuRmFrZVRpbWVTb3VyY2U7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lk1vcmVFeGVjdXRvcnM7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuRXhlY3V0b3I7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm1vY2tpdG8uTW9jazsKK2ltcG9ydCBvcmcubW9ja2l0by5qdW5pdC5Nb2NraXRvSlVuaXQ7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b1J1bGU7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGNsYXNzIERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yVGVzdCB7CisKKyAgLy8gVXNlIGRpcmVjdEV4ZWN1dG9yIHRvIGVuc3VyZSB0aGUgb3JkZXIgb2YgdGVzdCB2ZXJpZmljYXRpb24uCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIEV4ZWN1dG9yIENPTlRST0xfRVhFQ1VUT1IgPSBNb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yKCk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEdST1VQX05BTUVfMSA9ICJncm91cC1uYW1lLTEiOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBHUk9VUF9OQU1FXzIgPSAiZ3JvdXAtbmFtZS0yIjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9VUklfMSA9CisgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5nbXMvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8xIjsKKworICAvLyBOb3RlOiBXZSBjYW4ndCBtYWtlIHRob3NlIGFuZHJvaWQgdXJpcyBzdGF0aWMgdmFyaWFibGUgc2luY2UgdGhlIFVyaS5wYXJzZSB3aWxsIGZhaWwKKyAgLy8gd2l0aCBpbml0aWFsaXphdGlvbi4KKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdXJpMSA9IFVyaS5wYXJzZShGSUxFX1VSSV8xKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9VUklfMiA9CisgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5nbXMvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8yIjsKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdXJpMiA9IFVyaS5wYXJzZShGSUxFX1VSSV8yKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9VUklfMyA9CisgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5nbXMvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8zIjsKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdXJpMyA9IFVyaS5wYXJzZShGSUxFX1VSSV8zKTsKKworICBwcml2YXRlIERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yIGRvd25sb2FkTW9uaXRvcjsKKyAgcHJpdmF0ZSBmaW5hbCBGYWtlVGltZVNvdXJjZSBjbG9jayA9IG5ldyBGYWtlVGltZVNvdXJjZSgpOworCisgIEBNb2NrIHByaXZhdGUgRG93bmxvYWRMaXN0ZW5lciBtb2NrRG93bmxvYWRMaXN0ZW5lcjE7CisgIEBNb2NrIHByaXZhdGUgRG93bmxvYWRMaXN0ZW5lciBtb2NrRG93bmxvYWRMaXN0ZW5lcjI7CisKKyAgQE1vY2sKKyAgcHJpdmF0ZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlLkRvd25sb2FkTGlzdGVuZXIKKyAgICAgIG1vY2tMaXRlRG93bmxvYWRMaXN0ZW5lcjE7CisKKyAgQE1vY2sKKyAgcHJpdmF0ZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5saXRlLkRvd25sb2FkTGlzdGVuZXIKKyAgICAgIG1vY2tMaXRlRG93bmxvYWRMaXN0ZW5lcjI7CisKKyAgQFJ1bGUgcHVibGljIGZpbmFsIE1vY2tpdG9SdWxlIG1vY2tzID0gTW9ja2l0b0pVbml0LnJ1bGUoKTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZG93bmxvYWRNb25pdG9yID0gbmV3IERvd25sb2FkUHJvZ3Jlc3NNb25pdG9yKGNsb2NrLCBDT05UUk9MX0VYRUNVVE9SKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ5dGVzV3JpdHRlbl9jbGVhblNsYXRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZG93bmxvYWRNb25pdG9yLmFkZERvd25sb2FkTGlzdGVuZXIoR1JPVVBfTkFNRV8xLCBtb2NrRG93bmxvYWRMaXN0ZW5lcjEpOworICAgIGRvd25sb2FkTW9uaXRvci5hZGREb3dubG9hZExpc3RlbmVyKEdST1VQX05BTUVfMiwgbW9ja0Rvd25sb2FkTGlzdGVuZXIyKTsKKworICAgIC8vIFNldHVwIDIgRmlsZUdyb3VwczoKKyAgICAvLyBGaWxlR3JvdXAxOiBmaWxlMSBhbmQgZmlsZTIuCisgICAgLy8gRmlsZUdyb3VwMjogZmlsZTMuCisgICAgZG93bmxvYWRNb25pdG9yLm1vbml0b3JVcmkodXJpMSwgR1JPVVBfTkFNRV8xKTsKKyAgICBkb3dubG9hZE1vbml0b3IubW9uaXRvclVyaSh1cmkyLCBHUk9VUF9OQU1FXzEpOworICAgIGRvd25sb2FkTW9uaXRvci5tb25pdG9yVXJpKHVyaTMsIEdST1VQX05BTUVfMik7CisKKyAgICBNb25pdG9yLk91dHB1dE1vbml0b3Igb3V0cHV0TW9uaXRvcjEgPSBkb3dubG9hZE1vbml0b3IubW9uaXRvcldyaXRlKHVyaTEpOworICAgIE1vbml0b3IuT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yMiA9IGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMik7CisgICAgTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IzID0gZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkzKTsKKworICAgIC8vIG91dHB1dE1vbml0b3IxIGlzIHNhbWUgYXMgb3V0cHV0TW9uaXRvcjIgc2luY2UgdGhleSBib3RoIG1vbml0b3IgZm9yIEZpbGVHcm91cDEuCisgICAgYXNzZXJ0VGhhdChvdXRwdXRNb25pdG9yMSkuaXNTYW1lSW5zdGFuY2VBcyhvdXRwdXRNb25pdG9yMik7CisgICAgYXNzZXJ0VGhhdChvdXRwdXRNb25pdG9yMSkuaXNOb3RTYW1lSW5zdGFuY2VBcyhvdXRwdXRNb25pdG9yMyk7CisKKyAgICAvLyBUaGUgMXN0IGJ5dGVzV3JpdHRlbiB3YXMgYnVmZmVyZWQuCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAwLCAxKTsKKyAgICB2ZXJpZnlOb0ludGVyYWN0aW9ucyhtb2NrRG93bmxvYWRMaXN0ZW5lcjEpOworCisgICAgLy8gTm93IHRoZSBidWZmZXJlZCB0aW1lIHBhc3NlZC4KKyAgICBjbG9jay5hZHZhbmNlKExPR19GUkVRVUVOQ1kgKyAxMDBMLCBUaW1lVW5pdC5NSUxMSVNFQ09ORFMpOworCisgICAgLy8gVGhlIDJuZCBieXRlc1dyaXR0ZW4gbm93IHRyaWdnZXJlZCBvblByb2dyZXNzLgorICAgIG91dHB1dE1vbml0b3IxLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxXSwgMSwgMik7CisgICAgLy8gMSAoZmlyc3QgYnl0ZXNXcml0dGVuKSArIDIgKDJuZCBieXRlc1dyaXR0ZW4pCisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyMSkub25Qcm9ncmVzcygxICsgMik7CisKKyAgICAvLyBUaGUgM3JkIGJ5dGVzV3JpdHRlbiB3YXMgYnVmZmVyZWQKKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDMsIDQpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcjEsIHRpbWVzKDApKS5vblByb2dyZXNzKDEgKyAyICsgNCk7CisKKyAgICAvLyBOb3cgdGhlIGJ1ZmZlcmVkIHRpbWUgcGFzc2VkIGFnYWluLgorICAgIGNsb2NrLmFkdmFuY2UoTE9HX0ZSRVFVRU5DWSArIDEwMEwsIFRpbWVVbml0Lk1JTExJU0VDT05EUyk7CisKKyAgICAvLyBUaGUgNHRoIGJ5dGVzV3JpdHRlbiBub3cgdHJpZ2dlcmVkIG9uUHJvZ3Jlc3MuCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCA3LCA4KTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIxKS5vblByb2dyZXNzKDEgKyAyICsgNCArIDgpOworCisgICAgLy8gTm8gYnl0ZXMgd2VyZSBkb3dubG9hZGVkIGZvciBGaWxlR3JvdXAyLgorICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tEb3dubG9hZExpc3RlbmVyMik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBieXRlc1dyaXR0ZW5fZm9yU2luZ2xlRmlsZURvd25sb2FkX2NsZWFuU2xhdGUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcih1cmkxLCBtb2NrTGl0ZURvd25sb2FkTGlzdGVuZXIxKTsKKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcih1cmkyLCBtb2NrTGl0ZURvd25sb2FkTGlzdGVuZXIyKTsKKworICAgIE1vbml0b3IuT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yMSA9IGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSk7CisgICAgTW9uaXRvci5PdXRwdXRNb25pdG9yIGR1cGxpY2F0ZU91dHB1dE1vbml0b3IxID0gZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKTsKKyAgICBNb25pdG9yLk91dHB1dE1vbml0b3Igb3V0cHV0TW9uaXRvcjMgPSBkb3dubG9hZE1vbml0b3IubW9uaXRvcldyaXRlKHVyaTMpOworCisgICAgLy8gb3V0cHV0TW9uaXRvcjEgaXMgc2FtZSBhcyBkdXBsaWNhdGVPdXRwdXRNb25pdG9yMSBzaW5jZSB0aGV5IGJvdGggbW9uaXRvciBmb3IgdXJpMS4KKyAgICBhc3NlcnRUaGF0KG91dHB1dE1vbml0b3IxKS5pc1NhbWVJbnN0YW5jZUFzKGR1cGxpY2F0ZU91dHB1dE1vbml0b3IxKTsKKyAgICBhc3NlcnRUaGF0KG91dHB1dE1vbml0b3IxKS5pc05vdFNhbWVJbnN0YW5jZUFzKG91dHB1dE1vbml0b3IzKTsKKworICAgIC8vIFRoZSAxc3QgYnl0ZXNXcml0dGVuIHdhcyBidWZmZXJlZC4KKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDAsIDEpOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tMaXRlRG93bmxvYWRMaXN0ZW5lcjEpOworCisgICAgLy8gTm93IHRoZSBidWZmZXJlZCB0aW1lIHBhc3NlZC4KKyAgICBjbG9jay5hZHZhbmNlKExPR19GUkVRVUVOQ1kgKyAxMDBMLCBUaW1lVW5pdC5NSUxMSVNFQ09ORFMpOworCisgICAgLy8gVGhlIDJuZCBieXRlc1dyaXR0ZW4gbm93IHRyaWdnZXJlZCBvblByb2dyZXNzLgorICAgIG91dHB1dE1vbml0b3IxLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxXSwgMSwgMik7CisgICAgLy8gMSAoZmlyc3QgYnl0ZXNXcml0dGVuKSArIDIgKDJuZCBieXRlc1dyaXR0ZW4pCisgICAgdmVyaWZ5KG1vY2tMaXRlRG93bmxvYWRMaXN0ZW5lcjEpLm9uUHJvZ3Jlc3MoMSArIDIpOworCisgICAgLy8gVGhlIDNyZCBieXRlc1dyaXR0ZW4gd2FzIGJ1ZmZlcmVkCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAzLCA0KTsKKyAgICB2ZXJpZnkobW9ja0xpdGVEb3dubG9hZExpc3RlbmVyMSwgdGltZXMoMCkpLm9uUHJvZ3Jlc3MoMSArIDIgKyA0KTsKKworICAgIC8vIE5vdyB0aGUgYnVmZmVyZWQgdGltZSBwYXNzZWQgYWdhaW4uCisgICAgY2xvY2suYWR2YW5jZShMT0dfRlJFUVVFTkNZICsgMTAwTCwgVGltZVVuaXQuTUlMTElTRUNPTkRTKTsKKworICAgIC8vIFRoZSA0dGggYnl0ZXNXcml0dGVuIG5vdyB0cmlnZ2VyZWQgb25Qcm9ncmVzcy4KKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDcsIDgpOworICAgIHZlcmlmeShtb2NrTGl0ZURvd25sb2FkTGlzdGVuZXIxKS5vblByb2dyZXNzKDEgKyAyICsgNCArIDgpOworCisgICAgLy8gTm8gYnl0ZXMgd2VyZSBkb3dubG9hZGVkIGZvciB1cmkyCisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0xpdGVEb3dubG9hZExpc3RlbmVyMik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBieXRlc1dyaXR0ZW5fZm9yQm90aEZpbGVBbmRGaWxlR3JvdXBEb3dubG9hZHNfY2xlYW5TbGF0ZSgpIHRocm93cyBFeGNlcHRpb24geworICAgIGRvd25sb2FkTW9uaXRvci5hZGREb3dubG9hZExpc3RlbmVyKEdST1VQX05BTUVfMSwgbW9ja0Rvd25sb2FkTGlzdGVuZXIxKTsKKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcih1cmkyLCBtb2NrTGl0ZURvd25sb2FkTGlzdGVuZXIyKTsKKworICAgIC8vIFNldHVwIDEgRmlsZUdyb3VwCisgICAgLy8gRmlsZUdyb3VwMTogZmlsZTEKKyAgICAvLyBmaWxlMiBpcyBhIHNpbmdsZSBmaWxlIGRvd25sb2FkCisgICAgZG93bmxvYWRNb25pdG9yLm1vbml0b3JVcmkodXJpMSwgR1JPVVBfTkFNRV8xKTsKKworICAgIE1vbml0b3IuT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yMSA9IGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSk7CisgICAgTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IyID0gZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkyKTsKKworICAgIC8vIG91dHB1dE1vbml0b3IxIGlzIG5vdCB0aGUgc2FtZSBhcyBvdXRwdXRNb25pdG9yMgorICAgIGFzc2VydFRoYXQob3V0cHV0TW9uaXRvcjEpLmlzTm90U2FtZUluc3RhbmNlQXMob3V0cHV0TW9uaXRvcjIpOworCisgICAgLy8gVGhlIDFzdCBieXRlc1dyaXR0ZW4gd2FzIGJ1ZmZlcmVkLgorICAgIG91dHB1dE1vbml0b3IxLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxXSwgMCwgMSk7CisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0Rvd25sb2FkTGlzdGVuZXIxKTsKKworICAgIG91dHB1dE1vbml0b3IyLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxXSwgMCwgMSk7CisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0xpdGVEb3dubG9hZExpc3RlbmVyMik7CisKKyAgICAvLyBOb3cgdGhlIGJ1ZmZlcmVkIHRpbWUgcGFzc2VkLgorICAgIGNsb2NrLmFkdmFuY2UoTE9HX0ZSRVFVRU5DWSArIDEwMEwsIFRpbWVVbml0Lk1JTExJU0VDT05EUyk7CisKKyAgICAvLyBUaGUgMm5kIGJ5dGVzV3JpdHRlbiBub3cgdHJpZ2dlcmVkIG9uUHJvZ3Jlc3MuCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAxLCAyKTsKKyAgICAvLyAxIChmaXJzdCBieXRlc1dyaXR0ZW4pICsgMiAoMm5kIGJ5dGVzV3JpdHRlbikKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIxKS5vblByb2dyZXNzKDEgKyAyKTsKKworICAgIG91dHB1dE1vbml0b3IyLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxXSwgMSwgMik7CisgICAgdmVyaWZ5KG1vY2tMaXRlRG93bmxvYWRMaXN0ZW5lcjIpLm9uUHJvZ3Jlc3MoMSArIDIpOworCisgICAgLy8gVGhlIDNyZCBieXRlc1dyaXR0ZW4gd2FzIGJ1ZmZlcmVkCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAzLCA0KTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIxLCB0aW1lcygwKSkub25Qcm9ncmVzcygxICsgMiArIDQpOworCisgICAgb3V0cHV0TW9uaXRvcjIuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAzLCA0KTsKKyAgICB2ZXJpZnkobW9ja0xpdGVEb3dubG9hZExpc3RlbmVyMiwgdGltZXMoMCkpLm9uUHJvZ3Jlc3MoMSArIDIgKyA0KTsKKworICAgIC8vIE5vdyB0aGUgYnVmZmVyZWQgdGltZSBwYXNzZWQgYWdhaW4uCisgICAgY2xvY2suYWR2YW5jZShMT0dfRlJFUVVFTkNZICsgMTAwTCwgVGltZVVuaXQuTUlMTElTRUNPTkRTKTsKKworICAgIC8vIFRoZSA0dGggYnl0ZXNXcml0dGVuIG5vdyB0cmlnZ2VyZWQgb25Qcm9ncmVzcy4KKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDcsIDgpOworICAgIHZlcmlmeShtb2NrRG93bmxvYWRMaXN0ZW5lcjEpLm9uUHJvZ3Jlc3MoMSArIDIgKyA0ICsgOCk7CisKKyAgICBvdXRwdXRNb25pdG9yMi5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDcsIDgpOworICAgIHZlcmlmeShtb2NrTGl0ZURvd25sb2FkTGlzdGVuZXIyKS5vblByb2dyZXNzKDEgKyAyICsgNCArIDgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnl0ZXNXcml0dGVuX3BhcnRpYWxBbmREb3dubG9hZGVkRmlsZXMoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKworICAgIGRvd25sb2FkTW9uaXRvci5hZGREb3dubG9hZExpc3RlbmVyKEdST1VQX05BTUVfMSwgbW9ja0Rvd25sb2FkTGlzdGVuZXIxKTsKKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcihHUk9VUF9OQU1FXzIsIG1vY2tEb3dubG9hZExpc3RlbmVyMik7CisKKyAgICAvLyBTZXR1cCBhIEZpbGVHcm91cCB3aXRoIDMgZmlsZXMuIGZpbGUxIGlzIHBhcnRpYWxseSBkb3dubG9hZGVkICgxMDAwIGJ5dGVzKS4KKyAgICAvLyBmaWxlMiBpcyBlbXB0eS4gZmlsZTMgaXMgZG93bmxvYWRlZCAoMjAwMCBieXRlcykuCisgICAgZG93bmxvYWRNb25pdG9yLm1vbml0b3JVcmkodXJpMSwgR1JPVVBfTkFNRV8xKTsKKyAgICBkb3dubG9hZE1vbml0b3Iubm90aWZ5Q3VycmVudEZpbGVTaXplKEdST1VQX05BTUVfMSwgMTAwMCAvKiBjdXJyZW50U2l6ZSAqLyk7CisgICAgZG93bmxvYWRNb25pdG9yLm1vbml0b3JVcmkodXJpMiwgR1JPVVBfTkFNRV8xKTsKKyAgICBkb3dubG9hZE1vbml0b3Iubm90aWZ5Q3VycmVudEZpbGVTaXplKEdST1VQX05BTUVfMSwgMjAwMCAvKiBjdXJyZW50U2l6ZSAqLyk7CisKKyAgICBNb25pdG9yLk91dHB1dE1vbml0b3Igb3V0cHV0TW9uaXRvcjEgPSBkb3dubG9hZE1vbml0b3IubW9uaXRvcldyaXRlKHVyaTEpOworICAgIE1vbml0b3IuT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yMiA9IGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMik7CisKKyAgICAvLyBib3RoIG1vbml0b3JzIGFyZSB0aGUgc2FtZSBzaW5jZSAzIGZpbGVzIGFyZSBmcm9tIHNhbWUgZmlsZSBncm91cC4KKyAgICBhc3NlcnRUaGF0KG91dHB1dE1vbml0b3IxKS5pc1NhbWVJbnN0YW5jZUFzKG91dHB1dE1vbml0b3IyKTsKKworICAgIC8vIFRoZSAxc3QgYnl0ZXNXcml0dGVuIHdhcyBidWZmZXJlZC4KKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDAsIDEpOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tEb3dubG9hZExpc3RlbmVyMSk7CisKKyAgICAvLyBOb3cgdGhlIGJ1ZmZlcmVkIHRpbWUgcGFzc2VkLgorICAgIGNsb2NrLmFkdmFuY2UoTE9HX0ZSRVFVRU5DWSArIDEwMEwsIFRpbWVVbml0Lk1JTExJU0VDT05EUyk7CisKKyAgICAvLyBUaGUgMm5kIGJ5dGVzV3JpdHRlbiBub3cgdHJpZ2dlcmVkIG9uUHJvZ3Jlc3MuCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAxLCAyKTsKKyAgICAvLyAyMDAwIChkb3dubG9hZGVkIGZpbGUpICsgMTAwMCAocGFydGlhbGx5IGRvd25sb2FkZWQpICsgMSAoZmlyc3QgYnl0ZXNXcml0dGVuKSArIDIgKDJuZAorICAgIC8vIGJ5dGVzV3JpdHRlbikKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIxKS5vblByb2dyZXNzKDIwMDAgKyAxMDAwICsgMSArIDIpOworCisgICAgLy8gVGhlIDNyZCBieXRlc1dyaXR0ZW4gd2FzIGJ1ZmZlcmVkCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAzLCA0KTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIxLCB0aW1lcygwKSkub25Qcm9ncmVzcygyMDAwICsgMTAwMCArIDEgKyAyICsgNCk7CisKKyAgICAvLyBOb3cgdGhlIGJ1ZmZlcmVkIHRpbWUgcGFzc2VkIGFnYWluLgorICAgIGNsb2NrLmFkdmFuY2UoTE9HX0ZSRVFVRU5DWSArIDEwMEwsIFRpbWVVbml0Lk1JTExJU0VDT05EUyk7CisKKyAgICAvLyBUaGUgNHRoIGJ5dGVzV3JpdHRlbiBub3cgdHJpZ2dlcmVkIG9uUHJvZ3Jlc3MuCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCA3LCA4KTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIxKS5vblByb2dyZXNzKDIwMDAgKyAxMDAwICsgMSArIDIgKyA0ICsgOCk7CisKKyAgICAvLyBObyBieXRlcyB3ZXJlIGRvd25sb2FkZWQgZm9yIEZpbGVHcm91cDIuCisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0Rvd25sb2FkTGlzdGVuZXIyKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ5dGVzV3JpdHRlbl9hZGREb3dubG9hZExpc3RlbmVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisKKyAgICAvLyBUaGVyZSBpcyBubyBkb3dubG9hZCBsaXN0ZW5lciBmb3IgR1JPVVBfTkFNRV8xLgorICAgIGRvd25sb2FkTW9uaXRvci5tb25pdG9yVXJpKHVyaTEsIEdST1VQX05BTUVfMSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZE1vbml0b3IubW9uaXRvcldyaXRlKHVyaTEpKS5pc051bGwoKTsKKworICAgIC8vIEFkZGluZyBhIGxpc3RlbmVyIG5vdy4KKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcihHUk9VUF9OQU1FXzEsIG1vY2tEb3dubG9hZExpc3RlbmVyMSk7CisgICAgZG93bmxvYWRNb25pdG9yLm1vbml0b3JVcmkodXJpMSwgR1JPVVBfTkFNRV8xKTsKKworICAgIC8vIFJlbW92aW5nIHRoZSBsaXN0ZW5lci4KKyAgICBkb3dubG9hZE1vbml0b3IucmVtb3ZlRG93bmxvYWRMaXN0ZW5lcihHUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKSkuaXNOdWxsKCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBieXRlc1dyaXR0ZW5fZm9yU2luZ2xlRmlsZURvd25sb2FkX2FkZEFuZFJlbW92ZURvd25sb2FkTGlzdGVuZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBUaGVyZSBpcyBubyBkb3dubG9hZCBsaXN0ZW5lciBmb3IgdXJpMS4KKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSkpLmlzTnVsbCgpOworCisgICAgLy8gQWRkaW5nIGEgbGlzdGVuZXIgbm93LgorICAgIGRvd25sb2FkTW9uaXRvci5hZGREb3dubG9hZExpc3RlbmVyKHVyaTEsIG1vY2tMaXRlRG93bmxvYWRMaXN0ZW5lcjEpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKSkuaXNOb3ROdWxsKCk7CisKKyAgICAvLyBSZW1vdmluZyB0aGUgbGlzdGVuZXIuCisgICAgZG93bmxvYWRNb25pdG9yLnJlbW92ZURvd25sb2FkTGlzdGVuZXIodXJpMSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZE1vbml0b3IubW9uaXRvcldyaXRlKHVyaTEpKS5pc051bGwoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGJ5dGVzV3JpdHRlbl9mb3JCb3RoRmlsZUFuZEZpbGVHcm91cERvd25sb2Fkc19hZGRBbmRSZW1vdmVEb3dubG9hZExpc3RlbmVyKCkKKyAgICAgIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFRoZXJlIGlzIG5vIGRvd25sb2FkIGxpc3RlbmVyIGZvciB1cmkxLgorICAgIGFzc2VydFRoYXQoZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKSkuaXNOdWxsKCk7CisKKyAgICAvLyBUaGVyZSBpcyBubyBkb3dubG9hZCBsaXN0ZW5lciBmb3IgR1JPVVBfTkFNRV8yCisgICAgZG93bmxvYWRNb25pdG9yLm1vbml0b3JVcmkodXJpMiwgR1JPVVBfTkFNRV8yKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMikpLmlzTnVsbCgpOworCisgICAgLy8gQWRkaW5nIGEgbGlzdGVuZXIgZm9yIHVyaTEKKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcih1cmkxLCBtb2NrTGl0ZURvd25sb2FkTGlzdGVuZXIxKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSkpLmlzTm90TnVsbCgpOworICAgIC8vIHVyaTIgKEZpbGUgR3JvdXAgMikgc2hvdWxkIHN0aWxsIGhhdmUgbm8gbW9uaXRvci4KKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMikpLmlzTnVsbCgpOworCisgICAgLy8gQWRkaW5nIGEgbGlzdGVuZXIgZm9yIHVyaTIgKEZpbGUgR3JvdXAgMikKKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcihHUk9VUF9OQU1FXzIsIG1vY2tEb3dubG9hZExpc3RlbmVyMik7CisgICAgZG93bmxvYWRNb25pdG9yLm1vbml0b3JVcmkodXJpMiwgR1JPVVBfTkFNRV8yKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMikpLmlzTm90TnVsbCgpOworICAgIC8vIHVyaTEgc3RpbGwgaGFzIG1vbml0b3IKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSkpLmlzTm90TnVsbCgpOworCisgICAgLy8gUmVtb3ZpbmcgdGhlIGxpc3RlbmVyIGZvciB1cmkxCisgICAgZG93bmxvYWRNb25pdG9yLnJlbW92ZURvd25sb2FkTGlzdGVuZXIodXJpMSk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZE1vbml0b3IubW9uaXRvcldyaXRlKHVyaTEpKS5pc051bGwoKTsKKyAgICAvLyB1cmkyIChGaWxlIEdyb3VwIDIpIHNob3VsZCBzdGlsbCBoYXZlIG1vbml0b3IuCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZE1vbml0b3IubW9uaXRvcldyaXRlKHVyaTIpKS5pc05vdE51bGwoKTsKKworICAgIC8vIFJlbW92aW5nIGxpc3RlbmVyIGZvciB1cmkyIChGaWxlIEdyb3VwIDIpCisgICAgZG93bmxvYWRNb25pdG9yLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoR1JPVVBfTkFNRV8yKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMikpLmlzTnVsbCgpOworICAgIC8vIHVyaTEgc3RpbGwgaGFzIG5vIG1vbml0b3IKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSkpLmlzTnVsbCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgYnl0ZXNXcml0dGVuX2Rvd25sb2FkTGlzdGVuZXJSZW1vdmVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVGhlcmUgaXMgbm8gZG93bmxvYWQgbGlzdGVuZXIgZm9yIEdST1VQX05BTUVfMS4KKyAgICBkb3dubG9hZE1vbml0b3IubW9uaXRvclVyaSh1cmkxLCBHUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKSkuaXNOdWxsKCk7CisKKyAgICAvLyBBZGRpbmcgYSBsaXN0ZW5lciBub3cuCisgICAgZG93bmxvYWRNb25pdG9yLmFkZERvd25sb2FkTGlzdGVuZXIoR1JPVVBfTkFNRV8xLCBtb2NrRG93bmxvYWRMaXN0ZW5lcjEpOworICAgIGRvd25sb2FkTW9uaXRvci5tb25pdG9yVXJpKHVyaTEsIEdST1VQX05BTUVfMSk7CisKKyAgICBNb25pdG9yLk91dHB1dE1vbml0b3Igb3V0cHV0TW9uaXRvciA9IGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSk7CisKKyAgICAvLyBSZW1vdmluZyB0aGUgbGlzdGVuZXIuCisgICAgZG93bmxvYWRNb25pdG9yLnJlbW92ZURvd25sb2FkTGlzdGVuZXIoR1JPVVBfTkFNRV8xKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSkpLmlzTnVsbCgpOworCisgICAgb3V0cHV0TW9uaXRvci5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDMsIDQpOworCisgICAgLy8gTWFrZSBzdXJlIHRoYXQgb25Qcm9ncmVzcyBpcyBub3QgdHJpZ2dlcmVkIGlmIHRoZSBEb3dubG9hZExpc3RlbmVyIGlzIG5vIGxvbmdlciBiZWluZyB1c2VkLgorICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tEb3dubG9hZExpc3RlbmVyMSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBieXRlc1dyaXR0ZW5fZm9yU2luZ2xlRmlsZURvd25sb2FkX2Rvd25sb2FkTGlzdGVuZXJSZW1vdmVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZG93bmxvYWRNb25pdG9yLmFkZERvd25sb2FkTGlzdGVuZXIodXJpMSwgbW9ja0xpdGVEb3dubG9hZExpc3RlbmVyMSk7CisKKyAgICAvLyBNb25pdG9yIHNob3VsZCBleGlzdAorICAgIE1vbml0b3IuT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yID0gZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKTsKKyAgICBhc3NlcnRUaGF0KG91dHB1dE1vbml0b3IpLmlzTm90TnVsbCgpOworCisgICAgLy8gUmVtb3ZpbmcgdGhlIGxpc3RlbmVyCisgICAgZG93bmxvYWRNb25pdG9yLnJlbW92ZURvd25sb2FkTGlzdGVuZXIodXJpMSk7CisKKyAgICAvLyBNb25pdG9yIHNob3VsZCBub3QgZXhpc3QgYW55bW9yZQorICAgIGFzc2VydFRoYXQoZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKSkuaXNOdWxsKCk7CisKKyAgICBvdXRwdXRNb25pdG9yLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxXSwgMywgNCk7CisKKyAgICAvLyBNYWtlIHN1cmUgb25Qcm9ncmVzcyBpcyBub3QgdHJpZ2dlcmVkIGlmIERvd25sb2FkTGlzdGVuZXIgaXMgbm90IGxvbmdlciB1c2VkLgorICAgIHZlcmlmeShtb2NrTGl0ZURvd25sb2FkTGlzdGVuZXIxLCBuZXZlcigpKS5vblByb2dyZXNzKGFueUxvbmcoKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBieXRlc1dyaXR0ZW5fZm9yQm90aEZpbGVBbmRGaWxlR3JvdXBEb3dubG9hZHNfZG93bmxvYWRMaXN0ZW5lclJlbW92ZWQoKQorICAgICAgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gVGhlcmUgaXMgbm8gZG93bmxvYWQgbGlzdGVuZXIgZm9yIEdST1VQX05BTUVfMSBhbmQgbm8gbGlzdGVuZXIgZm9yIHVyaTIKKyAgICBkb3dubG9hZE1vbml0b3IubW9uaXRvclVyaSh1cmkxLCBHUk9VUF9OQU1FXzEpOworICAgIGFzc2VydFRoYXQoZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKSkuaXNOdWxsKCk7CisgICAgYXNzZXJ0VGhhdChkb3dubG9hZE1vbml0b3IubW9uaXRvcldyaXRlKHVyaTIpKS5pc051bGwoKTsKKworICAgIC8vIEFkZGluZyBhIGxpc3RlbmVyIGZvciBHUk9VUF9OQU1FXzEgYW5kIHNpbmdsZSBmaWxlIHVyaTIKKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcih1cmkyLCBtb2NrTGl0ZURvd25sb2FkTGlzdGVuZXIyKTsKKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcihHUk9VUF9OQU1FXzEsIG1vY2tEb3dubG9hZExpc3RlbmVyMSk7CisgICAgZG93bmxvYWRNb25pdG9yLm1vbml0b3JVcmkodXJpMSwgR1JPVVBfTkFNRV8xKTsKKworICAgIE1vbml0b3IuT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yMSA9IGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSk7CisgICAgTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IyID0gZG93bmxvYWRNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkyKTsKKworICAgIC8vIFJlbW92aW5nIHRoZSBsaXN0ZW5lci4KKyAgICBkb3dubG9hZE1vbml0b3IucmVtb3ZlRG93bmxvYWRMaXN0ZW5lcihHUk9VUF9OQU1FXzEpOworICAgIGRvd25sb2FkTW9uaXRvci5yZW1vdmVEb3dubG9hZExpc3RlbmVyKHVyaTIpOworCisgICAgYXNzZXJ0VGhhdChkb3dubG9hZE1vbml0b3IubW9uaXRvcldyaXRlKHVyaTEpKS5pc051bGwoKTsKKyAgICBhc3NlcnRUaGF0KGRvd25sb2FkTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMikpLmlzTnVsbCgpOworCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAzLCA0KTsKKyAgICBvdXRwdXRNb25pdG9yMi5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDMsIDQpOworCisgICAgLy8gTWFrZSBzdXJlIHRoYXQgb25Qcm9ncmVzcyBpcyBub3QgdHJpZ2dlcmVkIGlmIHRoZSBEb3dubG9hZExpc3RlbmVyIGlzIG5vIGxvbmdlciBiZWluZyB1c2VkLgorICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKG1vY2tEb3dubG9hZExpc3RlbmVyMSk7CisgICAgdmVyaWZ5Tm9JbnRlcmFjdGlvbnMobW9ja0xpdGVEb3dubG9hZExpc3RlbmVyMik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBkb3dubG9hZGVyTGlmZWN5Y2xlQ2FsbGJhY2soKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICBkb3dubG9hZE1vbml0b3IuYWRkRG93bmxvYWRMaXN0ZW5lcihHUk9VUF9OQU1FXzEsIG1vY2tEb3dubG9hZExpc3RlbmVyMSk7CisgICAgZG93bmxvYWRNb25pdG9yLmFkZERvd25sb2FkTGlzdGVuZXIoR1JPVVBfTkFNRV8yLCBtb2NrRG93bmxvYWRMaXN0ZW5lcjIpOworICAgIGRvd25sb2FkTW9uaXRvci5wYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIxKS5wYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKyAgICB2ZXJpZnkobW9ja0Rvd25sb2FkTGlzdGVuZXIyKS5wYXVzZWRGb3JDb25uZWN0aXZpdHkoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGRvd25sb2FkZXJMaWZlY3ljbGVDYWxsYmFja19mb3JGaWxlQW5kRmlsZUdyb3VwRG93bmxvYWRzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgZG93bmxvYWRNb25pdG9yLmFkZERvd25sb2FkTGlzdGVuZXIodXJpMSwgbW9ja0xpdGVEb3dubG9hZExpc3RlbmVyMSk7CisgICAgZG93bmxvYWRNb25pdG9yLmFkZERvd25sb2FkTGlzdGVuZXIoR1JPVVBfTkFNRV8yLCBtb2NrRG93bmxvYWRMaXN0ZW5lcjIpOworCisgICAgZG93bmxvYWRNb25pdG9yLnBhdXNlZEZvckNvbm5lY3Rpdml0eSgpOworCisgICAgdmVyaWZ5KG1vY2tMaXRlRG93bmxvYWRMaXN0ZW5lcjEpLm9uUGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7CisgICAgdmVyaWZ5KG1vY2tEb3dubG9hZExpc3RlbmVyMikucGF1c2VkRm9yQ29ubmVjdGl2aXR5KCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9tb25pdG9yL05ldHdvcmtVc2FnZU1vbml0b3JUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvci9OZXR3b3JrVXNhZ2VNb25pdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg2YWFkYjQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvbW9uaXRvci9OZXR3b3JrVXNhZ2VNb25pdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsMzg2IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5tb25pdG9yOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzLmRpcmVjdEV4ZWN1dG9yOworaW1wb3J0IHN0YXRpYyBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdC5NSUxMSVNFQ09ORFM7CitpbXBvcnQgc3RhdGljIGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0LlNFQ09ORFM7CisKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm5ldC5Db25uZWN0aXZpdHlNYW5hZ2VyOworaW1wb3J0IGFuZHJvaWQubmV0Lk5ldHdvcmtJbmZvLkRldGFpbGVkU3RhdGU7CitpbXBvcnQgYW5kcm9pZC5uZXQuVXJpOworaW1wb3J0IGFuZHJvaWQub3MuQnVpbGQ7CitpbXBvcnQgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuY29tbW9uLnRlc3RpbmcuVGVtcG9yYXJ5VXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZpbGUuc3BpLk1vbml0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwubG9nZ2luZy5Mb2dnaW5nU3RhdGVTdG9yZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5sb2dnaW5nLk5vT3BMb2dnaW5nU3RhdGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZy5GYWtlVGltZVNvdXJjZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5pbnRlcm5hbC5NZXRhZGF0YVByb3RvLkdyb3VwS2V5OworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkV4ZWN1dG9yOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlNoYWRvd3M7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLnNoYWRvd3MuU2hhZG93TmV0d29ya0luZm87CisKK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBOZXR3b3JrVXNhZ2VNb25pdG9yVGVzdCB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRXhlY3V0b3IgZXhlY3V0b3IgPSBkaXJlY3RFeGVjdXRvcigpOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgR1JPVVBfTkFNRV8xID0gImdyb3VwLW5hbWUtMSI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBPV05FUl9QQUNLQUdFXzEgPSAib3duZXItcGFja2FnZS0xIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFZBUklBTlRfSURfMSA9ICJ2YXJpYW50LWlkLTEiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVkVSU0lPTl9OVU1CRVJfMSA9IDE7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBCVUlMRF9JRF8xID0gMTIzOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBHUk9VUF9OQU1FXzIgPSAiZ3JvdXAtbmFtZS0yIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE9XTkVSX1BBQ0tBR0VfMiA9ICJvd25lci1wYWNrYWdlLTIiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkFSSUFOVF9JRF8yID0gInZhcmlhbnQtaWQtMiI7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFZFUlNJT05fTlVNQkVSXzIgPSAyOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgQlVJTERfSURfMiA9IDQ1NjsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9VUklfMSA9CisgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5nbXMvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8xIjsKKworICAvLyBOb3RlOiBXZSBjYW4ndCBtYWtlIHRob3NlIGFuZHJvaWQgdXJpcyBzdGF0aWMgdmFyaWFibGUgc2luY2UgdGhlIFVyaS5wYXJzZSB3aWxsIGZhaWwKKyAgLy8gd2l0aCBpbml0aWFsaXphdGlvbi4KKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdXJpMSA9IFVyaS5wYXJzZShGSUxFX1VSSV8xKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9VUklfMiA9CisgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5nbXMvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8yIjsKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdXJpMiA9IFVyaS5wYXJzZShGSUxFX1VSSV8yKTsKKworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRklMRV9VUklfMyA9CisgICAgICAiYW5kcm9pZDovL2NvbS5nb29nbGUuYW5kcm9pZC5nbXMvZmlsZXMvZGF0YWRvd25sb2FkL3NoYXJlZC9wdWJsaWMvZmlsZV8zIjsKKyAgcHJpdmF0ZSBmaW5hbCBVcmkgdXJpMyA9IFVyaS5wYXJzZShGSUxFX1VSSV8zKTsKKworICBwcml2YXRlIE5ldHdvcmtVc2FnZU1vbml0b3IgbmV0d29ya1VzYWdlTW9uaXRvcjsKKyAgcHJpdmF0ZSBMb2dnaW5nU3RhdGVTdG9yZSBsb2dnaW5nU3RhdGVTdG9yZTsKKyAgcHJpdmF0ZSBDb250ZXh0IGNvbnRleHQ7CisgIHByaXZhdGUgZmluYWwgRmFrZVRpbWVTb3VyY2UgY2xvY2sgPSBuZXcgRmFrZVRpbWVTb3VyY2UoKTsKKworICBDb25uZWN0aXZpdHlNYW5hZ2VyIGNvbm5lY3Rpdml0eU1hbmFnZXI7CisKKyAgQFJ1bGUgcHVibGljIGZpbmFsIFRlbXBvcmFyeVVyaSB0bXBVcmkgPSBuZXcgVGVtcG9yYXJ5VXJpKCk7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHRocm93cyBFeGNlcHRpb24geworICAgIGNvbnRleHQgPSBBcHBsaWNhdGlvblByb3ZpZGVyLmdldEFwcGxpY2F0aW9uQ29udGV4dCgpOworCisgICAgbG9nZ2luZ1N0YXRlU3RvcmUgPSBuZXcgTm9PcExvZ2dpbmdTdGF0ZSgpOworCisgICAgLy8gVE9ETyhiLzE3NzAxNTMwMyk6IHVzZSBidWlsZGVyIHdoZW4gYXZhaWxhYmxlCisgICAgbmV0d29ya1VzYWdlTW9uaXRvciA9IG5ldyBOZXR3b3JrVXNhZ2VNb25pdG9yKGNvbnRleHQsIGNsb2NrKTsKKworICAgIHRoaXMuY29ubmVjdGl2aXR5TWFuYWdlciA9CisgICAgICAgIChDb25uZWN0aXZpdHlNYW5hZ2VyKSBjb250ZXh0LmdldFN5c3RlbVNlcnZpY2UoQ29udGV4dC5DT05ORUNUSVZJVFlfU0VSVklDRSk7CisgIH0KKworICBwcml2YXRlIHZvaWQgc2V0TmV0d29ya0Nvbm5lY3Rpdml0eVR5cGUoaW50IG5ldHdvcmtDb25uZWN0aXZpdHlUeXBlKSB7CisgICAgU2hhZG93cy5zaGFkb3dPZihjb25uZWN0aXZpdHlNYW5hZ2VyKQorICAgICAgICAuc2V0QWN0aXZlTmV0d29ya0luZm8oCisgICAgICAgICAgICBTaGFkb3dOZXR3b3JrSW5mby5uZXdJbnN0YW5jZSgKKyAgICAgICAgICAgICAgICBEZXRhaWxlZFN0YXRlLkNPTk5FQ1RFRCwKKyAgICAgICAgICAgICAgICBuZXR3b3JrQ29ubmVjdGl2aXR5VHlwZSwKKyAgICAgICAgICAgICAgICAwIC8qIHN1YnR5cGUgKi8sCisgICAgICAgICAgICAgICAgdHJ1ZSAvKiBpc0F2YWlsYWJsZSAqLywKKyAgICAgICAgICAgICAgICB0cnVlIC8qIGlzQ29ubmVjdGVkICovKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZXNXcml0dGVuKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gU2V0dXAgMiBGaWxlR3JvdXBzOgorICAgIC8vIEZpbGVHcm91cDE6IGZpbGUxIGFuZCBmaWxlMi4KKyAgICAvLyBGaWxlR3JvdXAyOiBmaWxlMy4KKworICAgIEdyb3VwS2V5IGdyb3VwS2V5MSA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShPV05FUl9QQUNLQUdFXzEpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEdST1VQX05BTUVfMSkKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoVkFSSUFOVF9JRF8xKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgbmV0d29ya1VzYWdlTW9uaXRvci5tb25pdG9yVXJpKAorICAgICAgICB1cmkxLCBncm91cEtleTEsIEJVSUxEX0lEXzEsIFZFUlNJT05fTlVNQkVSXzEsIGxvZ2dpbmdTdGF0ZVN0b3JlKTsKKyAgICBuZXR3b3JrVXNhZ2VNb25pdG9yLm1vbml0b3JVcmkoCisgICAgICAgIHVyaTIsIGdyb3VwS2V5MSwgQlVJTERfSURfMSwgVkVSU0lPTl9OVU1CRVJfMSwgbG9nZ2luZ1N0YXRlU3RvcmUpOworCisgICAgR3JvdXBLZXkgZ3JvdXBLZXkyID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKE9XTkVSX1BBQ0tBR0VfMikKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoR1JPVVBfTkFNRV8yKQorICAgICAgICAgICAgLnNldFZhcmlhbnRJZChWQVJJQU5UX0lEXzIpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIG5ldHdvcmtVc2FnZU1vbml0b3IubW9uaXRvclVyaSgKKyAgICAgICAgdXJpMywgZ3JvdXBLZXkyLCBCVUlMRF9JRF8yLCBWRVJTSU9OX05VTUJFUl8yLCBsb2dnaW5nU3RhdGVTdG9yZSk7CisKKyAgICBNb25pdG9yLk91dHB1dE1vbml0b3Igb3V0cHV0TW9uaXRvcjEgPSBuZXR3b3JrVXNhZ2VNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKTsKKyAgICBNb25pdG9yLk91dHB1dE1vbml0b3Igb3V0cHV0TW9uaXRvcjIgPSBuZXR3b3JrVXNhZ2VNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkyKTsKKyAgICBNb25pdG9yLk91dHB1dE1vbml0b3Igb3V0cHV0TW9uaXRvcjMgPSBuZXR3b3JrVXNhZ2VNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkzKTsKKworICAgIC8vIG91dHB1dE1vbml0b3IxIGlzIHNhbWUgYXMgb3V0cHV0TW9uaXRvcjIgc2luY2UgdGhleSBib3RoIG1vbml0b3IgZm9yIEZpbGVHcm91cDEuCisgICAgYXNzZXJ0VGhhdChvdXRwdXRNb25pdG9yMSkuaXNTYW1lSW5zdGFuY2VBcyhvdXRwdXRNb25pdG9yMik7CisgICAgYXNzZXJ0VGhhdChvdXRwdXRNb25pdG9yMSkuaXNOb3RTYW1lSW5zdGFuY2VBcyhvdXRwdXRNb25pdG9yMyk7CisKKyAgICAvLyBGaXJzdCB3ZSBoYXZlIFdJRkkgY29ubmVjdGlvbi4KKyAgICAvLyBEb3dubG9hZGVkIDEgYnl0ZXMgb24gV0lGSSBmb3IgdXJpMQorICAgIHNldE5ldHdvcmtDb25uZWN0aXZpdHlUeXBlKENvbm5lY3Rpdml0eU1hbmFnZXIuVFlQRV9XSUZJKTsKKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDAsIDEpOworCisgICAgLy8gRG93bmxvYWRlZCAyIGJ5dGVzIG9uIFdJRkkgZm9yIHVyaTEKKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMl0sIDAsIDIpOworCisgICAgLy8gRG93bmxvYWRlZCA0IGJ5dGVzIG9uIFdJRkkgZm9yIHVyaTIKKyAgICBvdXRwdXRNb25pdG9yMi5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbNF0sIDAsIDQpOworCisgICAgLy8gRG93bmxvYWRlZCA4IGJ5dGVzIG9uIFdJRkkgZm9yIHVyaTMKKyAgICBvdXRwdXRNb25pdG9yMy5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbOF0sIDAsIDgpOworCisgICAgLy8gVGhlbiB3ZSBoYXZlIENFTExVTEFSIGNvbm5lY3Rpb24uCisgICAgLy8gRG93bmxvYWRlZCAxNiBieXRlcyBvbiBDRUxMVUxBUiBmb3IgdXJpMQorICAgIHNldE5ldHdvcmtDb25uZWN0aXZpdHlUeXBlKENvbm5lY3Rpdml0eU1hbmFnZXIuVFlQRV9NT0JJTEUpOworICAgIG91dHB1dE1vbml0b3IxLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVsxNl0sIDAsIDE2KTsKKworICAgIC8vIERvd25sb2FkZWQgMzIgYnl0ZXMgb24gQ0VMTFVMQVIgZm9yIHVyaTIKKyAgICBvdXRwdXRNb25pdG9yMi5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMzJdLCAwLCAzMik7CisKKyAgICAvLyBEb3dubG9hZGVkIDY0IGJ5dGVzIG9uIENFTExVTEFSIGZvciB1cmkzCisgICAgb3V0cHV0TW9uaXRvcjMuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzY0XSwgMCwgNjQpOworCisgICAgLy8gY2xvc2UoKSB3aWxsIHRyaWdnZXIgc2F2aW5nIGNvdW50ZXJzIHRvIExvZ2dpbmdTdGF0ZVN0b3JlLgorICAgIG91dHB1dE1vbml0b3IxLmNsb3NlKCk7CisgICAgb3V0cHV0TW9uaXRvcjIuY2xvc2UoKTsKKyAgICBvdXRwdXRNb25pdG9yMy5jbG9zZSgpOworCisgICAgLy8gYXdhaXQgZXhlY3V0b3JzIGlkbGUgaGVyZSBpZiB3ZSBzd2l0Y2ggZnJvbSBkaXJlY3RFeGVjdXRvci4uLgorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEJ5dGVzV3JpdHRlbl9tdWx0aXBsZVZlcnNpb25zKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisgICAgLy8gU2V0dXAgMiB2ZXJzaW9ucyBvZiBhIEZpbGVHcm91cDoKKyAgICAvLyBGaWxlR3JvdXAgdjE6IGZpbGUxIGFuZCBmaWxlMi4KKyAgICAvLyBGaWxlR3JvdXAgdjI6IGZpbGUyIGFuZCBmaWxlMy4KKyAgICBHcm91cEtleSBncm91cEtleTEgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoT1dORVJfUEFDS0FHRV8xKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShHUk9VUF9OQU1FXzEpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKFZBUklBTlRfSURfMSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIG5ldHdvcmtVc2FnZU1vbml0b3IubW9uaXRvclVyaSgKKyAgICAgICAgdXJpMSwgZ3JvdXBLZXkxLCBCVUlMRF9JRF8xLCBWRVJTSU9OX05VTUJFUl8xLCBsb2dnaW5nU3RhdGVTdG9yZSk7CisgICAgbmV0d29ya1VzYWdlTW9uaXRvci5tb25pdG9yVXJpKAorICAgICAgICB1cmkyLCBncm91cEtleTEsIEJVSUxEX0lEXzEsIFZFUlNJT05fTlVNQkVSXzEsIGxvZ2dpbmdTdGF0ZVN0b3JlKTsKKworICAgIEdyb3VwS2V5IGdyb3VwS2V5MiA9CisgICAgICAgIEdyb3VwS2V5Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZShPV05FUl9QQUNLQUdFXzIpCisgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKEdST1VQX05BTUVfMikKKyAgICAgICAgICAgIC5zZXRWYXJpYW50SWQoVkFSSUFOVF9JRF8yKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisKKyAgICAvLyBUaGlzIHdvdWxkIHVwZGF0ZSB1cmkyIHRvIGJlbG9uZyB0byBGaWxlR3JvdXAgdjIuCisgICAgbmV0d29ya1VzYWdlTW9uaXRvci5tb25pdG9yVXJpKAorICAgICAgICB1cmkyLCBncm91cEtleTIsIEJVSUxEX0lEXzIsIFZFUlNJT05fTlVNQkVSXzIsIGxvZ2dpbmdTdGF0ZVN0b3JlKTsKKyAgICBuZXR3b3JrVXNhZ2VNb25pdG9yLm1vbml0b3JVcmkoCisgICAgICAgIHVyaTMsIGdyb3VwS2V5MiwgQlVJTERfSURfMiwgVkVSU0lPTl9OVU1CRVJfMiwgbG9nZ2luZ1N0YXRlU3RvcmUpOworCisgICAgTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IxID0gbmV0d29ya1VzYWdlTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSk7CisgICAgTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IyID0gbmV0d29ya1VzYWdlTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMik7CisgICAgTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IzID0gbmV0d29ya1VzYWdlTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMyk7CisKKyAgICAvLyBvdXRwdXRNb25pdG9yMiBpcyBzYW1lIGFzIG91dHB1dE1vbml0b3IzIHNpbmNlIHRoZXkgYm90aCBtb25pdG9yIGZvciB0aGUgc2FtZSB2ZXJzaW9uIG9mIHRoZQorICAgIC8vIHNhbWUgRmlsZUdyb3VwLgorICAgIGFzc2VydFRoYXQob3V0cHV0TW9uaXRvcjEpLmlzTm90U2FtZUluc3RhbmNlQXMob3V0cHV0TW9uaXRvcjIpOworICAgIGFzc2VydFRoYXQob3V0cHV0TW9uaXRvcjIpLmlzU2FtZUluc3RhbmNlQXMob3V0cHV0TW9uaXRvcjMpOworCisgICAgLy8gRmlyc3Qgd2UgaGF2ZSBXSUZJIGNvbm5lY3Rpb24uCisgICAgLy8gRG93bmxvYWRlZCAxIGJ5dGVzIG9uIFdJRkkgZm9yIHVyaTEKKyAgICBzZXROZXR3b3JrQ29ubmVjdGl2aXR5VHlwZShDb25uZWN0aXZpdHlNYW5hZ2VyLlRZUEVfV0lGSSk7CisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAwLCAxKTsKKworICAgIC8vIERvd25sb2FkZWQgMiBieXRlcyBvbiBXSUZJIGZvciB1cmkxCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzJdLCAwLCAyKTsKKworICAgIC8vIERvd25sb2FkZWQgNCBieXRlcyBvbiBXSUZJIGZvciB1cmkyCisgICAgb3V0cHV0TW9uaXRvcjIuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzRdLCAwLCA0KTsKKworICAgIC8vIERvd25sb2FkZWQgOCBieXRlcyBvbiBXSUZJIGZvciB1cmkzCisgICAgb3V0cHV0TW9uaXRvcjMuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzhdLCAwLCA4KTsKKworICAgIC8vIFRoZW4gd2UgaGF2ZSBDRUxMVUxBUiBjb25uZWN0aW9uLgorICAgIC8vIERvd25sb2FkZWQgMTYgYnl0ZXMgb24gQ0VMTFVMQVIgZm9yIHVyaTEKKyAgICBzZXROZXR3b3JrQ29ubmVjdGl2aXR5VHlwZShDb25uZWN0aXZpdHlNYW5hZ2VyLlRZUEVfTU9CSUxFKTsKKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMTZdLCAwLCAxNik7CisKKyAgICAvLyBEb3dubG9hZGVkIDMyIGJ5dGVzIG9uIENFTExVTEFSIGZvciB1cmkyCisgICAgb3V0cHV0TW9uaXRvcjIuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzMyXSwgMCwgMzIpOworCisgICAgLy8gRG93bmxvYWRlZCA2NCBieXRlcyBvbiBDRUxMVUxBUiBmb3IgdXJpMworICAgIG91dHB1dE1vbml0b3IzLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVs2NF0sIDAsIDY0KTsKKworICAgIC8vIGNsb3NlKCkgd2lsbCB0cmlnZ2VyIHNhdmluZyBjb3VudGVycyB0byBTaGFyZWRQcmVmZXJlbmNlLgorICAgIG91dHB1dE1vbml0b3IxLmNsb3NlKCk7CisgICAgb3V0cHV0TW9uaXRvcjIuY2xvc2UoKTsKKyAgICBvdXRwdXRNb25pdG9yMy5jbG9zZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdEJ5dGVzV3JpdHRlbl9mbHVzaF9pbnRlcnZhbCgpIHRocm93cyBFeGNlcHRpb24geworICAgIC8vIFNldHVwIDEgRmlsZUdyb3VwczoKKyAgICAvLyBGaWxlR3JvdXAxOiBmaWxlMQorCisgICAgR3JvdXBLZXkgZ3JvdXBLZXkxID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKE9XTkVSX1BBQ0tBR0VfMSkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldFZhcmlhbnRJZChWQVJJQU5UX0lEXzEpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBuZXR3b3JrVXNhZ2VNb25pdG9yLm1vbml0b3JVcmkoCisgICAgICAgIHVyaTEsIGdyb3VwS2V5MSwgQlVJTERfSURfMSwgVkVSU0lPTl9OVU1CRVJfMSwgbG9nZ2luZ1N0YXRlU3RvcmUpOworCisgICAgTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IxID0gbmV0d29ya1VzYWdlTW9uaXRvci5tb25pdG9yV3JpdGUodXJpMSk7CisKKyAgICAvLyBBZHZhbmNlIHRpbWUgc28gY291bnRlcnMgYXJlIGZsdXNoZWQKKyAgICBjbG9jay5hZHZhbmNlKE5ldHdvcmtVc2FnZU1vbml0b3IuTE9HX0ZSRVFVRU5DWV9TRUNPTkRTICsgMSwgU0VDT05EUyk7CisKKyAgICAvLyBEb3dubG9hZGVkIDEgYnl0ZXMgb24gV0lGSSBmb3IgdXJpMQorICAgIHNldE5ldHdvcmtDb25uZWN0aXZpdHlUeXBlKENvbm5lY3Rpdml0eU1hbmFnZXIuVFlQRV9XSUZJKTsKKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMV0sIDAsIDEpOworCisgICAgLy8gQWR2YW5jZSB0aGUgY2xvY2sgYnkgPCBMT0dfRlJFUVVFTkNZX1NFQ09ORFMKKyAgICBjbG9jay5hZHZhbmNlKDEsIE1JTExJU0VDT05EUyk7CisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzJdLCAwLCAyKTsKKworICAgIGNsb2NrLmFkdmFuY2UoMSwgTUlMTElTRUNPTkRTKTsKKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMTZdLCAwLCA0KTsKKworICAgIC8vIE9ubHkgdGhlIDFzdCBhbmQgMm5kIGNodW5rcyB3ZXJlIHNhdmVkLgorICAgIGFzc2VydFRoYXQobG9nZ2luZ1N0YXRlU3RvcmUuZ2V0QW5kUmVzZXRBbGxEYXRhVXNhZ2UoKS5nZXQoKSkuaXNFbXB0eSgpOworCisgICAgLy8gQWR2YW5jZSB0aGUgY2xvY2sgYnkgPiBMT0dfRlJFUVVFTkNZX1NFQ09ORFMKKyAgICBjbG9jay5hZHZhbmNlKE5ldHdvcmtVc2FnZU1vbml0b3IuTE9HX0ZSRVFVRU5DWV9TRUNPTkRTICsgMSwgU0VDT05EUyk7CisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzE2XSwgMCwgOCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCB0ZXN0Qnl0ZXNXcml0dGVuX21peF93cml0ZV9hcHBlbmQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKKyAgICAvLyBTZXR1cCAyIEZpbGVHcm91cHM6CisgICAgLy8gRmlsZUdyb3VwMTogZmlsZTEgYW5kIGZpbGUyLgorICAgIC8vIEZpbGVHcm91cDI6IGZpbGUzLgorCisgICAgR3JvdXBLZXkgZ3JvdXBLZXkxID0KKyAgICAgICAgR3JvdXBLZXkubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0T3duZXJQYWNrYWdlKE9XTkVSX1BBQ0tBR0VfMSkKKyAgICAgICAgICAgIC5zZXRHcm91cE5hbWUoR1JPVVBfTkFNRV8xKQorICAgICAgICAgICAgLnNldFZhcmlhbnRJZChWQVJJQU5UX0lEXzEpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBuZXR3b3JrVXNhZ2VNb25pdG9yLm1vbml0b3JVcmkoCisgICAgICAgIHVyaTEsIGdyb3VwS2V5MSwgQlVJTERfSURfMSwgVkVSU0lPTl9OVU1CRVJfMSwgbG9nZ2luZ1N0YXRlU3RvcmUpOworICAgIG5ldHdvcmtVc2FnZU1vbml0b3IubW9uaXRvclVyaSgKKyAgICAgICAgdXJpMiwgZ3JvdXBLZXkxLCBCVUlMRF9JRF8xLCBWRVJTSU9OX05VTUJFUl8xLCBsb2dnaW5nU3RhdGVTdG9yZSk7CisKKyAgICBHcm91cEtleSBncm91cEtleTIgPQorICAgICAgICBHcm91cEtleS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRPd25lclBhY2thZ2UoT1dORVJfUEFDS0FHRV8yKQorICAgICAgICAgICAgLnNldEdyb3VwTmFtZShHUk9VUF9OQU1FXzIpCisgICAgICAgICAgICAuc2V0VmFyaWFudElkKFZBUklBTlRfSURfMikKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgbmV0d29ya1VzYWdlTW9uaXRvci5tb25pdG9yVXJpKAorICAgICAgICB1cmkzLCBncm91cEtleTIsIEJVSUxEX0lEXzIsIFZFUlNJT05fTlVNQkVSXzIsIGxvZ2dpbmdTdGF0ZVN0b3JlKTsKKworICAgIE1vbml0b3IuT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yMSA9IG5ldHdvcmtVc2FnZU1vbml0b3IubW9uaXRvcldyaXRlKHVyaTEpOworICAgIE1vbml0b3IuT3V0cHV0TW9uaXRvciBvdXRwdXRNb25pdG9yMiA9IG5ldHdvcmtVc2FnZU1vbml0b3IubW9uaXRvckFwcGVuZCh1cmkyKTsKKyAgICBNb25pdG9yLk91dHB1dE1vbml0b3Igb3V0cHV0TW9uaXRvcjMgPSBuZXR3b3JrVXNhZ2VNb25pdG9yLm1vbml0b3JBcHBlbmQodXJpMyk7CisKKyAgICAvLyBvdXRwdXRNb25pdG9yMSBpcyBzYW1lIGFzIG91dHB1dE1vbml0b3IyIHNpbmNlIHRoZXkgYm90aCBtb25pdG9yIGZvciBGaWxlR3JvdXAxLgorICAgIGFzc2VydFRoYXQob3V0cHV0TW9uaXRvcjEpLmlzU2FtZUluc3RhbmNlQXMob3V0cHV0TW9uaXRvcjIpOworICAgIGFzc2VydFRoYXQob3V0cHV0TW9uaXRvcjEpLmlzTm90U2FtZUluc3RhbmNlQXMob3V0cHV0TW9uaXRvcjMpOworCisgICAgLy8gRmlyc3Qgd2UgaGF2ZSBXSUZJIGNvbm5lY3Rpb24uCisgICAgLy8gRG93bmxvYWRlZCAxIGJ5dGVzIG9uIFdJRkkgZm9yIHVyaTEKKyAgICBzZXROZXR3b3JrQ29ubmVjdGl2aXR5VHlwZShDb25uZWN0aXZpdHlNYW5hZ2VyLlRZUEVfV0lGSSk7CisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzFdLCAwLCAxKTsKKworICAgIC8vIERvd25sb2FkZWQgMiBieXRlcyBvbiBXSUZJIGZvciB1cmkxCisgICAgb3V0cHV0TW9uaXRvcjEuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzJdLCAwLCAyKTsKKworICAgIC8vIERvd25sb2FkZWQgNCBieXRlcyBvbiBXSUZJIGZvciB1cmkyCisgICAgb3V0cHV0TW9uaXRvcjIuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzRdLCAwLCA0KTsKKworICAgIC8vIERvd25sb2FkZWQgOCBieXRlcyBvbiBXSUZJIGZvciB1cmkzCisgICAgb3V0cHV0TW9uaXRvcjMuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzhdLCAwLCA4KTsKKworICAgIC8vIFRoZW4gd2UgaGF2ZSBDRUxMVUxBUiBjb25uZWN0aW9uLgorICAgIC8vIERvd25sb2FkZWQgMTYgYnl0ZXMgb24gQ0VMTFVMQVIgZm9yIHVyaTEKKyAgICBzZXROZXR3b3JrQ29ubmVjdGl2aXR5VHlwZShDb25uZWN0aXZpdHlNYW5hZ2VyLlRZUEVfTU9CSUxFKTsKKyAgICBvdXRwdXRNb25pdG9yMS5ieXRlc1dyaXR0ZW4obmV3IGJ5dGVbMTZdLCAwLCAxNik7CisKKyAgICAvLyBEb3dubG9hZGVkIDMyIGJ5dGVzIG9uIENFTExVTEFSIGZvciB1cmkyCisgICAgb3V0cHV0TW9uaXRvcjIuYnl0ZXNXcml0dGVuKG5ldyBieXRlWzMyXSwgMCwgMzIpOworCisgICAgLy8gRG93bmxvYWRlZCA2NCBieXRlcyBvbiBDRUxMVUxBUiBmb3IgdXJpMworICAgIG91dHB1dE1vbml0b3IzLmJ5dGVzV3JpdHRlbihuZXcgYnl0ZVs2NF0sIDAsIDY0KTsKKworICAgIC8vIGNsb3NlKCkgd2lsbCB0cmlnZ2VyIHNhdmluZyBjb3VudGVycyB0byBTaGFyZWRQcmVmZXJlbmNlLgorICAgIG91dHB1dE1vbml0b3IxLmNsb3NlKCk7CisgICAgb3V0cHV0TW9uaXRvcjIuY2xvc2UoKTsKKyAgICBvdXRwdXRNb25pdG9yMy5jbG9zZSgpOworCisgICAgLy8gYXdhaXQgZXhlY3V0b3JzIGlkbGUgaGVyZSBpZiB3ZSBzd2l0Y2ggZnJvbSBkaXJlY3RFeGVjdXRvci4uLgorICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0TmV0d29ya0Nvbm5lY3Rpdml0eVR5cGUoKSB7CisgICAgc2V0TmV0d29ya0Nvbm5lY3Rpdml0eVR5cGUoQ29ubmVjdGl2aXR5TWFuYWdlci5UWVBFX1dJRkkpOworICAgIGFzc2VydFRoYXQoTmV0d29ya1VzYWdlTW9uaXRvci5pc0NlbGx1bGFyKGNvbnRleHQpKS5pc0ZhbHNlKCk7CisKKyAgICBzZXROZXR3b3JrQ29ubmVjdGl2aXR5VHlwZShDb25uZWN0aXZpdHlNYW5hZ2VyLlRZUEVfRVRIRVJORVQpOworICAgIGFzc2VydFRoYXQoTmV0d29ya1VzYWdlTW9uaXRvci5pc0NlbGx1bGFyKGNvbnRleHQpKS5pc0ZhbHNlKCk7CisKKyAgICBzZXROZXR3b3JrQ29ubmVjdGl2aXR5VHlwZShDb25uZWN0aXZpdHlNYW5hZ2VyLlRZUEVfVlBOKTsKKyAgICBpZiAoQnVpbGQuVkVSU0lPTi5TREtfSU5UID49IEJ1aWxkLlZFUlNJT05fQ09ERVMuTE9MTElQT1ApIHsKKyAgICAgIGFzc2VydFRoYXQoTmV0d29ya1VzYWdlTW9uaXRvci5pc0NlbGx1bGFyKGNvbnRleHQpKS5pc0ZhbHNlKCk7CisKKyAgICB9IGVsc2UgeworICAgICAgYXNzZXJ0VGhhdChOZXR3b3JrVXNhZ2VNb25pdG9yLmlzQ2VsbHVsYXIoY29udGV4dCkpLmlzVHJ1ZSgpOworICAgIH0KKworICAgIHNldE5ldHdvcmtDb25uZWN0aXZpdHlUeXBlKENvbm5lY3Rpdml0eU1hbmFnZXIuVFlQRV9NT0JJTEUpOworICAgIGFzc2VydFRoYXQoTmV0d29ya1VzYWdlTW9uaXRvci5pc0NlbGx1bGFyKGNvbnRleHQpKS5pc1RydWUoKTsKKworICAgIC8vIEZhaWwgdG8gZ2V0IE5ldHdvcmtJbmZvKHJldHVybiBudWxsKSB3aWxsIHJldHVybiBUWVBFX1dJRkkuCisgICAgU2hhZG93cy5zaGFkb3dPZihjb25uZWN0aXZpdHlNYW5hZ2VyKS5zZXRBY3RpdmVOZXR3b3JrSW5mbyhudWxsKTsKKyAgICBhc3NlcnRUaGF0KE5ldHdvcmtVc2FnZU1vbml0b3IuaXNDZWxsdWxhcihjb250ZXh0KSkuaXNGYWxzZSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgdGVzdE5vdFJlZ2lzdGVyVXJpKCkgeworICAgIC8vIENyZWF0aW5nIHRoZSBvdXRwdXRNb25pdG9yIGJlZm9yZSByZWdpc3RlcmluZyB0aGUgdXJpIHRocm91Z2ggbW9uaXRvclVyaSB3aWxsIHJldHVybgorICAgIC8vIG51bGwuCisgICAgTW9uaXRvci5PdXRwdXRNb25pdG9yIG91dHB1dE1vbml0b3IgPSBuZXR3b3JrVXNhZ2VNb25pdG9yLm1vbml0b3JXcml0ZSh1cmkxKTsKKyAgICBhc3NlcnRUaGF0KG91dHB1dE1vbml0b3IpLmlzTnVsbCgpOworCisgICAgb3V0cHV0TW9uaXRvciA9IG5ldHdvcmtVc2FnZU1vbml0b3IubW9uaXRvckFwcGVuZCh1cmkxKTsKKyAgICBhc3NlcnRUaGF0KG91dHB1dE1vbml0b3IpLmlzTnVsbCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0FuZHJvaWRNYW5pZmVzdC54bWwgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0FuZHJvaWRNYW5pZmVzdC54bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTEwMjQ5MQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvQW5kcm9pZE1hbmlmZXN0LnhtbApAQCAtMCwwICsxLDM2IEBACis8IS0tCisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLS0+Cis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI/PgorPG1hbmlmZXN0IHhtbG5zOmFuZHJvaWQ9Imh0dHA6Ly9zY2hlbWFzLmFuZHJvaWQuY29tL2Fway9yZXMvYW5kcm9pZCIKKyAgcGFja2FnZT0iY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQucG9wdWxhdG9yIiA+CisKKyAgPHVzZXMtc2RrIGFuZHJvaWQ6bWluU2RrVmVyc2lvbj0iMTYiIC8+CisgIDx1c2VzLXBlcm1pc3Npb24gYW5kcm9pZDpuYW1lPSJhbmRyb2lkLnBlcm1pc3Npb24uSU5URVJORVQiLz4KKyAgPHVzZXMtcGVybWlzc2lvbgorICAgIGFuZHJvaWQ6bmFtZT0iY29tLmdvb2dsZS5hbmRyb2lkLmdtcy5wZXJtaXNzaW9uLkJJTkRfTkVUV09SS19UQVNLX1NFUlZJQ0UiLz4KKyAgPHVzZXMtcGVybWlzc2lvbiBhbmRyb2lkOm5hbWU9ImFuZHJvaWQucGVybWlzc2lvbi5BQ0NFU1NfTkVUV09SS19TVEFURSIvPgorCisgIDxhcHBsaWNhdGlvbiBhbmRyb2lkOm5hbWU9ImFuZHJvaWQuc3VwcG9ydC5tdWx0aWRleC5NdWx0aURleEFwcGxpY2F0aW9uIj4KKyAgICA8IS0tVGhpcyBtZXRhLWRhdGEgdGFnIGlzIHJlcXVpcmVkIHRvIHVzZSBHb29nbGUgUGxheSBTZXJ2aWNlcy4tLT4KKyAgICA8bWV0YS1kYXRhIGFuZHJvaWQ6bmFtZT0iY29tLmdvb2dsZS5hbmRyb2lkLmdtcy52ZXJzaW9uIiBhbmRyb2lkOnZhbHVlPSJAaW50ZWdlci9nb29nbGVfcGxheV9zZXJ2aWNlc192ZXJzaW9uIi8+CisgIDwvYXBwbGljYXRpb24+CisKKyAgPGluc3RydW1lbnRhdGlvbgorICAgIGFuZHJvaWQ6bmFtZT0iY29tLmdvb2dsZS5hbmRyb2lkLmFwcHMuY29tbW9uLnRlc3RpbmcudGVzdHJ1bm5lci5Hb29nbGUzSW5zdHJ1bWVudGF0aW9uVGVzdFJ1bm5lciIKKyAgICBhbmRyb2lkOnRhcmdldFBhY2thZ2U9ImNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnBvcHVsYXRvciIgLz4KKzwvbWFuaWZlc3Q+CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0JVSUxEIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zNGFlNzI0Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9CVUlMRApAQCAtMCwwICsxLDk5IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9sb2NhbF90ZXN0IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiTWlncmF0aW9uUHJveHlQb3B1bGF0b3JUZXN0IiwKKyAgICBzcmNzID0gWyJNaWdyYXRpb25Qcm94eVBvcHVsYXRvclRlc3QuamF2YSJdLAorICAgIG1hbmlmZXN0X3ZhbHVlcyA9IHsKKyAgICAgICAgIm1pblNka1ZlcnNpb24iOiAiMTYiLAorICAgICAgICAidGFyZ2V0U2RrVmVyc2lvbiI6ICIyNyIsCisgICAgfSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3I6TWlncmF0aW9uUHJveHlQb3B1bGF0b3IiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJMb2NhdGlvblByb3ZpZGVySW1wbFRlc3QiLAorICAgIHNyY3MgPSBbIkxvY2F0aW9uUHJvdmlkZXJJbXBsVGVzdC5qYXZhIl0sCisgICAgbWFuaWZlc3RfdmFsdWVzID0geworICAgICAgICAibWluU2RrVmVyc2lvbiI6ICIxNiIsCisgICAgICAgICJ0YXJnZXRTZGtWZXJzaW9uIjogIjI3IiwKKyAgICB9LAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yOkxvY2F0aW9uUHJvdmlkZXIiLAorICAgICAgICAiQGFuZHJvaWR4X3Rlc3QiLAorICAgICAgICAiQG1vY2tpdG8iLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJNYW5pZmVzdENvbmZpZ0ZsYWdQb3B1bGF0b3JUZXN0IiwKKyAgICBzcmNzID0gWyJNYW5pZmVzdENvbmZpZ0ZsYWdQb3B1bGF0b3JUZXN0LmphdmEiXSwKKyAgICBtYW5pZmVzdF92YWx1ZXMgPSB7CisgICAgICAgICJtaW5TZGtWZXJzaW9uIjogIjE2IiwKKyAgICAgICAgInRhcmdldFNka1ZlcnNpb24iOiAiMjciLAorICAgIH0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZCIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yOk1hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yOk1hbmlmZXN0Q29uZmlnSGVscGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3I6TWFuaWZlc3RDb25maWdPdmVycmlkZXIiLAorICAgICAgICAiLy9wcm90bzpkb3dubG9hZF9jb25maWdfamF2YV9wcm90b19saXRlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBtb2NraXRvIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgIG5hbWUgPSAiTG9jYWxlT3ZlcnJpZGVyVGVzdCIsCisgICAgc3JjcyA9IFsiTG9jYWxlT3ZlcnJpZGVyVGVzdC5qYXZhIl0sCisgICAgbWFuaWZlc3RfdmFsdWVzID0geworICAgICAgICAibWluU2RrVmVyc2lvbiI6ICIxNiIsCisgICAgICAgICJ0YXJnZXRTZGtWZXJzaW9uIjogIjI3IiwKKyAgICB9LAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yOkxvY2FsZU92ZXJyaWRlciIsCisgICAgICAgICIvL3Byb3RvOmRvd25sb2FkX2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQHRydXRoIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xvY2FsX3Rlc3QoCisgICAgbmFtZSA9ICJNaWdyYXRpb25Qcm94eUxvY2FsZU92ZXJyaWRlclRlc3QiLAorICAgIHNyY3MgPSBbIk1pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyVGVzdC5qYXZhIl0sCisgICAgbWFuaWZlc3RfdmFsdWVzID0geworICAgICAgICAibWluU2RrVmVyc2lvbiI6ICIxNiIsCisgICAgICAgICJ0YXJnZXRTZGtWZXJzaW9uIjogIjI3IiwKKyAgICB9LAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yOkxvY2FsZU92ZXJyaWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yOk1pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyIiwKKyAgICAgICAgIi8vcHJvdG86ZG93bmxvYWRfY29uZmlnX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgICAgICJAdHJ1dGgiLAorICAgIF0sCispCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0xvY2FsZU92ZXJyaWRlclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTG9jYWxlT3ZlcnJpZGVyVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQxMjZmMDYKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0xvY2FsZU92ZXJyaWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDE4MSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQucG9wdWxhdG9yOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlN1cHBsaWVyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5Nb3JlRXhlY3V0b3JzOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5EYXRhRmlsZUdyb3VwOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uTWFuaWZlc3RDb25maWc7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKKy8qKiBUZXN0cyBmb3Ige0BsaW5rIExvY2FsZU92ZXJyaWRlcn0uICovCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgY2xhc3MgTG9jYWxlT3ZlcnJpZGVyVGVzdCB7CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3ZlcnJpZGVfZXF1YWxTdHJhdGVneV9oYXNNYXRjaCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICBTdXBwbGllcjxMb2NhbGU+IGxvY2FsZVN1cHBsaWVyID0gKCkgLT4gTG9jYWxlLmZvckxhbmd1YWdlVGFnKCJlbi1VUyIpOworICAgIE1hbmlmZXN0Q29uZmlnIGNvbmZpZyA9CisgICAgICAgIE1hbmlmZXN0Q29uZmlnLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEVudHJ5KGNyZWF0ZUVudHJ5V2l0aExvY2FsZUFuZElkZW50aWZpZXIoImVuIiwgImVuLXJlc291cmNlIikpCisgICAgICAgICAgICAuYWRkRW50cnkoY3JlYXRlRW50cnlXaXRoTG9jYWxlQW5kSWRlbnRpZmllcigiZW4tVVMiLCAiZW4tVVMtcmVzb3VyY2UiKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIExvY2FsZU92ZXJyaWRlciBvdmVycmlkZXIgPQorICAgICAgICBMb2NhbGVPdmVycmlkZXIuYnVpbGRlcigpCisgICAgICAgICAgICAuc2V0TG9jYWxlU3VwcGxpZXIobG9jYWxlU3VwcGxpZXIpCisgICAgICAgICAgICAuc2V0TWF0Y2hTdHJhdGVneShMb2NhbGVPdmVycmlkZXIuRVFVQUxfU1RSQVRFR1kpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXAgPSBvdmVycmlkZXIub3ZlcnJpZGUoY29uZmlnKS5nZXQoKS5nZXQoMCk7CisgICAgYXNzZXJ0VGhhdChkYXRhRmlsZUdyb3VwLmdldExvY2FsZSgwKSkuaXNFcXVhbFRvKCJlbi1VUyIpOworICAgIGFzc2VydFRoYXQoZGF0YUZpbGVHcm91cC50b1N0cmluZygpKS5jb250YWlucygiZW4tVVMtcmVzb3VyY2UiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG92ZXJyaWRlX2VxdWFsU3RyYXRlZ3lfaGFzTWF0Y2hfbG9jYWxlTEYoKQorICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24geworICAgIFN1cHBsaWVyPExpc3RlbmFibGVGdXR1cmU8TG9jYWxlPj4gbG9jYWxlU3VwcGxpZXIgPQorICAgICAgICAoKSAtPiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShMb2NhbGUuZm9yTGFuZ3VhZ2VUYWcoImVuLVVTIikpOworICAgIE1hbmlmZXN0Q29uZmlnIGNvbmZpZyA9CisgICAgICAgIE1hbmlmZXN0Q29uZmlnLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEVudHJ5KGNyZWF0ZUVudHJ5V2l0aExvY2FsZUFuZElkZW50aWZpZXIoImVuIiwgImVuLXJlc291cmNlIikpCisgICAgICAgICAgICAuYWRkRW50cnkoY3JlYXRlRW50cnlXaXRoTG9jYWxlQW5kSWRlbnRpZmllcigiZW4tVVMiLCAiZW4tVVMtcmVzb3VyY2UiKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIExvY2FsZU92ZXJyaWRlciBvdmVycmlkZXIgPQorICAgICAgICBMb2NhbGVPdmVycmlkZXIuYnVpbGRlcigpCisgICAgICAgICAgICAuc2V0TG9jYWxlRnV0dXJlU3VwcGxpZXIobG9jYWxlU3VwcGxpZXIsIE1vcmVFeGVjdXRvcnMuZGlyZWN0RXhlY3V0b3IoKSkKKyAgICAgICAgICAgIC5zZXRNYXRjaFN0cmF0ZWd5KExvY2FsZU92ZXJyaWRlci5FUVVBTF9TVFJBVEVHWSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cCA9IG92ZXJyaWRlci5vdmVycmlkZShjb25maWcpLmdldCgpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlR3JvdXAuZ2V0TG9jYWxlKDApKS5pc0VxdWFsVG8oImVuLVVTIik7CisgICAgYXNzZXJ0VGhhdChkYXRhRmlsZUdyb3VwLnRvU3RyaW5nKCkpLmNvbnRhaW5zKCJlbi1VUy1yZXNvdXJjZSIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3ZlcnJpZGVfZXF1YWxTdHJhdGVneV9ub01hdGNoKCkgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24geworICAgIFN1cHBsaWVyPExvY2FsZT4gbG9jYWxlU3VwcGxpZXIgPSAoKSAtPiBMb2NhbGUuZm9yTGFuZ3VhZ2VUYWcoImpwLUpQIik7CisgICAgTWFuaWZlc3RDb25maWcgY29uZmlnID0KKyAgICAgICAgTWFuaWZlc3RDb25maWcubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuYWRkRW50cnkoY3JlYXRlRW50cnlXaXRoTG9jYWxlQW5kSWRlbnRpZmllcigiZW4iLCAiZW4tcmVzb3VyY2UiKSkKKyAgICAgICAgICAgIC5hZGRFbnRyeShjcmVhdGVFbnRyeVdpdGhMb2NhbGVBbmRJZGVudGlmaWVyKCJlbi1VUyIsICJlbi1VUy1yZXNvdXJjZSIpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgTG9jYWxlT3ZlcnJpZGVyIG92ZXJyaWRlciA9CisgICAgICAgIExvY2FsZU92ZXJyaWRlci5idWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRMb2NhbGVTdXBwbGllcihsb2NhbGVTdXBwbGllcikKKyAgICAgICAgICAgIC5zZXRNYXRjaFN0cmF0ZWd5KExvY2FsZU92ZXJyaWRlci5FUVVBTF9TVFJBVEVHWSkKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgYXNzZXJ0VGhhdChvdmVycmlkZXIub3ZlcnJpZGUoY29uZmlnKS5nZXQoKSkuaXNFbXB0eSgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3ZlcnJpZGVfbGFuZ0ZhbGxiYWNrU3RyYXRlZ3lfZXhhY3RNYXRjaCgpCisgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbiB7CisgICAgU3VwcGxpZXI8TG9jYWxlPiBsb2NhbGVTdXBwbGllciA9ICgpIC0+IExvY2FsZS5mb3JMYW5ndWFnZVRhZygiZW4tVVMiKTsKKyAgICBNYW5pZmVzdENvbmZpZyBjb25maWcgPQorICAgICAgICBNYW5pZmVzdENvbmZpZy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRFbnRyeShjcmVhdGVFbnRyeVdpdGhMb2NhbGVBbmRJZGVudGlmaWVyKCJlbiIsICJlbi1yZXNvdXJjZSIpKQorICAgICAgICAgICAgLmFkZEVudHJ5KGNyZWF0ZUVudHJ5V2l0aExvY2FsZUFuZElkZW50aWZpZXIoImVuLVVTIiwgImVuLVVTLXJlc291cmNlIikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBMb2NhbGVPdmVycmlkZXIgb3ZlcnJpZGVyID0KKyAgICAgICAgTG9jYWxlT3ZlcnJpZGVyLmJ1aWxkZXIoKQorICAgICAgICAgICAgLnNldExvY2FsZVN1cHBsaWVyKGxvY2FsZVN1cHBsaWVyKQorICAgICAgICAgICAgLnNldE1hdGNoU3RyYXRlZ3koTG9jYWxlT3ZlcnJpZGVyLkxBTkdfRkFMTEJBQ0tfU1RSQVRFR1kpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQob3ZlcnJpZGVyLm92ZXJyaWRlKGNvbmZpZykuZ2V0KCkuZ2V0KDApLnRvU3RyaW5nKCkpLmNvbnRhaW5zKCJlbi1VUy1yZXNvdXJjZSIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3ZlcnJpZGVfbGFuZ0ZhbGxiYWNrU3RyYXRlZ3lfZmFsbGJhY2tNYXRjaCgpCisgICAgICB0aHJvd3MgSW50ZXJydXB0ZWRFeGNlcHRpb24sIEV4ZWN1dGlvbkV4Y2VwdGlvbiB7CisgICAgU3VwcGxpZXI8TG9jYWxlPiBsb2NhbGVTdXBwbGllciA9ICgpIC0+IExvY2FsZS5mb3JMYW5ndWFnZVRhZygiZW4tVVMiKTsKKyAgICBNYW5pZmVzdENvbmZpZyBjb25maWcgPQorICAgICAgICBNYW5pZmVzdENvbmZpZy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRFbnRyeShjcmVhdGVFbnRyeVdpdGhMb2NhbGVBbmRJZGVudGlmaWVyKCJlbiIsICJlbi1yZXNvdXJjZSIsIHRydWUpKQorICAgICAgICAgICAgLmFkZEVudHJ5KGNyZWF0ZUVudHJ5V2l0aExvY2FsZUFuZElkZW50aWZpZXIoImVuLUdCIiwgImVuLUdCLXJlc291cmNlIiwgdHJ1ZSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBMb2NhbGVPdmVycmlkZXIgb3ZlcnJpZGVyID0KKyAgICAgICAgTG9jYWxlT3ZlcnJpZGVyLmJ1aWxkZXIoKQorICAgICAgICAgICAgLnNldExvY2FsZVN1cHBsaWVyKGxvY2FsZVN1cHBsaWVyKQorICAgICAgICAgICAgLnNldE1hdGNoU3RyYXRlZ3koTG9jYWxlT3ZlcnJpZGVyLkxBTkdfRkFMTEJBQ0tfU1RSQVRFR1kpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cCA9IG92ZXJyaWRlci5vdmVycmlkZShjb25maWcpLmdldCgpLmdldCgwKTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlR3JvdXAuZ2V0TG9jYWxlKDApKS5pc0VxdWFsVG8oImVuIik7CisgICAgYXNzZXJ0VGhhdChkYXRhRmlsZUdyb3VwLmdldExvY2FsZUNvdW50KCkpLmlzRXF1YWxUbygxKTsKKyAgICBhc3NlcnRUaGF0KGRhdGFGaWxlR3JvdXAudG9TdHJpbmcoKSkuY29udGFpbnMoImVuLXJlc291cmNlIik7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvdmVycmlkZV9sYW5nRmFsbGJhY2tTdHJhdGVneV9ub01hdGNoKCkKKyAgICAgIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiwgRXhlY3V0aW9uRXhjZXB0aW9uIHsKKyAgICBTdXBwbGllcjxMb2NhbGU+IGxvY2FsZVN1cHBsaWVyID0gKCkgLT4gTG9jYWxlLmZvckxhbmd1YWdlVGFnKCJlbi1VUyIpOworICAgIE1hbmlmZXN0Q29uZmlnIGNvbmZpZyA9CisgICAgICAgIE1hbmlmZXN0Q29uZmlnLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEVudHJ5KGNyZWF0ZUVudHJ5V2l0aExvY2FsZUFuZElkZW50aWZpZXIoImpwIiwgImpwLXJlc291cmNlIikpCisgICAgICAgICAgICAuYWRkRW50cnkoY3JlYXRlRW50cnlXaXRoTG9jYWxlQW5kSWRlbnRpZmllcigiZW4tR0IiLCAiZW4tR0ItcmVzb3VyY2UiKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIExvY2FsZU92ZXJyaWRlciBvdmVycmlkZXIgPQorICAgICAgICBMb2NhbGVPdmVycmlkZXIuYnVpbGRlcigpCisgICAgICAgICAgICAuc2V0TG9jYWxlU3VwcGxpZXIobG9jYWxlU3VwcGxpZXIpCisgICAgICAgICAgICAuc2V0TWF0Y2hTdHJhdGVneShMb2NhbGVPdmVycmlkZXIuRVFVQUxfU1RSQVRFR1kpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIGFzc2VydFRoYXQob3ZlcnJpZGVyLm92ZXJyaWRlKGNvbmZpZykuZ2V0KCkpLmlzRW1wdHkoKTsKKyAgfQorCisgIC8qKgorICAgKiBDcmVhdGVzIGEge0BsaW5rIE1hbmlmZXN0Q29uZmlnLkVudHJ5fSB3aXRoIHtAY29kZSBsb2NhbGV9IGFuZCBzb21lIGZpZWxkIHNldCB0byB7QGNvZGUKKyAgICogaWRlbnRpZmllcn0KKyAgICovCisgIHByaXZhdGUgc3RhdGljIE1hbmlmZXN0Q29uZmlnLkVudHJ5IGNyZWF0ZUVudHJ5V2l0aExvY2FsZUFuZElkZW50aWZpZXIoCisgICAgICBTdHJpbmcgbG9jYWxlLCBTdHJpbmcgaWRlbnRpZmllcikgeworICAgIHJldHVybiBNYW5pZmVzdENvbmZpZy5FbnRyeS5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldE1vZGlmaWVyKE1hbmlmZXN0Q29uZmlnLkVudHJ5Lk1vZGlmaWVyLm5ld0J1aWxkZXIoKS5hZGRMb2NhbGUobG9jYWxlKS5idWlsZCgpKQorICAgICAgICAuc2V0RGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgIERhdGFGaWxlR3JvdXAubmV3QnVpbGRlcigpLmFkZEZpbGUoRGF0YUZpbGUubmV3QnVpbGRlcigpLnNldEZpbGVJZChpZGVudGlmaWVyKSkpCisgICAgICAgIC5idWlsZCgpOworICB9CisKKyAgLyoqCisgICAqIENyZWF0ZXMgYSB7QGxpbmsgTWFuaWZlc3RDb25maWcuRW50cnl9IHdpdGgge0Bjb2RlIGxvY2FsZX0gYW5kIHNvbWUgZmllbGQgc2V0IHRvIHtAY29kZQorICAgKiBpZGVudGlmaWVyfQorICAgKgorICAgKiBAcGFyYW0gaXNMb2NhbGVTZXRJbkRGIGlmIHRydWUsIGxvY2FsZSBpcyBzZXQgdG8gRGF0YUZpbGVHcm91cAorICAgKi8KKyAgcHJpdmF0ZSBzdGF0aWMgTWFuaWZlc3RDb25maWcuRW50cnkgY3JlYXRlRW50cnlXaXRoTG9jYWxlQW5kSWRlbnRpZmllcigKKyAgICAgIFN0cmluZyBsb2NhbGUsIFN0cmluZyBpZGVudGlmaWVyLCBib29sZWFuIGlzTG9jYWxlU2V0SW5ERikgeworICAgIGlmIChpc0xvY2FsZVNldEluREYpIHsKKyAgICAgIHJldHVybiBNYW5pZmVzdENvbmZpZy5FbnRyeS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAuc2V0TW9kaWZpZXIoTWFuaWZlc3RDb25maWcuRW50cnkuTW9kaWZpZXIubmV3QnVpbGRlcigpLmFkZExvY2FsZShsb2NhbGUpLmJ1aWxkKCkpCisgICAgICAgICAgLnNldERhdGFGaWxlR3JvdXAoCisgICAgICAgICAgICAgIERhdGFGaWxlR3JvdXAubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAuYWRkRmlsZShEYXRhRmlsZS5uZXdCdWlsZGVyKCkuc2V0RmlsZUlkKGlkZW50aWZpZXIpKQorICAgICAgICAgICAgICAgICAgLmFkZExvY2FsZShsb2NhbGUpKQorICAgICAgICAgIC5idWlsZCgpOworICAgIH0KKyAgICByZXR1cm4gY3JlYXRlRW50cnlXaXRoTG9jYWxlQW5kSWRlbnRpZmllcihsb2NhbGUsIGlkZW50aWZpZXIpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL0xvY2F0aW9uUHJvdmlkZXJJbXBsVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9Mb2NhdGlvblByb3ZpZGVySW1wbFRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NGNiYTViCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9Mb2NhdGlvblByb3ZpZGVySW1wbFRlc3QuamF2YQpAQCAtMCwwICsxLDExMSBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQucG9wdWxhdG9yOworCitpbXBvcnQgc3RhdGljIGFuZHJvaWQuTWFuaWZlc3QucGVybWlzc2lvbi5BQ0NFU1NfRklORV9MT0NBVElPTjsKK2ltcG9ydCBzdGF0aWMgYW5kcm9pZHgudGVzdC5jb3JlLmFwcC5BcHBsaWNhdGlvblByb3ZpZGVyLmdldEFwcGxpY2F0aW9uQ29udGV4dDsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by53aGVuOworaW1wb3J0IHN0YXRpYyBvcmcucm9ib2xlY3RyaWMuU2hhZG93cy5zaGFkb3dPZjsKKworaW1wb3J0IGFuZHJvaWQuTWFuaWZlc3QucGVybWlzc2lvbjsKK2ltcG9ydCBhbmRyb2lkLmFwcC5BcHBsaWNhdGlvbjsKK2ltcG9ydCBhbmRyb2lkLmxvY2F0aW9uLkxvY2F0aW9uOworaW1wb3J0IGFuZHJvaWQubG9jYXRpb24uTG9jYXRpb25NYW5hZ2VyOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKKy8qKiBUZXN0cyBmb3Ige0BsaW5rIExvY2F0aW9uUHJvdmlkZXJJbXBsfS4gKi8KK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBMb2NhdGlvblByb3ZpZGVySW1wbFRlc3QgeworCisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgQE1vY2sgcHJpdmF0ZSBMb2NhdGlvbk1hbmFnZXIgbG9jYXRpb25NYW5hZ2VyOworICBwcml2YXRlIExvY2F0aW9uUHJvdmlkZXIgbG9jYXRpb25Qcm92aWRlcjsKKyAgcHJpdmF0ZSBMb2NhdGlvbiBsb2NhdGlvbldpdGhBY2N1cmFjeTsKKyAgcHJpdmF0ZSBMb2NhdGlvbiBsb2NhdGlvbldpdGhvdXRBY2N1cmFjeTsKKworICBAQmVmb3JlCisgIHB1YmxpYyB2b2lkIHNldFVwKCkgeworICAgIGxvY2F0aW9uUHJvdmlkZXIgPSBuZXcgTG9jYXRpb25Qcm92aWRlckltcGwoZ2V0QXBwbGljYXRpb25Db250ZXh0KCksIGxvY2F0aW9uTWFuYWdlcik7CisgICAgbG9jYXRpb25XaXRoQWNjdXJhY3kgPSBuZXcgTG9jYXRpb24oInByb3ZpZGVyIik7CisgICAgbG9jYXRpb25XaXRoQWNjdXJhY3kuc2V0TGF0aXR1ZGUoNDAuNyk7CisgICAgbG9jYXRpb25XaXRoQWNjdXJhY3kuc2V0TG9uZ2l0dWRlKC03NC4wKTsKKyAgICBsb2NhdGlvbldpdGhvdXRBY2N1cmFjeSA9IG5ldyBMb2NhdGlvbihsb2NhdGlvbldpdGhBY2N1cmFjeSk7CisgICAgbG9jYXRpb25XaXRoQWNjdXJhY3kuc2V0QWNjdXJhY3koMTApOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0TG9jYXRpb25fd2hlblBlcm1pc3Npb25zRGVuaWVkX3JldHVybnNBYnNlbnRMb2NhdGlvbigpIHsKKyAgICBzaGFkb3dPZigoQXBwbGljYXRpb24pIGdldEFwcGxpY2F0aW9uQ29udGV4dCgpKQorICAgICAgICAuZGVueVBlcm1pc3Npb25zKHBlcm1pc3Npb24uQUNDRVNTX0ZJTkVfTE9DQVRJT04sIHBlcm1pc3Npb24uQUNDRVNTX0NPQVJTRV9MT0NBVElPTik7CisgICAgYXNzZXJ0VGhhdChsb2NhdGlvblByb3ZpZGVyLmdldCgpKS5pc0Fic2VudCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgZ2V0TG9jYXRpb25fd2hlbkVpdGhlckFjY2Vzc0xvY2F0aW9uUGVybWlzc2lvbkdyYW50ZWRfcmV0dXJuc0xvY2F0aW9uKCkgeworICAgIHdoZW4obG9jYXRpb25NYW5hZ2VyLmdldExhc3RLbm93bkxvY2F0aW9uKExvY2F0aW9uTWFuYWdlci5ORVRXT1JLX1BST1ZJREVSKSkKKyAgICAgICAgLnRoZW5SZXR1cm4obG9jYXRpb25XaXRoQWNjdXJhY3kpOworICAgIHNoYWRvd09mKChBcHBsaWNhdGlvbikgZ2V0QXBwbGljYXRpb25Db250ZXh0KCkpCisgICAgICAgIC5kZW55UGVybWlzc2lvbnMocGVybWlzc2lvbi5BQ0NFU1NfQ09BUlNFX0xPQ0FUSU9OKTsKKyAgICBzaGFkb3dPZigoQXBwbGljYXRpb24pIGdldEFwcGxpY2F0aW9uQ29udGV4dCgpKQorICAgICAgICAuZ3JhbnRQZXJtaXNzaW9ucyhwZXJtaXNzaW9uLkFDQ0VTU19GSU5FX0xPQ0FUSU9OKTsKKworICAgIGFzc2VydFRoYXQobG9jYXRpb25Qcm92aWRlci5nZXQoKSkuaGFzVmFsdWUobG9jYXRpb25XaXRoQWNjdXJhY3kpOworCisgICAgc2hhZG93T2YoKEFwcGxpY2F0aW9uKSBnZXRBcHBsaWNhdGlvbkNvbnRleHQoKSkKKyAgICAgICAgLmRlbnlQZXJtaXNzaW9ucyhwZXJtaXNzaW9uLkFDQ0VTU19GSU5FX0xPQ0FUSU9OKTsKKyAgICBzaGFkb3dPZigoQXBwbGljYXRpb24pIGdldEFwcGxpY2F0aW9uQ29udGV4dCgpKQorICAgICAgICAuZ3JhbnRQZXJtaXNzaW9ucyhwZXJtaXNzaW9uLkFDQ0VTU19DT0FSU0VfTE9DQVRJT04pOworCisgICAgYXNzZXJ0VGhhdChsb2NhdGlvblByb3ZpZGVyLmdldCgpKS5oYXNWYWx1ZShsb2NhdGlvbldpdGhBY2N1cmFjeSk7CisKKyAgICBzaGFkb3dPZigoQXBwbGljYXRpb24pIGdldEFwcGxpY2F0aW9uQ29udGV4dCgpKQorICAgICAgICAuZ3JhbnRQZXJtaXNzaW9ucyhwZXJtaXNzaW9uLkFDQ0VTU19DT0FSU0VfTE9DQVRJT04sIEFDQ0VTU19GSU5FX0xPQ0FUSU9OKTsKKyAgICBhc3NlcnRUaGF0KGxvY2F0aW9uUHJvdmlkZXIuZ2V0KCkpLmhhc1ZhbHVlKGxvY2F0aW9uV2l0aEFjY3VyYWN5KTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIGdldExvY2F0aW9uX3doZW5OZXR3b3JrTG9jYXRpb25IYXNOb0FjY3VyYWN5X3JldHVybnNHcHNMb2NhdGlvbigpIHsKKyAgICBzaGFkb3dPZigoQXBwbGljYXRpb24pIGdldEFwcGxpY2F0aW9uQ29udGV4dCgpKQorICAgICAgICAuZ3JhbnRQZXJtaXNzaW9ucyhwZXJtaXNzaW9uLkFDQ0VTU19DT0FSU0VfTE9DQVRJT04sIEFDQ0VTU19GSU5FX0xPQ0FUSU9OKTsKKworICAgIHdoZW4obG9jYXRpb25NYW5hZ2VyLmdldExhc3RLbm93bkxvY2F0aW9uKExvY2F0aW9uTWFuYWdlci5ORVRXT1JLX1BST1ZJREVSKSkKKyAgICAgICAgLnRoZW5SZXR1cm4obG9jYXRpb25XaXRob3V0QWNjdXJhY3kpOworICAgIHdoZW4obG9jYXRpb25NYW5hZ2VyLmdldExhc3RLbm93bkxvY2F0aW9uKExvY2F0aW9uTWFuYWdlci5HUFNfUFJPVklERVIpKQorICAgICAgICAudGhlblJldHVybihsb2NhdGlvbldpdGhBY2N1cmFjeSk7CisgICAgYXNzZXJ0VGhhdChsb2NhdGlvblByb3ZpZGVyLmdldCgpKS5oYXNWYWx1ZShsb2NhdGlvbldpdGhBY2N1cmFjeSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBnZXRMb2NhdGlvbl93aGVuQm90aExvY2F0aW9uc0hhdmVOb0FjY3VyYWN5X3JldHVybnNBYnNlbnRMb2NhdGlvbigpIHsKKyAgICBzaGFkb3dPZigoQXBwbGljYXRpb24pIGdldEFwcGxpY2F0aW9uQ29udGV4dCgpKQorICAgICAgICAuZ3JhbnRQZXJtaXNzaW9ucyhwZXJtaXNzaW9uLkFDQ0VTU19DT0FSU0VfTE9DQVRJT04sIEFDQ0VTU19GSU5FX0xPQ0FUSU9OKTsKKworICAgIHdoZW4obG9jYXRpb25NYW5hZ2VyLmdldExhc3RLbm93bkxvY2F0aW9uKExvY2F0aW9uTWFuYWdlci5ORVRXT1JLX1BST1ZJREVSKSkKKyAgICAgICAgLnRoZW5SZXR1cm4obG9jYXRpb25XaXRob3V0QWNjdXJhY3kpOworICAgIHdoZW4obG9jYXRpb25NYW5hZ2VyLmdldExhc3RLbm93bkxvY2F0aW9uKExvY2F0aW9uTWFuYWdlci5HUFNfUFJPVklERVIpKQorICAgICAgICAudGhlblJldHVybihsb2NhdGlvbldpdGhvdXRBY2N1cmFjeSk7CisgICAgYXNzZXJ0VGhhdChsb2NhdGlvblByb3ZpZGVyLmdldCgpKS5pc0Fic2VudCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvclRlc3QuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTWFuaWZlc3RDb25maWdGbGFnUG9wdWxhdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFkNGE5YmUKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvclRlc3QuamF2YQpAQCAtMCwwICsxLDI4MyBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQucG9wdWxhdG9yOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnBvcHVsYXRvci5NYW5pZmVzdENvbmZpZ0hlbHBlci5VUkxfVEVNUExBVEVfQ0hFQ0tTVU1fUExBQ0VIT0xERVI7CitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CitpbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0VGhyb3dzOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Bcmd1bWVudE1hdGNoZXJzLmFueTsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by50aW1lczsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uTW9ja2l0by52ZXJpZnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8ud2hlbjsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLkFkZEZpbGVHcm91cFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuTW9iaWxlRGF0YURvd25sb2FkOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmJhc2UuT3B0aW9uYWw7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JdGVyYWJsZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50Lkxpc3RlbmFibGVGdXR1cmU7CitpbXBvcnQgY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuRG93bmxvYWRDb25maWdQcm90by5CYXNlRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRhdGFGaWxlOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uRGF0YUZpbGVHcm91cDsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRlbHRhRmlsZTsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLkRlbHRhRmlsZS5EaWZmRGVjb2RlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZENvbmZpZ1Byb3RvLk1hbmlmZXN0Q29uZmlnOworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uTWFuaWZlc3RDb25maWcuVXJsVGVtcGxhdGU7CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuUnVsZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLm1vY2tpdG8uQXJndW1lbnRDYXB0b3I7CitpbXBvcnQgb3JnLm1vY2tpdG8uQ2FwdG9yOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKKy8qKiBUZXN0cyBmb3Ige0BsaW5rIE1hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvcn0uICovCitAUnVuV2l0aChSb2JvbGVjdHJpY1Rlc3RSdW5uZXIuY2xhc3MpCitwdWJsaWMgY2xhc3MgTWFuaWZlc3RDb25maWdGbGFnUG9wdWxhdG9yVGVzdCB7CisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgQE1vY2sgTW9iaWxlRGF0YURvd25sb2FkIG1vY2tNb2JpbGVEYXRhRG93bmxvYWQ7CisgIEBDYXB0b3IgcHJpdmF0ZSBBcmd1bWVudENhcHRvcjxBZGRGaWxlR3JvdXBSZXF1ZXN0PiBhZGRGaWxlR3JvdXBSZXF1ZXN0Q2FwdG9yOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIERlbHRhRmlsZSBERUxUQV9GSUxFID0KKyAgICAgIERlbHRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAuc2V0RGlmZkRlY29kZXIoRGlmZkRlY29kZXIuVkNfRElGRikKKyAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaHR0cHM6Ly9zdGFuZGFyZC5maWxlLnVybCIpCisgICAgICAgICAgLnNldENoZWNrc3VtKCJzdGFuZGFyZERlbHRhRmlsZUNoZWNrc3VtIikKKyAgICAgICAgICAuc2V0QmFzZUZpbGUoQmFzZUZpbGUubmV3QnVpbGRlcigpLnNldENoZWNrc3VtKCJzdGFuZGFyZEJhc2VGaWxlQ2hlY2tzdW0iKS5idWlsZCgpKQorICAgICAgICAgIC5idWlsZCgpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIERhdGFGaWxlIERBVEFfRklMRSA9CisgICAgICBEYXRhRmlsZS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAuc2V0RmlsZUlkKCJzdGFuZGFyZC1maWxlIikKKyAgICAgICAgICAuc2V0VXJsVG9Eb3dubG9hZCgiaHR0cHM6Ly9zdGFuZGFyZC5maWxlLnVybCIpCisgICAgICAgICAgLnNldENoZWNrc3VtKCJzdGFuZGFyZEZpbGVDaGVja3N1bSIpCisgICAgICAgICAgLmFkZERlbHRhRmlsZShERUxUQV9GSUxFKQorICAgICAgICAgIC5idWlsZCgpOworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIERhdGFGaWxlR3JvdXAgREFUQV9GSUxFX0dST1VQID0KKyAgICAgIERhdGFGaWxlR3JvdXAubmV3QnVpbGRlcigpLnNldEdyb3VwTmFtZSgiZ3JvdXBOYW1lIikuc2V0T3duZXJQYWNrYWdlKCJvd25lclBhY2thZ2UiKS5idWlsZCgpOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB7CisgICAgd2hlbihtb2NrTW9iaWxlRGF0YURvd25sb2FkLmFkZEZpbGVHcm91cChhbnkoQWRkRmlsZUdyb3VwUmVxdWVzdC5jbGFzcykpKQorICAgICAgICAudGhlblJldHVybihGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZSh0cnVlKSk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCByZWZyZXNoRnJvbU1hbmlmZXN0Q29uZmlnX2Fic2VudE92ZXJyaWRlcigpCisgICAgICB0aHJvd3MgRXhlY3V0aW9uRXhjZXB0aW9uLCBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgTWFuaWZlc3RDb25maWcgbWFuaWZlc3RDb25maWcgPSBjcmVhdGVNYW5pZmVzdENvbmZpZygpOworCisgICAgTWFuaWZlc3RDb25maWdIZWxwZXIucmVmcmVzaEZyb21NYW5pZmVzdENvbmZpZygKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWQsIG1hbmlmZXN0Q29uZmlnLCAvKm92ZXJyaWRlck9wdGlvbmFsPSovIE9wdGlvbmFsLmFic2VudCgpKQorICAgICAgICAuZ2V0KCk7CisgICAgdmVyaWZ5KG1vY2tNb2JpbGVEYXRhRG93bmxvYWQsIHRpbWVzKDIpKS5hZGRGaWxlR3JvdXAoYWRkRmlsZUdyb3VwUmVxdWVzdENhcHRvci5jYXB0dXJlKCkpOworCisgICAgYXNzZXJ0VGhhdChhZGRGaWxlR3JvdXBSZXF1ZXN0Q2FwdG9yLmdldEFsbFZhbHVlcygpLmdldCgwKS5kYXRhRmlsZUdyb3VwKCkuZ2V0R3JvdXBOYW1lKCkpCisgICAgICAgIC5pc0VxdWFsVG8oImdyb3VwTmFtZUxvY2FsZUVuVVMiKTsKKyAgICBhc3NlcnRUaGF0KGFkZEZpbGVHcm91cFJlcXVlc3RDYXB0b3IuZ2V0QWxsVmFsdWVzKCkuZ2V0KDEpLmRhdGFGaWxlR3JvdXAoKS5nZXRHcm91cE5hbWUoKSkKKyAgICAgICAgLmlzRXF1YWxUbygiZ3JvdXBOYW1lTG9jYWxlRW5VSyIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVmcmVzaEZyb21NYW5pZmVzdENvbmZpZ193aXRoVXJsVGVtcGxhdGVfYWJzZW50T3ZlcnJpZGVyKCkKKyAgICAgIHRocm93cyBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICBNYW5pZmVzdENvbmZpZyBtYW5pZmVzdENvbmZpZ1dpdGhVcmxUZW1wbGF0ZSA9IGNyZWF0ZU1hbmlmZXN0Q29uZmlnV2l0aFVybFRlbXBsYXRlKCk7CisgICAgLy8gRmlsZSB1cmxfdG9fZG93bmxvYWQgcG9wdWxhdGVkIHVzaW5nIHVybCB0ZW1wbGF0ZXMuCisgICAgRGF0YUZpbGVHcm91cCBkYXRhRmlsZUdyb3VwMSA9CisgICAgICAgIERBVEFfRklMRV9HUk9VUC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgREFUQV9GSUxFLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKCJodHRwczovL3N0YW5kYXJkLmZpbGUudXJsL3N0YW5kYXJkRmlsZUNoZWNrc3VtIikKKyAgICAgICAgICAgICAgICAgICAgLnNldERlbHRhRmlsZSgKKyAgICAgICAgICAgICAgICAgICAgICAgIDAsCisgICAgICAgICAgICAgICAgICAgICAgICBERUxUQV9GSUxFLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJodHRwczovL3N0YW5kYXJkLmZpbGUudXJsL3N0YW5kYXJkRGVsdGFGaWxlQ2hlY2tzdW0iKSkpCisgICAgICAgICAgICAuYnVpbGQoKTsKKyAgICBEYXRhRmlsZUdyb3VwIGRhdGFGaWxlR3JvdXAyID0gREFUQV9GSUxFX0dST1VQLnRvQnVpbGRlcigpLmFkZEZpbGUoREFUQV9GSUxFKS5idWlsZCgpOworCisgICAgTWFuaWZlc3RDb25maWdIZWxwZXIucmVmcmVzaEZyb21NYW5pZmVzdENvbmZpZygKKyAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWQsCisgICAgICAgICAgICBtYW5pZmVzdENvbmZpZ1dpdGhVcmxUZW1wbGF0ZSwKKyAgICAgICAgICAgIC8qb3ZlcnJpZGVyT3B0aW9uYWw9Ki8gT3B0aW9uYWwuYWJzZW50KCkpCisgICAgICAgIC5nZXQoKTsKKyAgICB2ZXJpZnkobW9ja01vYmlsZURhdGFEb3dubG9hZCwgdGltZXMoMikpLmFkZEZpbGVHcm91cChhZGRGaWxlR3JvdXBSZXF1ZXN0Q2FwdG9yLmNhcHR1cmUoKSk7CisKKyAgICBMaXN0PEFkZEZpbGVHcm91cFJlcXVlc3Q+IGFkZEZpbGVHcm91cFJlcXVlc3RzID0gYWRkRmlsZUdyb3VwUmVxdWVzdENhcHRvci5nZXRBbGxWYWx1ZXMoKTsKKyAgICBhc3NlcnRUaGF0KEl0ZXJhYmxlcy50cmFuc2Zvcm0oYWRkRmlsZUdyb3VwUmVxdWVzdHMsIEFkZEZpbGVHcm91cFJlcXVlc3Q6OmRhdGFGaWxlR3JvdXApKQorICAgICAgICAuY29udGFpbnNFeGFjdGx5KGRhdGFGaWxlR3JvdXAxLCBkYXRhRmlsZUdyb3VwMikKKyAgICAgICAgLmluT3JkZXIoKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlZnJlc2hGcm9tTWFuaWZlc3RDb25maWdfbm9VcmxUZW1wbGF0ZV91cmxUb0Rvd25sb2FkRW1wdHlfYWJzZW50T3ZlcnJpZGVyKCkKKyAgICAgIHRocm93cyBFeGVjdXRpb25FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKKyAgICAvLyBGaWxlcyB3aXRoIG5vIHVybF90b19kb3dubG9hZCB3aWxsIGZhaWwgc2luY2UgdXJsIHRlbXBsYXRlIGlzIG5vdCBhdmFpbGFibGUuCisgICAgTWFuaWZlc3RDb25maWcgbWFuaWZlc3RDb25maWdXaXRob3V0VXJsVGVtcGxhdGUgPQorICAgICAgICBjcmVhdGVNYW5pZmVzdENvbmZpZ1dpdGhVcmxUZW1wbGF0ZSgpLnRvQnVpbGRlcigpLmNsZWFyVXJsVGVtcGxhdGUoKS5idWlsZCgpOworCisgICAgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiA9CisgICAgICAgIGFzc2VydFRocm93cygKKyAgICAgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywKKyAgICAgICAgICAgICgpIC0+CisgICAgICAgICAgICAgICAgTWFuaWZlc3RDb25maWdIZWxwZXIucmVmcmVzaEZyb21NYW5pZmVzdENvbmZpZygKKyAgICAgICAgICAgICAgICAgICAgICAgIG1vY2tNb2JpbGVEYXRhRG93bmxvYWQsCisgICAgICAgICAgICAgICAgICAgICAgICBtYW5pZmVzdENvbmZpZ1dpdGhvdXRVcmxUZW1wbGF0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qb3ZlcnJpZGVyT3B0aW9uYWw9Ki8gT3B0aW9uYWwuYWJzZW50KCkpCisgICAgICAgICAgICAgICAgICAgIC5nZXQoKSk7CisKKyAgICBhc3NlcnRUaGF0KGlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbikKKyAgICAgICAgLmhhc01lc3NhZ2VUaGF0KCkKKyAgICAgICAgLmlzRXF1YWxUbygiRGF0YUZpbGUgc3RhbmRhcmQtZmlsZSB1cmxfdG9fZG93bmxvYWQgaXMgbWlzc2luZy4iKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlZnJlc2hGcm9tTWFuaWZlc3RDb25maWdfaWRlbnRpdHlPdmVycmlkZXIoKQorICAgICAgdGhyb3dzIEV4ZWN1dGlvbkV4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgIE1hbmlmZXN0Q29uZmlnIG1hbmlmZXN0Q29uZmlnID0gY3JlYXRlTWFuaWZlc3RDb25maWcoKTsKKworICAgIC8vIFVzZSBhIE1hbmlmZXN0Q29uZmlnT3ZlcnJpZGVyIHRoYXQgZG9lcyBub3QgZmlsdGVyL2NoYW5nZSBhbnl0aGluZy4KKyAgICBNYW5pZmVzdENvbmZpZ092ZXJyaWRlciBvdmVycmlkZXIgPQorICAgICAgICBuZXcgTWFuaWZlc3RDb25maWdPdmVycmlkZXIoKSB7CisgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8TGlzdDxEYXRhRmlsZUdyb3VwPj4gb3ZlcnJpZGUoTWFuaWZlc3RDb25maWcgY29uZmlnKSB7CisgICAgICAgICAgICBMaXN0PERhdGFGaWxlR3JvdXA+IG92ZXJyaWRlclJlc3VsdHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgICAgIGZvciAoTWFuaWZlc3RDb25maWcuRW50cnkgZW50cnkgOiBjb25maWcuZ2V0RW50cnlMaXN0KCkpIHsKKyAgICAgICAgICAgICAgb3ZlcnJpZGVyUmVzdWx0cy5hZGQoZW50cnkuZ2V0RGF0YUZpbGVHcm91cCgpKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKG92ZXJyaWRlclJlc3VsdHMpOworICAgICAgICAgIH0KKyAgICAgICAgfTsKKworICAgIE1hbmlmZXN0Q29uZmlnSGVscGVyLnJlZnJlc2hGcm9tTWFuaWZlc3RDb25maWcoCisgICAgICAgICAgICBtb2NrTW9iaWxlRGF0YURvd25sb2FkLCBtYW5pZmVzdENvbmZpZywgT3B0aW9uYWwub2Yob3ZlcnJpZGVyKSkKKyAgICAgICAgLmdldCgpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkLCB0aW1lcygyKSkuYWRkRmlsZUdyb3VwKGFkZEZpbGVHcm91cFJlcXVlc3RDYXB0b3IuY2FwdHVyZSgpKTsKKworICAgIGFzc2VydFRoYXQoYWRkRmlsZUdyb3VwUmVxdWVzdENhcHRvci5nZXRBbGxWYWx1ZXMoKS5nZXQoMCkuZGF0YUZpbGVHcm91cCgpLmdldEdyb3VwTmFtZSgpKQorICAgICAgICAuaXNFcXVhbFRvKCJncm91cE5hbWVMb2NhbGVFblVTIik7CisgICAgYXNzZXJ0VGhhdChhZGRGaWxlR3JvdXBSZXF1ZXN0Q2FwdG9yLmdldEFsbFZhbHVlcygpLmdldCgxKS5kYXRhRmlsZUdyb3VwKCkuZ2V0R3JvdXBOYW1lKCkpCisgICAgICAgIC5pc0VxdWFsVG8oImdyb3VwTmFtZUxvY2FsZUVuVUsiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlZnJlc2hGcm9tTWFuaWZlc3RDb25maWdfZW5fVVNMb2NhbGVPdmVycmlkZXIoKQorICAgICAgdGhyb3dzIEV4ZWN1dGlvbkV4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgIE1hbmlmZXN0Q29uZmlnIG1hbmlmZXN0Q29uZmlnID0gY3JlYXRlTWFuaWZlc3RDb25maWcoKTsKKworICAgIC8vIFVzZSBhIE1hbmlmZXN0Q29uZmlnT3ZlcnJpZGVyIHRoYXQgb25seSBrZWVwcyBlbnRyeSB3aXRoIGxvY2FsZSBlbl9VUy4KKyAgICBNYW5pZmVzdENvbmZpZ092ZXJyaWRlciBvdmVycmlkZXIgPQorICAgICAgICBuZXcgTWFuaWZlc3RDb25maWdPdmVycmlkZXIoKSB7CisgICAgICAgICAgQE92ZXJyaWRlCisgICAgICAgICAgcHVibGljIExpc3RlbmFibGVGdXR1cmU8TGlzdDxEYXRhRmlsZUdyb3VwPj4gb3ZlcnJpZGUoTWFuaWZlc3RDb25maWcgY29uZmlnKSB7CisgICAgICAgICAgICBMaXN0PERhdGFGaWxlR3JvdXA+IG92ZXJyaWRlclJlc3VsdHMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgICAgICAgIGZvciAoTWFuaWZlc3RDb25maWcuRW50cnkgZW50cnkgOiBjb25maWcuZ2V0RW50cnlMaXN0KCkpIHsKKyAgICAgICAgICAgICAgaWYgKCJlbl9VUyIuZXF1YWxzKGVudHJ5LmdldE1vZGlmaWVyKCkuZ2V0TG9jYWxlTGlzdCgpLmdldCgwKSkpIHsKKyAgICAgICAgICAgICAgICBvdmVycmlkZXJSZXN1bHRzLmFkZChlbnRyeS5nZXREYXRhRmlsZUdyb3VwKCkpOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBGdXR1cmVzLmltbWVkaWF0ZUZ1dHVyZShvdmVycmlkZXJSZXN1bHRzKTsKKyAgICAgICAgICB9CisgICAgICAgIH07CisKKyAgICBNYW5pZmVzdENvbmZpZ0hlbHBlci5yZWZyZXNoRnJvbU1hbmlmZXN0Q29uZmlnKAorICAgICAgICAgICAgbW9ja01vYmlsZURhdGFEb3dubG9hZCwgbWFuaWZlc3RDb25maWcsIE9wdGlvbmFsLm9mKG92ZXJyaWRlcikpCisgICAgICAgIC5nZXQoKTsKKyAgICB2ZXJpZnkobW9ja01vYmlsZURhdGFEb3dubG9hZCwgdGltZXMoMSkpLmFkZEZpbGVHcm91cChhZGRGaWxlR3JvdXBSZXF1ZXN0Q2FwdG9yLmNhcHR1cmUoKSk7CisKKyAgICBhc3NlcnRUaGF0KGFkZEZpbGVHcm91cFJlcXVlc3RDYXB0b3IuZ2V0QWxsVmFsdWVzKCkuZ2V0KDApLmRhdGFGaWxlR3JvdXAoKS5nZXRHcm91cE5hbWUoKSkKKyAgICAgICAgLmlzRXF1YWxUbygiZ3JvdXBOYW1lTG9jYWxlRW5VUyIpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVmcmVzaEZpbGVHcm91cHNfdXNlc1N1cHBsaWVyKCkgdGhyb3dzIEV4ZWN1dGlvbkV4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24geworICAgIE1hbmlmZXN0Q29uZmlnIG1hbmlmZXN0Q29uZmlnID0gY3JlYXRlTWFuaWZlc3RDb25maWcoKTsKKworICAgIE1hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvciBwb3B1bGF0b3IgPQorICAgICAgICBNYW5pZmVzdENvbmZpZ0ZsYWdQb3B1bGF0b3IuYnVpbGRlcigpCisgICAgICAgICAgICAuc2V0TWFuaWZlc3RDb25maWdTdXBwbGllcigoKSAtPiBtYW5pZmVzdENvbmZpZykKKyAgICAgICAgICAgIC5idWlsZCgpOworCisgICAgcG9wdWxhdG9yLnJlZnJlc2hGaWxlR3JvdXBzKG1vY2tNb2JpbGVEYXRhRG93bmxvYWQpLmdldCgpOworICAgIHZlcmlmeShtb2NrTW9iaWxlRGF0YURvd25sb2FkLCB0aW1lcygyKSkuYWRkRmlsZUdyb3VwKGFkZEZpbGVHcm91cFJlcXVlc3RDYXB0b3IuY2FwdHVyZSgpKTsKKworICAgIGFzc2VydFRoYXQoYWRkRmlsZUdyb3VwUmVxdWVzdENhcHRvci5nZXRBbGxWYWx1ZXMoKS5nZXQoMCkuZGF0YUZpbGVHcm91cCgpLmdldEdyb3VwTmFtZSgpKQorICAgICAgICAuaXNFcXVhbFRvKCJncm91cE5hbWVMb2NhbGVFblVTIik7CisgICAgYXNzZXJ0VGhhdChhZGRGaWxlR3JvdXBSZXF1ZXN0Q2FwdG9yLmdldEFsbFZhbHVlcygpLmdldCgxKS5kYXRhRmlsZUdyb3VwKCkuZ2V0R3JvdXBOYW1lKCkpCisgICAgICAgIC5pc0VxdWFsVG8oImdyb3VwTmFtZUxvY2FsZUVuVUsiKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIG1hbmlmZXN0Q29uZmlnRmxhZ1BvcHVsYXRvckJ1aWxkZXJfcmVqZWN0c05vdEJvdGhQYWNrYWdlQW5kRmxhZygpIHsKKyAgICBhc3NlcnRUaHJvd3MoCisgICAgICAgIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbi5jbGFzcywgKCkgLT4gTWFuaWZlc3RDb25maWdGbGFnUG9wdWxhdG9yLmJ1aWxkZXIoKS5idWlsZCgpKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIE1hbmlmZXN0Q29uZmlnIGNyZWF0ZU1hbmlmZXN0Q29uZmlnKCkgeworICAgIC8vIENyZWF0ZSBhIE1hbmlmZXN0Q29uZmlnIHdpdGggMiBlbnRyaWVzIGZvciBsb2NhbGUgZW5fVVMgYW5kIGVuX1VLLgorICAgIE1hbmlmZXN0Q29uZmlnLkVudHJ5IGVudHJ5VXMgPQorICAgICAgICBNYW5pZmVzdENvbmZpZy5FbnRyeS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRNb2RpZmllcihNYW5pZmVzdENvbmZpZy5FbnRyeS5Nb2RpZmllci5uZXdCdWlsZGVyKCkuYWRkTG9jYWxlKCJlbl9VUyIpLmJ1aWxkKCkpCisgICAgICAgICAgICAuc2V0RGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKCJncm91cE5hbWVMb2NhbGVFblVTIikKKyAgICAgICAgICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZSgib3duZXJQYWNrYWdlIikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIE1hbmlmZXN0Q29uZmlnLkVudHJ5IGVudHJ5VWsgPQorICAgICAgICBNYW5pZmVzdENvbmZpZy5FbnRyeS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRNb2RpZmllcihNYW5pZmVzdENvbmZpZy5FbnRyeS5Nb2RpZmllci5uZXdCdWlsZGVyKCkuYWRkTG9jYWxlKCJlbl9VSyIpLmJ1aWxkKCkpCisgICAgICAgICAgICAuc2V0RGF0YUZpbGVHcm91cCgKKyAgICAgICAgICAgICAgICBEYXRhRmlsZUdyb3VwLm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgICAgICAgICAuc2V0R3JvdXBOYW1lKCJncm91cE5hbWVMb2NhbGVFblVLIikKKyAgICAgICAgICAgICAgICAgICAgLnNldE93bmVyUGFja2FnZSgib3duZXJQYWNrYWdlIikpCisgICAgICAgICAgICAuYnVpbGQoKTsKKworICAgIHJldHVybiBNYW5pZmVzdENvbmZpZy5uZXdCdWlsZGVyKCkuYWRkRW50cnkoZW50cnlVcykuYWRkRW50cnkoZW50cnlVaykuYnVpbGQoKTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIE1hbmlmZXN0Q29uZmlnIGNyZWF0ZU1hbmlmZXN0Q29uZmlnV2l0aFVybFRlbXBsYXRlKCkgeworICAgIERhdGFGaWxlR3JvdXAgZGF0YUZpbGVHcm91cFdpdGhvdXRVcmxEb3dubG9hZCA9CisgICAgICAgIERBVEFfRklMRV9HUk9VUC50b0J1aWxkZXIoKQorICAgICAgICAgICAgLmFkZEZpbGUoCisgICAgICAgICAgICAgICAgREFUQV9GSUxFLnRvQnVpbGRlcigpCisgICAgICAgICAgICAgICAgICAgIC5jbGVhclVybFRvRG93bmxvYWQoKQorICAgICAgICAgICAgICAgICAgICAuc2V0RGVsdGFGaWxlKDAsIERFTFRBX0ZJTEUudG9CdWlsZGVyKCkuY2xlYXJVcmxUb0Rvd25sb2FkKCkpKQorICAgICAgICAgICAgLmJ1aWxkKCk7CisgICAgRGF0YUZpbGVHcm91cCBkYXRhRmlsZUdyb3VwMiA9IERBVEFfRklMRV9HUk9VUC50b0J1aWxkZXIoKS5hZGRGaWxlKERBVEFfRklMRSkuYnVpbGQoKTsKKworICAgIHJldHVybiBNYW5pZmVzdENvbmZpZy5uZXdCdWlsZGVyKCkKKyAgICAgICAgLnNldFVybFRlbXBsYXRlKAorICAgICAgICAgICAgVXJsVGVtcGxhdGUubmV3QnVpbGRlcigpCisgICAgICAgICAgICAgICAgLnNldEZpbGVVcmxUZW1wbGF0ZSgKKyAgICAgICAgICAgICAgICAgICAgImh0dHBzOi8vc3RhbmRhcmQuZmlsZS51cmwvIiArIFVSTF9URU1QTEFURV9DSEVDS1NVTV9QTEFDRUhPTERFUikKKyAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgLmFkZEVudHJ5KAorICAgICAgICAgICAgTWFuaWZlc3RDb25maWcuRW50cnkubmV3QnVpbGRlcigpLnNldERhdGFGaWxlR3JvdXAoZGF0YUZpbGVHcm91cFdpdGhvdXRVcmxEb3dubG9hZCkpCisgICAgICAgIC5hZGRFbnRyeShNYW5pZmVzdENvbmZpZy5FbnRyeS5uZXdCdWlsZGVyKCkuc2V0RGF0YUZpbGVHcm91cChkYXRhRmlsZUdyb3VwMikpCisgICAgICAgIC5idWlsZCgpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyVGVzdC5qYXZhIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9NaWdyYXRpb25Qcm94eUxvY2FsZU92ZXJyaWRlclRlc3QuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYTk2YjY1Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3BvcHVsYXRvci9NaWdyYXRpb25Qcm94eUxvY2FsZU92ZXJyaWRlclRlc3QuamF2YQpAQCAtMCwwICsxLDY0IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5wb3B1bGF0b3I7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udHJ1dGguVHJ1dGguYXNzZXJ0VGhhdDsKKworaW1wb3J0IGNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkLkRvd25sb2FkQ29uZmlnUHJvdG8uTWFuaWZlc3RDb25maWc7CitpbXBvcnQgamF2YS51dGlsLkxvY2FsZTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRpb25FeGNlcHRpb247CitpbXBvcnQgb3JnLmp1bml0LkJlZm9yZTsKK2ltcG9ydCBvcmcuanVuaXQuVGVzdDsKK2ltcG9ydCBvcmcuanVuaXQucnVubmVyLlJ1bldpdGg7CitpbXBvcnQgb3JnLnJvYm9sZWN0cmljLlJvYm9sZWN0cmljVGVzdFJ1bm5lcjsKKworLyoqIFRlc3RzIGZvciB7QGxpbmsgTWlncmF0aW9uUHJveHlMb2NhbGVPdmVycmlkZXJ9LiAqLworQFJ1bldpdGgoUm9ib2xlY3RyaWNUZXN0UnVubmVyLmNsYXNzKQorcHVibGljIGNsYXNzIE1pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyVGVzdCB7CisKKyAgcHJpdmF0ZSBMb2NhbGVPdmVycmlkZXIgbG9jYWxlT3ZlcnJpZGVyOworICBwcml2YXRlIE1hbmlmZXN0Q29uZmlnIG1hbmlmZXN0Q29uZmlnOworCisgIEBCZWZvcmUKKyAgcHVibGljIHZvaWQgc2V0VXAoKSB7CisgICAgbWFuaWZlc3RDb25maWcgPQorICAgICAgICBNYW5pZmVzdENvbmZpZy5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgIC5hZGRFbnRyeSgKKyAgICAgICAgICAgICAgICBNYW5pZmVzdENvbmZpZy5FbnRyeS5uZXdCdWlsZGVyKCkKKyAgICAgICAgICAgICAgICAgICAgLnNldE1vZGlmaWVyKAorICAgICAgICAgICAgICAgICAgICAgICAgTWFuaWZlc3RDb25maWcuRW50cnkuTW9kaWZpZXIubmV3QnVpbGRlcigpLmFkZExvY2FsZSgiZW4tVVMiKS5idWlsZCgpKQorICAgICAgICAgICAgICAgICAgICAuYnVpbGQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpOworICAgIGxvY2FsZU92ZXJyaWRlciA9CisgICAgICAgIExvY2FsZU92ZXJyaWRlci5idWlsZGVyKCkuc2V0TG9jYWxlU3VwcGxpZXIoKCkgLT4gTG9jYWxlLmZvckxhbmd1YWdlVGFnKCJlbi1VUyIpKS5idWlsZCgpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgb3ZlcnJpZGVfd2hlbkZsYWdSZXR1cm5zRmFsc2VfcmV0dXJuc05vdGhpbmcoKQorICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24geworICAgIE1pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyIG1pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyID0KKyAgICAgICAgbmV3IE1pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyKGxvY2FsZU92ZXJyaWRlciwgKCkgLT4gZmFsc2UpOworICAgIGFzc2VydFRoYXQobWlncmF0aW9uUHJveHlMb2NhbGVPdmVycmlkZXIub3ZlcnJpZGUobWFuaWZlc3RDb25maWcpLmdldCgpKS5pc0VtcHR5KCk7CisgIH0KKworICBAVGVzdAorICBwdWJsaWMgdm9pZCBvdmVycmlkZV93aGVuRmxhZ1JldHVybnNUcnVlX3VzZXNMb2NhbGVPdmVycmlkZXIoKQorICAgICAgdGhyb3dzIEludGVycnVwdGVkRXhjZXB0aW9uLCBFeGVjdXRpb25FeGNlcHRpb24geworICAgIE1pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyIG1pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyID0KKyAgICAgICAgbmV3IE1pZ3JhdGlvblByb3h5TG9jYWxlT3ZlcnJpZGVyKGxvY2FsZU92ZXJyaWRlciwgKCkgLT4gdHJ1ZSk7CisgICAgYXNzZXJ0VGhhdChtaWdyYXRpb25Qcm94eUxvY2FsZU92ZXJyaWRlci5vdmVycmlkZShtYW5pZmVzdENvbmZpZykuZ2V0KCkpLmhhc1NpemUoMSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9wb3B1bGF0b3IvTWlncmF0aW9uUHJveHlQb3B1bGF0b3JUZXN0LmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01pZ3JhdGlvblByb3h5UG9wdWxhdG9yVGVzdC5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1MzI3ZTkKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvcG9wdWxhdG9yL01pZ3JhdGlvblByb3h5UG9wdWxhdG9yVGVzdC5qYXZhCkBAIC0wLDAgKzEsNzUgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnBvcHVsYXRvcjsKKworaW1wb3J0IHN0YXRpYyBjb20uZ29vZ2xlLmNvbW1vbi5sYWJzLnRydXRoLkZ1dHVyZVN1YmplY3QuYXNzZXJ0VGhhdDsKK2ltcG9ydCBzdGF0aWMgb3JnLm1vY2tpdG8uQXJndW1lbnRNYXRjaGVycy5hbnk7CitpbXBvcnQgc3RhdGljIG9yZy5tb2NraXRvLk1vY2tpdG8udmVyaWZ5OworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLnZlcmlmeU5vSW50ZXJhY3Rpb25zOworaW1wb3J0IHN0YXRpYyBvcmcubW9ja2l0by5Nb2NraXRvLndoZW47CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GaWxlR3JvdXBQb3B1bGF0b3I7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuTW9iaWxlRGF0YURvd25sb2FkOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzOworaW1wb3J0IG9yZy5qdW5pdC5CZWZvcmU7CitpbXBvcnQgb3JnLmp1bml0LlJ1bGU7CitpbXBvcnQgb3JnLmp1bml0LlRlc3Q7CitpbXBvcnQgb3JnLmp1bml0LnJ1bm5lci5SdW5XaXRoOworaW1wb3J0IG9yZy5tb2NraXRvLk1vY2s7CitpbXBvcnQgb3JnLm1vY2tpdG8uanVuaXQuTW9ja2l0b0pVbml0OworaW1wb3J0IG9yZy5tb2NraXRvLmp1bml0Lk1vY2tpdG9SdWxlOworaW1wb3J0IG9yZy5yb2JvbGVjdHJpYy5Sb2JvbGVjdHJpY1Rlc3RSdW5uZXI7CisKKy8qKiBUZXN0cyBmb3Ige0BsaW5rIE1pZ3JhdGlvblByb3h5UG9wdWxhdG9yfS4gKi8KK0BSdW5XaXRoKFJvYm9sZWN0cmljVGVzdFJ1bm5lci5jbGFzcykKK3B1YmxpYyBjbGFzcyBNaWdyYXRpb25Qcm94eVBvcHVsYXRvclRlc3QgeworCisgIEBSdWxlIHB1YmxpYyBmaW5hbCBNb2NraXRvUnVsZSBtb2NrcyA9IE1vY2tpdG9KVW5pdC5ydWxlKCk7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVm9pZCBWT0lEID0gbnVsbDsKKworICBATW9jayBwcml2YXRlIEZpbGVHcm91cFBvcHVsYXRvciBjb250cm9sUG9wdWxhdG9yOworICBATW9jayBwcml2YXRlIEZpbGVHcm91cFBvcHVsYXRvciBleHBlcmltZW50UG9wdWxhdG9yOworICBATW9jayBwcml2YXRlIE1vYmlsZURhdGFEb3dubG9hZCBtb2JpbGVEYXRhRG93bmxvYWQ7CisKKyAgQEJlZm9yZQorICBwdWJsaWMgdm9pZCBzZXRVcCgpIHsKKyAgICB3aGVuKGNvbnRyb2xQb3B1bGF0b3IucmVmcmVzaEZpbGVHcm91cHMoYW55KCkpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKFZPSUQpKTsKKyAgICB3aGVuKGV4cGVyaW1lbnRQb3B1bGF0b3IucmVmcmVzaEZpbGVHcm91cHMoYW55KCkpKS50aGVuUmV0dXJuKEZ1dHVyZXMuaW1tZWRpYXRlRnV0dXJlKFZPSUQpKTsKKyAgfQorCisgIEBUZXN0CisgIHB1YmxpYyB2b2lkIHJlZnJlc2hGaWxlR3JvdXBzX3doZW5GbGFnUmV0dXJuc0ZhbHNlX3VzZXNDb250cm9sUG9wdWxhdG9yKCkgeworICAgIE1pZ3JhdGlvblByb3h5UG9wdWxhdG9yIG1pZ3JhdGlvblByb3h5UG9wdWxhdG9yID0KKyAgICAgICAgbmV3IE1pZ3JhdGlvblByb3h5UG9wdWxhdG9yKGNvbnRyb2xQb3B1bGF0b3IsIGV4cGVyaW1lbnRQb3B1bGF0b3IsICgpIC0+IGZhbHNlKTsKKyAgICBhc3NlcnRUaGF0KG1pZ3JhdGlvblByb3h5UG9wdWxhdG9yLnJlZnJlc2hGaWxlR3JvdXBzKG1vYmlsZURhdGFEb3dubG9hZCkpCisgICAgICAgIC53aGVuRG9uZSgpCisgICAgICAgIC5pc1N1Y2Nlc3NmdWwoKTsKKyAgICB2ZXJpZnkoY29udHJvbFBvcHVsYXRvcikucmVmcmVzaEZpbGVHcm91cHMoYW55KCkpOworICAgIHZlcmlmeU5vSW50ZXJhY3Rpb25zKGV4cGVyaW1lbnRQb3B1bGF0b3IpOworICB9CisKKyAgQFRlc3QKKyAgcHVibGljIHZvaWQgcmVmcmVzaEZpbGVHcm91cHNfd2hlbkZsYWdSZXR1cm5zVHJ1ZV91c2VzRXhwZXJpbWVudFBvcHVsYXRvcigpIHsKKyAgICBNaWdyYXRpb25Qcm94eVBvcHVsYXRvciBtaWdyYXRpb25Qcm94eVBvcHVsYXRvciA9CisgICAgICAgIG5ldyBNaWdyYXRpb25Qcm94eVBvcHVsYXRvcihjb250cm9sUG9wdWxhdG9yLCBleHBlcmltZW50UG9wdWxhdG9yLCAoKSAtPiB0cnVlKTsKKyAgICBhc3NlcnRUaGF0KG1pZ3JhdGlvblByb3h5UG9wdWxhdG9yLnJlZnJlc2hGaWxlR3JvdXBzKG1vYmlsZURhdGFEb3dubG9hZCkpCisgICAgICAgIC53aGVuRG9uZSgpCisgICAgICAgIC5pc1N1Y2Nlc3NmdWwoKTsKKyAgICB2ZXJpZnlOb0ludGVyYWN0aW9ucyhjb250cm9sUG9wdWxhdG9yKTsKKyAgICB2ZXJpZnkoZXhwZXJpbWVudFBvcHVsYXRvcikucmVmcmVzaEZpbGVHcm91cHMoYW55KCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdF9kZWZzLmJ6bCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0X2RlZnMuYnpsCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk2NDc1NmQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdF9kZWZzLmJ6bApAQCAtMCwwICsxLDE1OCBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorIiIiQ29tbW9uIG1ldGhvZHMgdG8gZ2VuZXJhdGUgdGVzdCBzdWl0ZXMuIiIiCisKK2xvYWQoIi8vZGV2dG9vbHMvZGVwcy9jaGVjazpkZXBzX2NoZWNrLmJ6bCIsICJjaGVja19kZXBlbmRlbmNpZXMiKQorbG9hZCgKKyAgICAiQGJ1aWxkX2JhemVsX3J1bGVzX2FuZHJvaWQvL2FuZHJvaWQ6cnVsZXMuYnpsIiwKKyAgICAiYW5kcm9pZF9hcHBsaWNhdGlvbl90ZXN0IiwKKyAgICAiYW5kcm9pZF9sb2NhbF90ZXN0IiwKKyAgICAiaW5mZXJfdGVzdF9jbGFzc19mcm9tX3NyY3MiLAorKQorbG9hZCgiLy9kZXZ0b29scy9idWlsZF9jbGVhbmVyL3NreWxhcms6YnVpbGRfZGVmcy5iemwiLCAicmVnaXN0ZXJfZXh0ZW5zaW9uX2luZm8iKQorCitfTUFOSUZFU1RfVkFMVUVTID0geworICAgICJtaW5TZGtWZXJzaW9uIjogIjE2IiwKKyAgICAidGFyZ2V0U2RrVmVyc2lvbiI6ICIyOSIsCit9CisKK2RlZiBtZGRfbG9jYWxfdGVzdChuYW1lLCBkZXBzLCBtYW5pZmVzdF92YWx1ZXMgPSBfTUFOSUZFU1RfVkFMVUVTLCAqKmt3YXJncyk6CisgICAgIiIiR2VuZXJhdGUgMiBmbGF2b3JzIGZvciBhbmRyb2lkX2xvY2FsX3Rlc3QsIHdpdGggZGVmYXVsdCBiZWhhdmlvciBhbmQgd2l0aCBhbGwgZmxhZ3Mgb24uCisKKyAgICBUaGUgYWxsIG9uIHRlc3Rpbmcgb25seSB3b3JrcyBhcyBleHBlY3RlZCBpZiB0aGUgdGVzdCBpbmNsdWRlcyBmbGFncnVsZS9GbGFnUnVsZSBhcyBhIHJ1bGUgaW4KKyAgICB0aGUgdGVzdC4KKworICAgIEFyZ3M6CisgICAgICBuYW1lOiB0aGUgdGVzdCBuYW1lCisgICAgICBkZXBzOiBhIGxpc3Qgb2YgZGVwcworICAgICAgbWFuaWZlc3RfdmFsdWVzOiBtYW5pZmVzdCB2YWx1ZXMgdG8gdXNlLgorICAgICAgKiprd2FyZ3M6IEFueSBvdGhlciBwYXJhbSB0aGF0IGlzIHN1cHBvcnRlZCBieSA8aW50ZXJuYWw+LgorICAgICIiIgorCisgICAgYW5kcm9pZF9sb2NhbF90ZXN0KAorICAgICAgICBuYW1lID0gbmFtZSwKKyAgICAgICAgZGVwcyA9IGRlcHMsCisgICAgICAgIG1hbmlmZXN0X3ZhbHVlcyA9IG1hbmlmZXN0X3ZhbHVlcywKKyAgICAgICAgKiprd2FyZ3MKKyAgICApCisKKyMgU2VlIDxpbnRlcm5hbD4KK3JlZ2lzdGVyX2V4dGVuc2lvbl9pbmZvKAorICAgIGV4dGVuc2lvbiA9IG1kZF9sb2NhbF90ZXN0LAorICAgIGxhYmVsX3JlZ2V4X2Zvcl9kZXAgPSAiKGFsbF9vbl8pP3tleHRlbnNpb25fbmFtZX0iLAorKQorCisjIFJ1biBtZGRfYW5kcm9pZF90ZXN0IG9uIGFuIGFzc29ydG1lbnQgb2YgZW11bGF0b3JzLgorIyBUaGUgbGFzdCBpdGVtIGluIHRoZSBsaXN0IHdpbGwgYmUgdXNlZCBhcyB0aGUgZGVmYXVsdC4KK19FTVVMQVRPUl9JTUFHRVMgPSBbCisgICAgIyBBdXRvbW90aXZlCisgICAgIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2F1dG9tb3RpdmU6YXV0b18yOV94ODYiLAorCisgICAgIyBBbmRyb2lkIFBob25lCisgICAgIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2dlbmVyaWNfcGhvbmU6Z29vZ2xlXzIxX3g4Nl9nbXNfc3RhYmxlIiwKKyAgICAiLy90b29scy9hbmRyb2lkL2VtdWxhdGVkX2RldmljZXMvZ2VuZXJpY19waG9uZTpnb29nbGVfMjJfeDg2X2dtc19zdGFibGUiLAorICAgICIvL3Rvb2xzL2FuZHJvaWQvZW11bGF0ZWRfZGV2aWNlcy9nZW5lcmljX3Bob25lOmdvb2dsZV8yM194ODZfZ21zX3N0YWJsZSIsCisgICAgIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2dlbmVyaWNfcGhvbmU6Z29vZ2xlXzI0X3g4Nl9nbXNfc3RhYmxlIiwKKyAgICAiLy90b29scy9hbmRyb2lkL2VtdWxhdGVkX2RldmljZXMvZ2VuZXJpY19waG9uZTpnb29nbGVfMjVfeDg2X2dtc19zdGFibGUiLAorICAgICIvL3Rvb2xzL2FuZHJvaWQvZW11bGF0ZWRfZGV2aWNlcy9nZW5lcmljX3Bob25lOmdvb2dsZV8yNl94ODZfZ21zX3N0YWJsZSIsCisgICAgIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzL2dlbmVyaWNfcGhvbmU6Z29vZ2xlXzI3X3g4Nl9nbXNfc3RhYmxlIiwKKyAgICAiLy90b29scy9hbmRyb2lkL2VtdWxhdGVkX2RldmljZXMvZ2VuZXJpY19waG9uZTpnb29nbGVfMjhfeDg2X2dtc19zdGFibGUiLAorXQorCisjIExvZ2NhdCBmaWx0ZXIgZmxhZ3MuCitfQ09NTU9OX0xPR0NBVF9BUkdTID0gWworICAgICItLXRlc3RfbG9nY2F0X2ZpbHRlcj0nTUREOlYsTW9iaWxlRGF0YURvd25sb2FkOlYnIiwKK10KKworIyBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgYGFuZHJvaWRfYXBwbGljYXRpb25fdGVzdGAgd2lsbCBtZXJnZSB0aGUgcmVzb3VyY2VzIGluIGl0cyBkZXBlbmRlbmNpZXMgaW50byB0aGUKKyMgdGVzdCBiaW5hcnksIGp1c3QgbGlrZSBhbiBgYW5kcm9pZF9iaW5hcnlgIHJ1bGUgZG9lcy4KKyMgVGhpcyBpcyBhIHdvcmthcm91bmQgZm9yIGIvMTExMDYxNDU2LgorX0VNUFRZX0xPQ0FMX1JFU09VUkNFX0ZJTEVTID0gW10KKworIyBXcmFwcGVyIGFyb3VuZCBhbmRyb2lkX2FwcGxpY2F0aW9uX3Rlc3QgdG8gZ2VuZXJhdGUgdGFyZ2V0cyBmb3IgbXVsdGlwbGUgZW11bGF0b3IgaW1hZ2VzLgorZGVmIG1kZF9hbmRyb2lkX3Rlc3QobmFtZSwgdGFyZ2V0X2RldmljZXMgPSBfRU1VTEFUT1JfSU1BR0VTLCAqKmt3YXJncyk6CisgICAgIiIiR2VuZXJhdGUgYW4gYW5kcm9pZF9hcHBsaWNhdGlvbl90ZXN0IGZvciBNREQuCisKKyAgICBBcmdzOgorICAgICAgbmFtZTogdGhlIHRlc3QgbmFtZQorICAgICAgdGFyZ2V0X2RldmljZXM6IG9uZSBvciBtb3JlIGVtdWxhdG9ycyB0byBydW4gdGhlIHRlc3Qgb24uCisgICAgICAgIFRoZSBkZWZhdWx0IHRlc3QgbmFtZSB3aWxsIHJ1biBvbiB0aGUgbGFzdCBlbXVsYXRvciBwcm92aWRlZC4KKyAgICAgICAgSWYgYWRkaXRpb25hbCBlbXVsYXRvcnMgYXJlIGxpc3RlZCwgYWRkaXRpb25hbCB0ZXN0IHRhcmdldHMgd2lsbCBiZQorICAgICAgICBjcmVhdGVkIGJ5IGFwcGVuZGluZyB0aGUgZW11bGF0b3IgbmFtZSB0byB0aGUgb3JpZ2luYWwgdGVzdCBuYW1lCisgICAgICAqKmt3YXJnczogQW55IGtleXdvcmQgYXJndW1lbnRzIHRvIGJlIHBhc3NlZC4KKworICAgIFJldHVybnM6CisgICAgICBlYWNoIGFuZHJvaWRfYXBwbGljYXRpb25fdGVzdCBwZXIgZW11bGF0b3IgaW1hZ2UuCisgICAgIiIiCisKKyAgICBkZXBzID0ga3dhcmdzLnBvcCgiZGVwcyIsIFtdKQorICAgIG11bHRpZGV4ID0ga3dhcmdzLnBvcCgibXVsdGlkZXgiLCAibmF0aXZlIikKKyAgICBzcmNzID0ga3dhcmdzLnBvcCgic3JjcyIsIFtdKQorICAgIHRlc3RfY2xhc3MgPSBrd2FyZ3MucG9wKCJ0ZXN0X2NsYXNzIiwgaW5mZXJfdGVzdF9jbGFzc19mcm9tX3NyY3MobmFtZSwgc3JjcykpCisKKyAgICAjIGNyZWF0ZSBhIEJVSUxEIHRhcmdldCBmb3IgdGhlIGxhc3QgZWxlbWVudCBvZiB0YXJnZXRfZGV2aWNlcywgd2l0aCB0aGUgYmFzaWMgdGVzdCBuYW1lCisgICAgdGFyZ2V0X2RldmljZSA9IHRhcmdldF9kZXZpY2VzWy0xXQorICAgIGFuZHJvaWRfYXBwbGljYXRpb25fdGVzdCgKKyAgICAgICAgbmFtZSA9IG5hbWUsCisgICAgICAgIHNyY3MgPSBzcmNzLAorICAgICAgICBkZXBzID0gZGVwcywKKyAgICAgICAgbXVsdGlkZXggPSBtdWx0aWRleCwKKyAgICAgICAgbG9jYWxfcmVzb3VyY2VfZmlsZXMgPSBfRU1QVFlfTE9DQUxfUkVTT1VSQ0VfRklMRVMsCisgICAgICAgIGFyZ3MgPSBfQ09NTU9OX0xPR0NBVF9BUkdTLAorICAgICAgICB0YXJnZXRfZGV2aWNlcyA9IFt0YXJnZXRfZGV2aWNlXSwKKyAgICAgICAgdGVzdF9jbGFzcyA9IHRlc3RfY2xhc3MsCisgICAgICAgICoqa3dhcmdzCisgICAgKQorCisgICAgIyBpZiB0aGVyZSBhcmUgbXVsdGlwbGUgdGFyZ2V0X2RldmljZXMsIGNyZWF0ZSBuYW1lZCBCVUlMRCB0YXJnZXRzIGZvciBhbGwgdGhlIG90aGVyIG9uZXMgZXhjZXB0CisgICAgIyB0aGUgbGFzdCBvbmUuCisgICAgaWYgbGVuKHRhcmdldF9kZXZpY2VzKSA+IDE6CisgICAgICAgIGZvciB0YXJnZXRfZGV2aWNlIGluIHRhcmdldF9kZXZpY2VzWzotMV06CisgICAgICAgICAgICB0YXJnZXRfZGV2aWNlX25hbWUgPSB0YXJnZXRfZGV2aWNlLnJlcGxhY2UoIi8vdG9vbHMvYW5kcm9pZC9lbXVsYXRlZF9kZXZpY2VzLyIsICIiKS5yZXBsYWNlKCI6IiwgIl8iKQorICAgICAgICAgICAgYW5kcm9pZF9hcHBsaWNhdGlvbl90ZXN0KAorICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lICsgIl8iICsgdGFyZ2V0X2RldmljZV9uYW1lLAorICAgICAgICAgICAgICAgIHNyY3MgPSBzcmNzLAorICAgICAgICAgICAgICAgIGRlcHMgPSBkZXBzLAorICAgICAgICAgICAgICAgIG11bHRpZGV4ID0gbXVsdGlkZXgsCisgICAgICAgICAgICAgICAgbG9jYWxfcmVzb3VyY2VfZmlsZXMgPSBfRU1QVFlfTE9DQUxfUkVTT1VSQ0VfRklMRVMsCisgICAgICAgICAgICAgICAgYXJncyA9IF9DT01NT05fTE9HQ0FUX0FSR1MsCisgICAgICAgICAgICAgICAgdGFyZ2V0X2RldmljZXMgPSBbdGFyZ2V0X2RldmljZV0sCisgICAgICAgICAgICAgICAgdGVzdF9jbGFzcyA9IHRlc3RfY2xhc3MsCisgICAgICAgICAgICAgICAgKiprd2FyZ3MKKyAgICAgICAgICAgICkKKworIyBXcmFwcGVyIGFyb3VuZCBjaGVja19kZXBlbmRlbmNpZXMuCitkZWYgZGVwZW5kZW5jaWVzX3Rlc3QobmFtZSwgYWxsb3dsaXN0ID0gW10sICoqa3dhcmdzKToKKyAgICAiIiJHZW5lcmF0ZSBhIGRlcGVuZGVuY2llc190ZXN0IGZvciBNREQuCisKKyAgICBBcmdzOgorICAgICAgbmFtZTogVGhlIHRlc3QgbmFtZS4KKyAgICAgIGFsbG93bGlzdDogVGhlIGV4Y2x1ZGVkIHRhcmdldHMgdW5kZXIgdGhlIHBhY2thZ2UuCisgICAgICAqKmt3YXJnczogQW55IGtleXdvcmQgYXJndW1lbnRzIHRvIGJlIHBhc3NlZC4KKyAgICAiIiIKKyAgICBhbGxfYnVpbGRzID0gW10KKyAgICBmb3IgciBpbiBuYXRpdmUuZXhpc3RpbmdfcnVsZXMoKS52YWx1ZXMoKToKKyAgICAgICAgYWxsb3dsaXN0ZWQgPSBGYWxzZQorICAgICAgICBmb3IgYnVpbGQgaW4gYWxsb3dsaXN0OgorICAgICAgICAgICAgIyBJZ25vcmUgdGhlIGxlYWRpbmcgY29sb24gaW4gYnVpbGQuCisgICAgICAgICAgICBpZiBidWlsZFsxOl0gaW4gclsibmFtZSJdOgorICAgICAgICAgICAgICAgIGFsbG93bGlzdGVkID0gVHJ1ZQorICAgICAgICAgICAgICAgIGJyZWFrCisgICAgICAgIGlmIG5vdCBhbGxvd2xpc3RlZDoKKyAgICAgICAgICAgIGFsbF9idWlsZHMuYXBwZW5kKHJbIm5hbWUiXSkKKyAgICBjaGVja19kZXBlbmRlbmNpZXMoCisgICAgICAgIG5hbWUgPSBuYW1lLAorICAgICAgICBvZiA9IFsiOiIgKyBidWlsZCBmb3IgYnVpbGQgaW4gYWxsX2J1aWxkc10sCisgICAgICAgICoqa3dhcmdzCisgICAgKQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL0JVSUxEIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL0JVSUxECm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlYzUwNmMKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGEvQlVJTEQKQEAgLTAsMCArMSwzNyBAQAorIyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisjCisjIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworIyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisjIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorIworIyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorIworIyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisjIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisjIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorIyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisjIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworZmlsZWdyb3VwKAorICAgIG5hbWUgPSAiaW50ZWdyYXRpb25fdGVzdF9kYXRhX2ZpbGVzIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgc3JjcyA9IFsKKyAgICAgICAgIm9kd3MxX2VtcHR5IiwKKyAgICAgICAgInN0ZXAxLnR4dCIsCisgICAgICAgICJzdGVwMi50eHQiLAorICAgICAgICAiemlwX3Rlc3RfZm9sZGVyLnppcCIsCisgICAgXSwKKykKKworZmlsZWdyb3VwKAorICAgIG5hbWUgPSAiZG93bmxvYWRlcl90ZXN0X2RhdGFfZmlsZXMiLAorICAgIHRlc3Rvbmx5ID0gMSwKKyAgICBzcmNzID0gWworICAgICAgICAiZnVsbF9maWxlLnR4dCIsCisgICAgICAgICJwYXJ0aWFsX2ZpbGUudHh0IiwKKyAgICBdLAorKQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL2Z1bGxfZmlsZS50eHQgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGEvZnVsbF9maWxlLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNmU0MzVlCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL2Z1bGxfZmlsZS50eHQKQEAgLTAsMCArMSwyIEBACitGb3IgdGVzdGluZywgdGhpcyBmaWxlIG9ubHkgY29udGFpbnMgaGFsZiB0aGUgY29udGVudC4KK1RoZSBvdGhlciBoYWxmIGlzIGFsc28gaW5jbHVkZWQgZm9yIGNvbXBsZXRlZCBjb250ZW50LgpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL29kd3MxX2VtcHR5IGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL29kd3MxX2VtcHR5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFjOTkwYzQKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGEvb2R3czFfZW1wdHkKQmluYXJ5IGZpbGVzIGRpZmZlcgpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL3BhcnRpYWxfZmlsZS50eHQgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGEvcGFydGlhbF9maWxlLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NTljMmQ4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL3BhcnRpYWxfZmlsZS50eHQKQEAgLTAsMCArMSBAQAorRm9yIHRlc3RpbmcsIHRoaXMgZmlsZSBvbmx5IGNvbnRhaW5zIGhhbGYgdGhlIGNvbnRlbnQuCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGEvc3RlcDEudHh0IGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL3N0ZXAxLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NzAyNDUzCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL3N0ZXAxLnR4dApAQCAtMCwwICsxIEBACitodHRwczovL3d3dy5nc3RhdGljLmNvbS9pY2luZy9pZGQvc2FtcGxlX2dyb3VwL3N0ZXAyLnR4dApkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RkYXRhL3N0ZXAyLnR4dCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0ZGF0YS9zdGVwMi50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTUwMzMwNQotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0ZGF0YS9zdGVwMi50eHQKQEAgLTAsMCArMSBAQAorU3RlcCAyIGZpbGUuCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGEvemlwX3Rlc3RfZm9sZGVyLnppcCBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0ZGF0YS96aXBfdGVzdF9mb2xkZXIuemlwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhmZjdhYmEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGRhdGEvemlwX3Rlc3RfZm9sZGVyLnppcApCaW5hcnkgZmlsZXMgZGlmZmVyCmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZy9BbmRyb2lkTWFuaWZlc3QueG1sIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RpbmcvQW5kcm9pZE1hbmlmZXN0LnhtbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMDZlNGI2Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RpbmcvQW5kcm9pZE1hbmlmZXN0LnhtbApAQCAtMCwwICsxLDQxIEBACis8IS0tCisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworLS0+Cis8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJ1dGYtOCI/PgorPG1hbmlmZXN0IHhtbG5zOmFuZHJvaWQ9Imh0dHA6Ly9zY2hlbWFzLmFuZHJvaWQuY29tL2Fway9yZXMvYW5kcm9pZCIKKyAgcGFja2FnZT0iY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZyIgPgorCisgIDx1c2VzLXNkayBhbmRyb2lkOm1pblNka1ZlcnNpb249IjE2IiAvPgorCisgIDx1c2VzLXBlcm1pc3Npb24gYW5kcm9pZDpuYW1lPSJhbmRyb2lkLnBlcm1pc3Npb24uSU5URVJORVQiLz4KKyAgPHVzZXMtcGVybWlzc2lvbgorICAgIGFuZHJvaWQ6bmFtZT0iY29tLmdvb2dsZS5hbmRyb2lkLmdtcy5wZXJtaXNzaW9uLkJJTkRfTkVUV09SS19UQVNLX1NFUlZJQ0UiLz4KKyAgPHVzZXMtcGVybWlzc2lvbiBhbmRyb2lkOm5hbWU9ImFuZHJvaWQucGVybWlzc2lvbi5BQ0NFU1NfTkVUV09SS19TVEFURSIvPgorCisgIDwhLS0gUGVybWlzc2lvbiBuZWVkZWQgdG8gZG93bmxvYWQgZmlsZXMgbG9jYWxseSBpbiBMb2NhbEZpbGVEb3dubG9hZGVyLiAtLT4KKyAgPHVzZXMtcGVybWlzc2lvbiBhbmRyb2lkOm5hbWU9ImFuZHJvaWQucGVybWlzc2lvbi5SRUFEX0VYVEVSTkFMX1NUT1JBR0UiLz4KKworICA8IS0tIE5lZWRlZCB0byBhbGxvdyBpbnNlY3VyZSBIVFRQIHByb3RvY29sIHVzZWQgYnkgVGVzdEh0dHBTZXJ2ZXIuIC0tPgorICA8YXBwbGljYXRpb24gYW5kcm9pZDp1c2VzQ2xlYXJ0ZXh0VHJhZmZpYz0idHJ1ZSI+CisgICAgPCEtLSBFeHBsaWNpdCBkZWNsYXJhdGlvbiBuZWVkZWQgdG8gbWFrZSBvcmcuYXBhY2hlLmh0dHAgcHJlc2VudCBpbiBEZXhQYXRoTGlzdC4gLS0+CisgICAgPHVzZXMtbGlicmFyeSBhbmRyb2lkOm5hbWU9Im9yZy5hcGFjaGUuaHR0cC5sZWdhY3kiIGFuZHJvaWQ6cmVxdWlyZWQ9ImZhbHNlIiAvPgorICA8L2FwcGxpY2F0aW9uPgorCisgIDxpbnN0cnVtZW50YXRpb24KKyAgICBhbmRyb2lkOm5hbWU9ImNvbS5nb29nbGUuYW5kcm9pZC5hcHBzLmNvbW1vbi50ZXN0aW5nLnRlc3RydW5uZXIuR29vZ2xlM0luc3RydW1lbnRhdGlvblRlc3RSdW5uZXIiCisgICAgYW5kcm9pZDp0YXJnZXRQYWNrYWdlPSJjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nIiAvPgorPC9tYW5pZmVzdD4KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL0JVSUxEIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RpbmcvQlVJTEQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTRjNGFmMAotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL0JVSUxECkBAIC0wLDAgKzEsMTI5IEBACisjIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyMKKyMgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisjIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyMgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisjCisjICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisjCisjIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyMgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisjIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyMgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitsb2FkKCJAYnVpbGRfYmF6ZWxfcnVsZXNfYW5kcm9pZC8vYW5kcm9pZDpydWxlcy5iemwiLCAiYW5kcm9pZF9saWJyYXJ5IikKKworcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vOl9fc3VicGFja2FnZXNfXyJdLAorICAgIGxpY2Vuc2VzID0gWyJub3RpY2UiXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiQmxvY2tpbmdGaWxlRG93bmxvYWRlciIsCisgICAgdGVzdG9ubHkgPSAxLAorICAgIHNyY3MgPSBbCisgICAgICAgICJCbG9ja2luZ0ZpbGVEb3dubG9hZGVyLmphdmEiLAorICAgIF0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyOkZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBmbG9nZ2VyIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJGYWtlTG9nZ2VyIiwKKyAgICB0ZXN0b25seSA9IDEsCisgICAgc3JjcyA9IFsiRmFrZUxvZ2dlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZDpMb2dnZXIiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgICAgICAiQGNvbV9nb29nbGVfcHJvdG9idWYvLzpwcm90b2J1Zl9saXRlIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJGYWtlVGltZVNvdXJjZSIsCisgICAgdGVzdG9ubHkgPSAxLAorICAgIHNyY3MgPSBbIkZha2VUaW1lU291cmNlLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOlRpbWVTb3VyY2UiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIkxvY2FsRmlsZURvd25sb2FkZXIiLAorICAgIHRlc3Rvbmx5ID0gMSwKKyAgICBzcmNzID0gWyJMb2NhbEZpbGVEb3dubG9hZGVyLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkOkRvd25sb2FkRXhjZXB0aW9uIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyOkZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL29wZW5lcnM6c3RyZWFtIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9pbnRlcm5hbC9sb2dnaW5nOkxvZ1V0aWwiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIk1kZE5vdGlmaWNhdGlvbkNhcHR1cmUiLAorICAgIHRlc3Rvbmx5ID0gMSwKKyAgICBzcmNzID0gWyJNZGROb3RpZmljYXRpb25DYXB0dXJlLmphdmEiXSwKKyAgICBkZXBzID0gWworICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ZvcmVncm91bmQ6Tm90aWZpY2F0aW9uVXRpbCIsCisgICAgICAgICJAY29tX2dvb2dsZV9hbmRyb2lkX3Rlc3RpbmcvLzp1dGlsIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2NvZGVfZmluZGJ1Z3NfanNyMzA1IiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkB0cnV0aCIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiUm9ib2xlY3RyaWNGaWxlRG93bmxvYWRlciIsCisgICAgdGVzdG9ubHkgPSAxLAorICAgIHNyY3MgPSBbIlJvYm9sZWN0cmljRmlsZURvd25sb2FkZXIuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6TG9jYWxGaWxlRG93bmxvYWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZG93bmxvYWRlcjpGaWxlRG93bmxvYWRlciIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZSIsCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvZmlsZS9iYWNrZW5kczpmaWxlIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX2d1YXZhX2d1YXZhIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3J1bmZpbGVzIiwKKyAgICBdLAorKQorCithbmRyb2lkX2xpYnJhcnkoCisgICAgbmFtZSA9ICJUZXN0RmxhZ3MiLAorICAgIHRlc3Rvbmx5ID0gMSwKKyAgICBzcmNzID0gWyJUZXN0RmxhZ3MuamF2YSJdLAorICAgIGRlcHMgPSBbCisgICAgICAgICIvL2phdmEvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQ6RmxhZ3MiLAorICAgICAgICAiQGNvbV9nb29nbGVfZ3VhdmFfZ3VhdmEiLAorICAgIF0sCispCisKK2FuZHJvaWRfbGlicmFyeSgKKyAgICBuYW1lID0gIlRlc3RGaWxlRG93bmxvYWRlciIsCisgICAgdGVzdG9ubHkgPSAxLAorICAgIHNyY3MgPSBbIlRlc3RGaWxlRG93bmxvYWRlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIjpMb2NhbEZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9kb3dubG9hZGVyOkZpbGVEb3dubG9hZGVyIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlIiwKKyAgICAgICAgIi8vamF2YS9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC9maWxlL2JhY2tlbmRzOmZpbGUiLAorICAgICAgICAiLy9qYXZhL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL2ludGVybmFsL2xvZ2dpbmc6TG9nVXRpbCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworYW5kcm9pZF9saWJyYXJ5KAorICAgIG5hbWUgPSAiVGVzdEh0dHBTZXJ2ZXIiLAorICAgIHRlc3Rvbmx5ID0gMSwKKyAgICBzcmNzID0gWyJUZXN0SHR0cFNlcnZlci5qYXZhIl0sCisgICAgZGVwcyA9IFsKKyAgICAgICAgIkBhbmRyb2lkX3Nka19saW51eCIsCisgICAgICAgICJAY29tX2dvb2dsZV9ndWF2YV9ndWF2YSIsCisgICAgXSwKKykKKworZXhwb3J0c19maWxlcyhbIkFuZHJvaWRNYW5pZmVzdC54bWwiXSkKZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL0Jsb2NraW5nRmlsZURvd25sb2FkZXIuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL0Jsb2NraW5nRmlsZURvd25sb2FkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNGY1ZWVjCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RpbmcvQmxvY2tpbmdGaWxlRG93bmxvYWRlci5qYXZhCkBAIC0wLDAgKzEsMjE2IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmZsb2dnZXIuR29vZ2xlTG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVDYWxsYmFjazsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkNvdW50RG93bkxhdGNoOworCisvKioKKyAqIEZpbGUgRG93bmxvYWRlciB0aGF0IGFsbG93cyBjb250cm9sIG92ZXIgaG93IGxvbmcgdGhlIGRvd25sb2FkIHRha2VzLgorICoKKyAqIDxwPkFuIG9wdGlvbmFsIGRlbGVnYXRlIEZpbGVEb3dubG9hZGVyIGNhbiBiZSBwcm92aWRlZCB0byBwZXJmb3JtIGRvd25sb2FkaW5nIHdoaWxlIG1haW50YWluaW5nCisgKiBjb250cm9sIG92ZXIgdGhlIGRvd25sb2FkIHN0YXRlLgorICoKKyAqIDxoMz5UaGUgc3RhdGVzIG9mIGEgZG93bmxvYWQ8L2gzPgorICoKKyAqIDxwPlRoZSBmb2xsb3dpbmcgInN0YXRlcyIgYXJlIGRlZmluZWQgYW5kIHVzaW5nIHRoZSBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIHdpbGwgYWxsb3cgdGhlCisgKiBkb3dubG9hZCB0byBiZSBwYXVzZWQgc28gYXNzZXJ0aW9ucyBjYW4gYmUgbWFkZToKKyAqCisgKiA8b2w+CisgKiAgIDxsaT5JZGxlIC0gVGhlIGRvd25sb2FkIGhhcyBub3Qgc3RhcnRlZCB5ZXQuCisgKiAgIDxsaT5JbiBQcm9ncmVzcyAtIFRoZSBkb3dubG9hZCBoYXMgc3RhcnRlZCwgYnV0IGhhcyBub3QgY29tcGxldGVkIHlldC4KKyAqICAgPGxpPkZpbmlzaGluZyogLSBUaGUgZG93bmxvYWQgaXMgZmluaXNoaW5nIChPbmx5IGFwcGxpY2FibGUgd2hlbiBkZWxlZ2F0ZSBpcyBwcm92aWRlZCkuCisgKiAgIDxsaT5GaW5pc2hlZCAtIFRoZSBkb3dubG9hZCBoYXMgZmluaXNoZWQuCisgKiA8L29sPgorICoKKyAqIDxoNT5UaGUgIkZpbmlzaGluZyIgc3RhdGU8L2g1PgorICoKKyAqIDxwPlRoZSBGaW5pc2hpbmcgc3RhdGUgaXMgYSBzcGVjaWFsIHN0YXRlIG9ubHkgYXBwbGljYWJsZSB3aGVuIGEgZGVsZWdhdGUgRmlsZURvd25sb2FkZXIgaXMKKyAqIHByb3ZpZGVkLiBUaGUgRmluaXNoaW5nIHN0YXRlIGNhbiBiZSBjb25zaWRlcmVkIG1vc3QgbGlrZSB0aGUgSW4gUHJvZ3Jlc3Mgc3RhdGUsIHRoZSBtYWluCisgKiBkaXN0aW5jdGlvbiBiZWluZyB0aGF0IG5vIGFjdGlvbiBpcyBiZWluZyBwZXJmb3JtZWQgZHVyaW5nIHRoZSBJbiBQcm9ncmVzcyBzdGF0ZSwgYnV0IHRoZQorICogZGVsZWdhdGUgaXMgcnVubmluZyBkdXJpbmcgdGhlIEZpbmlzaGluZyBzdGF0ZS4KKyAqCisgKiA8cD48ZW0+V2h5IG5vdCBqdXN0IHJ1biB0aGUgZGVsZWdhdGUgZHVyaW5nIEluIFByb2dyZXNzPzwvZW0+CisgKgorICogPHA+QmVjYXVzZSB0aGUgZGVsZ2F0ZSBjb3VsZCBiZSBwZXJmb3JtaW5nIGFjdHVhbCB3b3JrIChpLmUuIG5ldHdvcmsgY2FsbHMsIEkvTyksIHRoZXJlIGNvdWxkIGJlCisgKiBzb21lIHZhcmlhYmlsaXR5IGludHJvZHVjZWQgdGhhdCBjYXVzZXMgdGVzdCBhc3NlcnRpb25zIHRvIGJlY29tZSBmbGFreS4gVGhlIEluIFByb2dyZXNzIGlzCisgKiByZXNlcnZlZCB0byBlZmZlY3RpdmVseSBiZSBhIEZyb3plbiBzdGF0ZSB0aGF0IGVuc3VyZSBubyB3b3JrIGlzIGJlaW5nIGRvbmUuIFRoaXMgZW5zdXJlcyB0aGF0CisgKiB0ZXN0IGFzc2VydGlvbnMgcmVtYWluIGNvbnNpc3RlbnQuCisgKgorICogPGg1PkNvbnRyb2xsaW5nIHRoZSBzdGF0ZXM8L2g1PgorICoKKyAqIDxwPkFmdGVyIGNyZWF0aW5nIGFuIGluc3RhbmNlIG9mIEJsb2NraW5nRmlsZURvd25sb2FkZXIsIHRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzaG93cyBob3cgdGhlCisgKiBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIGNhbiBjb250cm9sIHRoZSBzdGF0ZSBhcyB3ZWxsIGFzIHdoZW4gYXNzZXJ0aW9ucyBjYW4gYmUgbWFkZS4KKyAqCisgKiA8cHJlPntAY29kZQorICogLy8gQmVmb3JlIHRoZSBjYWxsIHRvIE1ERCdzIGRvd25sb2FkRmlsZUdyb3VwLCB0aGUgc3RhdGUgaXMgY29uc2lkZXJlZCAiSWRsZSIgYW5kIGFzc2VydGlvbnMKKyAqIC8vIGNhbiBiZSBtYWRlIGF0IHRoaXMgdGltZS4KKyAqCisgKiBtZGQuZG93bmxvYWRGaWxlR3JvdXAoLi4uKTsKKyAqCisgKiAvLyBBZnRlciBjYWxsaW5nIGRvd25sb2FkRmlsZUdyb3VwLCB0aGUgc3RhdGUgaXMgaW4gYSB0cmFuc2l0aW9uIHBlcmlvZCBmcm9tICJJZGxlIiB0bworICogLy8gIkluIFByb2dyZXNzLiIgYXNzZXJ0aW9ucyBzaG91bGQgbm90IGJlIG1hZGUgZHVyaW5nIHRoaXMgdGltZS4KKyAqCisgKiBibG9ja2luZ0ZpbGVEb3dubG9hZGVyLndhaXRGb3JEb3dubG9hZFN0YXJ0ZWQoKTsKKyAqCisgKiAvLyBUaGUgYWJvdmUgbWV0aG9kIGJsb2NrcyB1bnRpbCB0aGUgIkluIFByb2dyZXNzIiBzdGF0ZSBoYXMgYmVlbiByZWFjaGVkLiBBc3NlcnRpb25zIGNhbiBiZSBtYWRlCisgKiAvLyBhZnRlciB0aGlzIGNhbGwgZm9yIHRoZSAiSW4gUHJvZ3Jlc3MiIHN0YXRlLiBJZiBubyBhc3NlcnRpb25zIG5lZWQgdG8gYmUgbWFkZSBkdXJpbmcgdGhpcworICogLy8gc3RhdGUsIHRoZSBhYm92ZSBjYWxsIGNhbiBiZSBza2lwcGVkLgorICoKKyAqIGJsb2NraW5nRmlsZURvd25sb2FkZXIuZmluaXNoRG93bmxvYWRpbmcoKTsKKyAqCisgKiAvLyBUaGUgYWJvdmUgbWV0aG9kIG1vdmVzIHRoZSBzdGF0ZSBmcm9tICJJbiBQcm9ncmVzcyIgdG8gIkZpbmlzaGluZyIgKGlmIGEgZGVsZWdhdGUgaXMgcHJvdmlkZWQpCisgKiAvLyBvciAiRmluaXNoZWQiIChpZiBubyBkZWxlZ2F0ZSBpcyBwcm92aWRlZCkuIFRoaXMgaXMgYW5vdGhlciB0cmFuc2l0aW9uIHBlcmlvZCwgc28gYXNzZXJ0aW9ucworICogLy8gc2hvdWxkIG5vdCBiZSBtYWRlIGR1cmluZyB0aGlzIHRpbWUuCisgKgorICogYmxvY2tpbmdGaWxlRG93bmxvYWRlci53YWl0Rm9yRG93bmxvYWRDb21wbGV0ZWQoKTsKKyAqCisgKiAvLyBUaGUgYWJvdmUgbWV0aG9kIGVuc3VyZXMgdGhlIHN0YXRlIGhhcyBjaGFuZ2VkIGZyb20gIkluIFByb2dyZXNzIi8iRmluaXNoaW5nIiB0byAiRmluaXNoZWQuIgorICogLy8gQWZ0ZXIgdGhpcyBwb2ludCwgYXNzZXJ0aW9ucyBjYW4gYmUgbWFkZSBzYWZlbHkgYWdhaW4uCisgKiAvLworICogLy8gT3B0aW9uYWxseSwgdGhlIGZ1dHVyZSByZXR1cm5lZCBmcm9tIG1kZC5kb3dubG9hZEZpbGVHcm91cCBjYW4gYmUgYXdhaXRlZCBpbnN0ZWFkLCBzaW5jZSB0aGF0CisgKiAvLyBhbHNvIGVuc3VyZXMgdGhlIGRvd25sb2FkIGhhcyBjb21wbGV0ZWQuCisgKiB9PC9wcmU+CisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBCbG9ja2luZ0ZpbGVEb3dubG9hZGVyIGltcGxlbWVudHMgRmlsZURvd25sb2FkZXIgeworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBHb29nbGVMb2dnZXIgbG9nZ2VyID0gR29vZ2xlTG9nZ2VyLmZvckVuY2xvc2luZ0NsYXNzKCk7CisKKyAgcHJpdmF0ZSBmaW5hbCBMaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2UgZG93bmxvYWRFeGVjdXRvcjsKKyAgcHJpdmF0ZSBmaW5hbCBPcHRpb25hbDxGaWxlRG93bmxvYWRlcj4gZGVsZWdhdGVGaWxlRG93bmxvYWRlck9wdGlvbmFsOworCisgIHByaXZhdGUgQ291bnREb3duTGF0Y2ggZG93bmxvYWRJblByb2dyZXNzTGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisgIHByaXZhdGUgQ291bnREb3duTGF0Y2ggZG93bmxvYWRGaW5pc2hpbmdMYXRjaCA9IG5ldyBDb3VudERvd25MYXRjaCgxKTsKKyAgcHJpdmF0ZSBDb3VudERvd25MYXRjaCBkZWxlZ2F0ZUluUHJvZ3Jlc3NMYXRjaCA9IG5ldyBDb3VudERvd25MYXRjaCgxKTsKKyAgcHJpdmF0ZSBDb3VudERvd25MYXRjaCBkb3dubG9hZEZpbmlzaGVkTGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisKKyAgcHVibGljIEJsb2NraW5nRmlsZURvd25sb2FkZXIoTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlIGRvd25sb2FkRXhlY3V0b3IpIHsKKyAgICB0aGlzLmRvd25sb2FkRXhlY3V0b3IgPSBkb3dubG9hZEV4ZWN1dG9yOworICAgIHRoaXMuZGVsZWdhdGVGaWxlRG93bmxvYWRlck9wdGlvbmFsID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIH0KKworICBwdWJsaWMgQmxvY2tpbmdGaWxlRG93bmxvYWRlcigKKyAgICAgIExpc3RlbmluZ0V4ZWN1dG9yU2VydmljZSBkb3dubG9hZEV4ZWN1dG9yLCBGaWxlRG93bmxvYWRlciBkZWxlZ2F0ZUZpbGVEb3dubG9hZGVyKSB7CisgICAgdGhpcy5kb3dubG9hZEV4ZWN1dG9yID0gZG93bmxvYWRFeGVjdXRvcjsKKyAgICB0aGlzLmRlbGVnYXRlRmlsZURvd25sb2FkZXJPcHRpb25hbCA9IE9wdGlvbmFsLm9mKGRlbGVnYXRlRmlsZURvd25sb2FkZXIpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHN0YXJ0RG93bmxvYWRpbmcoRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCkgeworICAgIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gZG93bmxvYWRGdXR1cmUgPQorICAgICAgICBGdXR1cmVzLnN1Ym1pdEFzeW5jKAorICAgICAgICAgICAgKCkgLT4geworICAgICAgICAgICAgICBsb2dnZXIuYXRJbmZvKCkubG9nKCJEb3dubG9hZCBTdGFydGVkLCBzdGF0ZSBjaGFuZ2VkIHRvOiBJbiBQcm9ncmVzcyIpOworICAgICAgICAgICAgICBkb3dubG9hZEluUHJvZ3Jlc3NMYXRjaC5jb3VudERvd24oKTsKKworICAgICAgICAgICAgICBsb2dnZXIuYXRJbmZvKCkubG9nKCJXYWl0aW5nIGZvciBkb3dubG9hZCB0byBjb250aW51ZSIpOworICAgICAgICAgICAgICBkb3dubG9hZEZpbmlzaGluZ0xhdGNoLmF3YWl0KCk7CisKKyAgICAgICAgICAgICAgTGlzdGVuYWJsZUZ1dHVyZTxWb2lkPiByZXN1bHQ7CisgICAgICAgICAgICAgIGlmIChkZWxlZ2F0ZUZpbGVEb3dubG9hZGVyT3B0aW9uYWwuaXNQcmVzZW50KCkpIHsKKyAgICAgICAgICAgICAgICBsb2dnZXIuYXRJbmZvKCkubG9nKCJEb3dubG9hZCBTdGF0ZSBDaGFuZ2VkIHRvOiBGaW5pc2hpbmcgKGRlbGVnYXRlIGluIHByb2dyZXNzKSIpOworICAgICAgICAgICAgICAgIC8vIERlbGVnYXRlIHdhcyBwcm92aWRlZCwgc28gcGVyZm9ybSBpdHMgZG93bmxvYWQKKyAgICAgICAgICAgICAgICByZXN1bHQgPSBkZWxlZ2F0ZUZpbGVEb3dubG9hZGVyT3B0aW9uYWwuZ2V0KCkuc3RhcnREb3dubG9hZGluZyhkb3dubG9hZFJlcXVlc3QpOworICAgICAgICAgICAgICAgIGRlbGVnYXRlSW5Qcm9ncmVzc0xhdGNoLmNvdW50RG93bigpOworICAgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIHJlc3VsdCA9IEZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgICAgICAgICAgICB9CisKKyAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgIH0sCisgICAgICAgICAgICBkb3dubG9hZEV4ZWN1dG9yKTsKKworICAgIC8vIEFkZCBhIGNhbGxiYWNrIHRvIGVuc3VyZSB0aGUgc3RhdGUgdHJhbnNpdGlvbnMgZnJvbSAiSW4gUHJvZ3Jlc3MiLyJGaW5pc2hpbmciIHRvICJGaW5pc2hlZC4iCisgICAgRnV0dXJlcy5hZGRDYWxsYmFjaygKKyAgICAgICAgZG93bmxvYWRGdXR1cmUsCisgICAgICAgIG5ldyBGdXR1cmVDYWxsYmFjazxWb2lkPigpIHsKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgdm9pZCBvblN1Y2Nlc3MoVm9pZCB1bnVzZWQpIHsKKyAgICAgICAgICAgIEJsb2NraW5nRmlsZURvd25sb2FkZXIubG9nZ2VyLmF0SW5mbygpLmxvZygiRG93bmxvYWQgU3RhdGUgQ2hhbmdlZCB0bzogRmluaXNoZWQiKTsKKyAgICAgICAgICAgIGRvd25sb2FkRmluaXNoZWRMYXRjaC5jb3VudERvd24oKTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICBAT3ZlcnJpZGUKKyAgICAgICAgICBwdWJsaWMgdm9pZCBvbkZhaWx1cmUoVGhyb3dhYmxlIHQpIHsKKyAgICAgICAgICAgIEJsb2NraW5nRmlsZURvd25sb2FkZXIubG9nZ2VyCisgICAgICAgICAgICAgICAgLmF0U2V2ZXJlKCkKKyAgICAgICAgICAgICAgICAud2l0aENhdXNlKHQpCisgICAgICAgICAgICAgICAgLmxvZygiRG93bmxvYWQgU3RhdGUgQ2hhbmdlZCB0bzogRmluaXNoZWQgKHdpdGggZXJyb3IpIik7CisgICAgICAgICAgICBkb3dubG9hZEZpbmlzaGVkTGF0Y2guY291bnREb3duKCk7CisgICAgICAgICAgfQorICAgICAgICB9LAorICAgICAgICBkb3dubG9hZEV4ZWN1dG9yKTsKKworICAgIHJldHVybiBkb3dubG9hZEZ1dHVyZTsKKyAgfQorCisgIC8qKiBCbG9ja3MgdGhlIGNhbGxlciB0aHJlYWQgdW50aWwgdGhlIGRvd25sb2FkIGhhcyBtb3ZlZCB0byB0aGUgIkluIFByb2dyZXNzIiBzdGF0ZS4gKi8KKyAgcHVibGljIHZvaWQgd2FpdEZvckRvd25sb2FkU3RhcnRlZCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgZG93bmxvYWRJblByb2dyZXNzTGF0Y2guYXdhaXQoKTsKKyAgfQorCisgIC8qKiBCbG9ja3MgdGhlIGNhbGxlciB0aHJlYWQgdW50aWwgdGhlIGRvd25sb2FkIGhhcyBtb3ZlZCB0byB0aGUgIkZpbmlzaGluZyIgc3RhdGUuICovCisgIHB1YmxpYyB2b2lkIHdhaXRGb3JEb3dubG9hZENvbXBsZXRlZCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgZG93bmxvYWRGaW5pc2hlZExhdGNoLmF3YWl0KCk7CisgIH0KKworICAvKioKKyAgICogQmxvY2tzIHRoZSBjYWxsZXIgdGhyZWFkIHVudGlsIHRoZSBkZWxlZ2F0ZSBkb3dubG9hZGVyIGhhcyBiZWVuIGludm9rZWQuIFRoaXMgbWV0aG9kIHdpbGwgbmV2ZXIKKyAgICogY29tcGxldGUgaWYgbm8gZGVsZWdhdGUgd2FzIHByb3ZpZGVkLgorICAgKi8KKyAgcHVibGljIHZvaWQgd2FpdEZvckRlbGVnYXRlU3RhcnRlZCgpIHRocm93cyBJbnRlcnJ1cHRlZEV4Y2VwdGlvbiB7CisgICAgZGVsZWdhdGVJblByb2dyZXNzTGF0Y2guYXdhaXQoKTsKKyAgfQorCisgIC8qKgorICAgKiBGaW5pc2hlcyB0aGUgY3VycmVudCBkb3dubG9hZCBsaWZlY3ljbGUuCisgICAqCisgICAqIDxwPlRoZSBpbiBwcm9ncmVzcyBsYXRjaCBpcyB0cmlnZ2VyZWQgaWYgaXQgaGFzbid0IHlldCBiZWVuIHRyaWdnZXJlZCB0byBwcmV2ZW50IGEgZGVhZGxvY2sKKyAgICogZnJvbSBvY2N1cnJpbmcuCisgICAqLworICBwdWJsaWMgdm9pZCBmaW5pc2hEb3dubG9hZGluZygpIHsKKyAgICBpZiAoZG93bmxvYWRJblByb2dyZXNzTGF0Y2guZ2V0Q291bnQoKSA+IDApIHsKKyAgICAgIGRvd25sb2FkSW5Qcm9ncmVzc0xhdGNoLmNvdW50RG93bigpOworICAgIH0KKyAgICBkb3dubG9hZEZpbmlzaGluZ0xhdGNoLmNvdW50RG93bigpOworICB9CisKKyAgLyoqCisgICAqIFJlc2V0cyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgZG93bmxvYWQgbGlmZWN5Y2xlLgorICAgKgorICAgKiA8cD5BbiBleGlzdGluZyBkb3dubG9hZCBjeWNsZSBpcyBmaW5pc2hlZCBiZWZvcmUgcmVzZXR0aW5nIHRoZSBzdGF0ZSB0byBwcmV2ZW50IGEgZGVhZGxvY2sgZnJvbQorICAgKiBvY2N1cnJpbmcuCisgICAqLworICBwdWJsaWMgdm9pZCByZXNldFN0YXRlKCkgeworICAgIC8vIEZvcmNlIGEgZmluaXNoIGRvd25sb2FkIGlmIGl0IHdhcyBwcmV2aW91c2x5IGluIHByb2dyZXNzIHRvIHByZXZlbnQgZGVhZGxvY2suCisgICAgaWYgKGRvd25sb2FkRmluaXNoZWRMYXRjaC5nZXRDb3VudCgpID4gMCkgeworICAgICAgZmluaXNoRG93bmxvYWRpbmcoKTsKKyAgICB9CisgICAgZG93bmxvYWRGaW5pc2hlZExhdGNoLmNvdW50RG93bigpOworCisgICAgbG9nZ2VyLmF0SW5mbygpLmxvZygiUmVzZXQgU3RhdGUgYmFjayB0bzogSWRsZSIpOworICAgIGRvd25sb2FkSW5Qcm9ncmVzc0xhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworICAgIGRvd25sb2FkRmluaXNoaW5nTGF0Y2ggPSBuZXcgQ291bnREb3duTGF0Y2goMSk7CisgICAgZG93bmxvYWRGaW5pc2hlZExhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworICAgIGRlbGVnYXRlSW5Qcm9ncmVzc0xhdGNoID0gbmV3IENvdW50RG93bkxhdGNoKDEpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZy9GYWtlTG9nZ2VyLmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZy9GYWtlTG9nZ2VyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTc5MGE5MwotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL0Zha2VMb2dnZXIuamF2YQpAQCAtMCwwICsxLDQwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nOworCitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuTG9nZ2VyOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLmNvbGxlY3QuSW1tdXRhYmxlTGlzdDsKK2ltcG9ydCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VMaXRlOworCisvKiogRmFrZSBMb2dnZXIgaW1wbGVtZW50YXRpb24gdGhhdCBzYXZlcyBldmVudCBjb2RlcyBzZW50IHRvIGl0LiAqLworcHVibGljIGZpbmFsIGNsYXNzIEZha2VMb2dnZXIgaW1wbGVtZW50cyBMb2dnZXIgeworCisgIHByaXZhdGUgZmluYWwgSW1tdXRhYmxlTGlzdC5CdWlsZGVyPEludGVnZXI+IGxvZ0V2ZW50czsKKworICBwdWJsaWMgRmFrZUxvZ2dlcigpIHsKKyAgICBsb2dFdmVudHMgPSBJbW11dGFibGVMaXN0LjxJbnRlZ2VyPmJ1aWxkZXIoKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgdm9pZCBsb2coTWVzc2FnZUxpdGUgbXNnLCBpbnQgZXZlbnRDb2RlKSB7CisgICAgbG9nRXZlbnRzLmFkZChldmVudENvZGUpOworICB9CisKKyAgLyoqIFJldHVybnMgYW4gSW1tdXRhYmxlTGlzdCBjb250YWluaW5nIGFsbCB0aGUgZXZlbnQgY29kZXMgdGhhdCBoYXZlIGJlZW4gc2VudCB0byB0aGlzIGxvZ2dlci4gKi8KKyAgcHVibGljIEltbXV0YWJsZUxpc3Q8SW50ZWdlcj4gZ2V0TG9nRXZlbnRzKCkgeworICAgIHJldHVybiBsb2dFdmVudHMuYnVpbGQoKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RpbmcvRmFrZVRpbWVTb3VyY2UuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL0Zha2VUaW1lU291cmNlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzhlN2ZhOAotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL0Zha2VUaW1lU291cmNlLmphdmEKQEAgLTAsMCArMSw1MCBAQAorLyoKKyAqIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKyAqCisgKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKyAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKyAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorICoKKyAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisgKgorICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKyAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCisgKi8KK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQudGVzdGluZzsKKworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLlRpbWVTb3VyY2U7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGltZVVuaXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0xvbmc7CisKKy8qKiBGYWtlIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBUaW1lU291cmNlfSBmb3IgdGVzdGluZy4gKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBGYWtlVGltZVNvdXJjZSBpbXBsZW1lbnRzIFRpbWVTb3VyY2UgeworCisgIHByaXZhdGUgZmluYWwgQXRvbWljTG9uZyBjdXJyZW50TWlsbGlzID0gbmV3IEF0b21pY0xvbmcoKTsKKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGxvbmcgY3VycmVudFRpbWVNaWxsaXMoKSB7CisgICAgcmV0dXJuIGN1cnJlbnRNaWxsaXMuZ2V0KCk7CisgIH0KKworICAvKiogQWR2YW5jZXMgdGhlIGN1cnJlbnQgdGltZSBhbmQgcmV0dXJucyB7QGNvZGUgdGhpc30uICovCisgIHB1YmxpYyBGYWtlVGltZVNvdXJjZSBhZHZhbmNlKGxvbmcgaW50ZXJ2YWwsIFRpbWVVbml0IHVuaXRzKSB7CisgICAgbG9uZyBtaWxsaXMgPSB1bml0cy50b01pbGxpcyhpbnRlcnZhbCk7CisgICAgaWYgKG1pbGxpcyA8IDApIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkNhbid0IGFkdmFuY2UgbmVnYXRpdmUgZHVyYXRpb246ICIgKyBtaWxsaXMpOworICAgIH0KKyAgICBjdXJyZW50TWlsbGlzLmdldEFuZEFkZChtaWxsaXMpOworICAgIHJldHVybiB0aGlzOworICB9CisKKyAgLyoqIFNldHMgdGhlIGN1cnJlbnQgdGltZSBhbmQgcmV0dXJucyB7QGNvZGUgdGhpc30uICovCisgIHB1YmxpYyBGYWtlVGltZVNvdXJjZSBzZXQobG9uZyBtaWxsaXMpIHsKKyAgICBpZiAobWlsbGlzIDwgMCkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiQ2FuJ3Qgc2V0IGJlZm9yZSB1bml4IGVwb2NoOiIgKyBtaWxsaXMpOworICAgIH0KKyAgICBjdXJyZW50TWlsbGlzLnNldChtaWxsaXMpOworICAgIHJldHVybiB0aGlzOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZy9Mb2NhbEZpbGVEb3dubG9hZGVyLmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZy9Mb2NhbEZpbGVEb3dubG9hZGVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmIyYTkwYwotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL0xvY2FsRmlsZURvd25sb2FkZXIuamF2YQpAQCAtMCwwICsxLDkzIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZUZhaWxlZEZ1dHVyZTsKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZTsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5Eb3dubG9hZEV4Y2VwdGlvbi5Eb3dubG9hZFJlc3VsdENvZGU7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLk9wZW5lcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLlJlYWRTdHJlYW1PcGVuZXI7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5vcGVuZXJzLldyaXRlU3RyZWFtT3BlbmVyOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5pby5CeXRlU3RyZWFtczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuRnV0dXJlczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKK2ltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcjsKKworLyoqCisgKiBBIHtAbGluayBGaWxlRG93bmxvYWRlcn0gdGhhdCAiZG93bmxvYWRzIiBieSBjb3B5aW5nIHRoZSBmaWxlIGZyb20gdGhlIGxvY2FsIGZvbGRlci4KKyAqCisgKiA8cD5Ob3RlIHRoYXQgTG9jYWxGaWxlRG93bmxvYWRlciBpZ25vcmVzIERvd25sb2FkQ29uZGl0aW9ucy4KKyAqLworcHVibGljIGZpbmFsIGNsYXNzIExvY2FsRmlsZURvd25sb2FkZXIgaW1wbGVtZW50cyBGaWxlRG93bmxvYWRlciB7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9ICJMb2NhbEZpbGVEb3dubG9hZGVyIjsKKworICBwcml2YXRlIGZpbmFsIEV4ZWN1dG9yIGJhY2tncm91ZEV4ZWN1dG9yOworICBwcml2YXRlIGZpbmFsIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2U7CisKKyAgcHVibGljIExvY2FsRmlsZURvd25sb2FkZXIoCisgICAgICBTeW5jaHJvbm91c0ZpbGVTdG9yYWdlIGZpbGVTdG9yYWdlLCBMaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3IpIHsKKyAgICB0aGlzLmZpbGVTdG9yYWdlID0gZmlsZVN0b3JhZ2U7CisgICAgdGhpcy5iYWNrZ3JvdWRFeGVjdXRvciA9IGV4ZWN1dG9yOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHN0YXJ0RG93bmxvYWRpbmcoRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCkgeworICAgIHJldHVybiBGdXR1cmVzLnN1Ym1pdEFzeW5jKCgpIC0+IHN0YXJ0RG93bmxvYWRpbmdJbnRlcm5hbChkb3dubG9hZFJlcXVlc3QpLCBiYWNrZ3JvdWRFeGVjdXRvcik7CisgIH0KKworICBwcml2YXRlIExpc3RlbmFibGVGdXR1cmU8Vm9pZD4gc3RhcnREb3dubG9hZGluZ0ludGVybmFsKERvd25sb2FkUmVxdWVzdCBkb3dubG9hZFJlcXVlc3QpIHsKKyAgICBVcmkgZmlsZVVyaSA9IGRvd25sb2FkUmVxdWVzdC5maWxlVXJpKCk7CisgICAgU3RyaW5nIHVybFRvRG93bmxvYWQgPSBkb3dubG9hZFJlcXVlc3QudXJsVG9Eb3dubG9hZCgpOworICAgIExvZ1V0aWwuZCgiJXM6IHN0YXJ0RG93bmxvYWRpbmc7IGZpbGVVcmk6ICVzOyB1cmxUb0Rvd25sb2FkOiAlcyIsIFRBRywgZmlsZVVyaSwgdXJsVG9Eb3dubG9hZCk7CisKKyAgICBVcmkgdXJpVG9Eb3dubG9hZCA9IFVyaS5wYXJzZSh1cmxUb0Rvd25sb2FkKTsKKyAgICBpZiAodXJpVG9Eb3dubG9hZCA9PSBudWxsKSB7CisgICAgICBMb2dVdGlsLmUoIiVzOiBJbnZhbGlkIHVybFRvRG93bmxvYWQgJXMiLCBUQUcsIHVybFRvRG93bmxvYWQpOworICAgICAgcmV0dXJuIGltbWVkaWF0ZUZhaWxlZEZ1dHVyZShuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJJbnZhbGlkIHVybFRvRG93bmxvYWQiKSk7CisgICAgfQorCisgICAgdHJ5IHsKKyAgICAgIE9wZW5lcjxJbnB1dFN0cmVhbT4gcmVhZFN0cmVhbU9wZW5lciA9IFJlYWRTdHJlYW1PcGVuZXIuY3JlYXRlKCk7CisgICAgICBPcGVuZXI8T3V0cHV0U3RyZWFtPiB3cml0ZVN0cmVhbU9wZW5lciA9IFdyaXRlU3RyZWFtT3BlbmVyLmNyZWF0ZSgpOworICAgICAgbG9uZyB3cml0dGVuQnl0ZXM7CisgICAgICB0cnkgKElucHV0U3RyZWFtIGluID0gZmlsZVN0b3JhZ2Uub3Blbih1cmlUb0Rvd25sb2FkLCByZWFkU3RyZWFtT3BlbmVyKTsKKyAgICAgICAgICBPdXRwdXRTdHJlYW0gb3V0ID0gZmlsZVN0b3JhZ2Uub3BlbihmaWxlVXJpLCB3cml0ZVN0cmVhbU9wZW5lcikpIHsKKyAgICAgICAgd3JpdHRlbkJ5dGVzID0gQnl0ZVN0cmVhbXMuY29weShpbiwgb3V0KTsKKyAgICAgIH0KKyAgICAgIExvZ1V0aWwuZCgiJXM6IEZpbGUgVVJJICVzIGRvd25sb2FkIGNvbXBsZXRlLCB3cml0dGVuQnl0ZXM6ICVkIiwgVEFHLCBmaWxlVXJpLCB3cml0dGVuQnl0ZXMpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIExvZ1V0aWwuZShlLCAiJXM6IHN0YXJ0RG93bmxvYWRpbmcgZ290IGV4Y2VwdGlvbiIsIFRBRyk7CisgICAgICByZXR1cm4gaW1tZWRpYXRlRmFpbGVkRnV0dXJlKAorICAgICAgICAgIERvd25sb2FkRXhjZXB0aW9uLmJ1aWxkZXIoKQorICAgICAgICAgICAgICAuc2V0RG93bmxvYWRSZXN1bHRDb2RlKERvd25sb2FkUmVzdWx0Q29kZS5BTkRST0lEX0RPV05MT0FERVJfSFRUUF9FUlJPUikKKyAgICAgICAgICAgICAgLmJ1aWxkKCkpOworICAgIH0KKworICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL01kZE5vdGlmaWNhdGlvbkNhcHR1cmUuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL01kZE5vdGlmaWNhdGlvbkNhcHR1cmUuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NjQ1NGU3Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RpbmcvTWRkTm90aWZpY2F0aW9uQ2FwdHVyZS5qYXZhCkBAIC0wLDAgKzEsMzA4IEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnRydXRoLlRydXRoLmFzc2VydFRoYXQ7CisKK2ltcG9ydCBhbmRyb2lkLmFwcC5Ob3RpZmljYXRpb247CitpbXBvcnQgYW5kcm9pZC5hcHAuTm90aWZpY2F0aW9uTWFuYWdlcjsKK2ltcG9ydCBhbmRyb2lkLmNvbnRlbnQuQ29udGV4dDsKK2ltcG9ydCBhbmRyb2lkLm9zLkJ1aWxkLlZFUlNJT047CitpbXBvcnQgYW5kcm9pZC5vcy5CdWlsZC5WRVJTSU9OX0NPREVTOworaW1wb3J0IGFuZHJvaWQuc2VydmljZS5ub3RpZmljYXRpb24uU3RhdHVzQmFyTm90aWZpY2F0aW9uOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5hcHBzLmNvbW1vbi50ZXN0aW5nLnV0aWwuQW5kcm9pZFRlc3RVdGlsOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmZvcmVncm91bmQuTm90aWZpY2F0aW9uVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLlByZWNvbmRpdGlvbnM7CitpbXBvcnQgY29tLmdvb2dsZS5jb21tb24uY29sbGVjdC5JbW11dGFibGVMaXN0OworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnRydXRoLkNvcnJlc3BvbmRlbmNlOworaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CitpbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKK2ltcG9ydCBqYXZhLnV0aWwucmVnZXguUGF0dGVybjsKK2ltcG9ydCBqYXZheC5hbm5vdGF0aW9uLk51bGxhYmxlOworCisvKiogVGVzdGluZyBVdGlsaXR5IHRvIGNhcHR1cmUgbm90aWZpY2F0aW9ucyBhbmQgbWFrZSBhc3NlcnRpb25zLiAqLworcHVibGljIGludGVyZmFjZSBNZGROb3RpZmljYXRpb25DYXB0dXJlIHsKKyAgLyoqCisgICAqIEFEQiBzaGVsbCBjb21tYW5kIHRvIGNsZWFyIG5vdGlmaWNhdGlvbnMuCisgICAqCisgICAqIDxwPlRoaXMgY29tbWFuZCB1c2VzIHRoZSBub3RpZmljYXRpb24gc2VydmljZSAoaS5lLiBOb3RpZmljYXRpb25NYW5hZ2VyKSBhbmQgY2FsbHMgdGhlIGZpcnN0CisgICAqIG1ldGhvZCBpbiB0aGF0IHNlcnZpY2VzIGlkbCBkZWZpbml0aW9uLiBGb3Igb3VyIHNlcnZpY2UsIHRoaXMgcmVmZXJzIHRvIHRoZSBtZXRob2QgPGEKKyAgICogaHJlZj0iPGludGVybmFsPiI+Y2FuY2VsQWxsTm90aWZpY2F0aW9uczwvYT4gaW4gdGhlIElOb3RpZmljYXRpb25NYW5hZ2VyLmFpZGwuCisgICAqLworICBzdGF0aWMgZmluYWwgU3RyaW5nIENMRUFSX05PVElGSUNBVElPTlNfQ01EID0gInNlcnZpY2UgY2FsbCBub3RpZmljYXRpb24gMSI7CisKKyAgLyoqCisgICAqIEFEQiBzaGVsbCBjb21tYW5kIHRvIGR1bXAgbm90aWZpY2F0aW9uIGNvbnRlbnQgdG8gbG9nY2F0LgorICAgKgorICAgKiA8cD5UaGUge0Bjb2RlIGR1bXBzeXN9IGNvbW1hbmQgaXMgdXNlZCB0byBkdW1wIHN5c3RlbSBkaWFnbm9zdGljcy4gV2UgYXJlIGludGVyZXN0ZWQgaW4KKyAgICogbm90aWZpY2F0aW9ucywgc28gdGhleSBhcmUgc3BlY2lmaWVkIGhlcmUuIFRoZSB7QGNvZGUgLS1ub3JlZGFjdH0gZmxhZyBpcyBhZGRlZCB0byBwcm92aWRlZAorICAgKiB1bnJlZGFjdGVkIGluZm8gKHRoZSBhY3R1YWwgdmFsdWVzIG9mIHZhcmlhYmxlcykgaW5zdGVhZCBvZiBqdXN0IHRoZWlyIHR5cGUgZGVmaW5pdGlvbnMuIFRoaXMKKyAgICogZmxhZyBoYXMgdmFyeWluZyBsZXZlbHMgb2Ygc3VwcG9ydCBhY3Jvc3MgdGhlIEFQSSBsZXZlbHMsIGJ1dCBzaG91bGQgcHJvdmlkZSBlcXVpdmFsZW50IG9yCisgICAqIGdyZWF0ZXIgaW5mb3JtYXRpb24gaW4gdGhlIGxvZyBkdW1wIHRoYXQgY2FuIGJlIGNhcHR1cmVkLgorICAgKi8KKyAgc3RhdGljIGZpbmFsIFN0cmluZyBEVU1QX05PVElGSUNBVElPTl9DTUQgPSAiZHVtcHN5cyBub3RpZmljYXRpb24gLS1ub3JlZGFjdCI7CisKKyAgc3RhdGljIGZpbmFsIEltbXV0YWJsZUxpc3Q8SW50ZWdlcj4gTUREX0lDT05fSURTID0KKyAgICAgIEltbXV0YWJsZUxpc3Qub2YoCisgICAgICAgICAgYW5kcm9pZC5SLmRyYXdhYmxlLnN0YXRfc3lzX2Rvd25sb2FkLAorICAgICAgICAgIGFuZHJvaWQuUi5kcmF3YWJsZS5zdGF0X3N5c19kb3dubG9hZF9kb25lLAorICAgICAgICAgIGFuZHJvaWQuUi5kcmF3YWJsZS5zdGF0X3N5c193YXJuaW5nKTsKKworICBwdWJsaWMgc3RhdGljIHZvaWQgY2xlYXJOb3RpZmljYXRpb25zKCkgeworICAgIHRyeSB7CisgICAgICBBbmRyb2lkVGVzdFV0aWwuZXhlY3V0ZVNoZWxsQ29tbWFuZChDTEVBUl9OT1RJRklDQVRJT05TX0NNRCk7CisgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiVW5hYmxlIHRvIGV4ZWN1dGUgc2hlbGwgY29tbWFuZCIsIGUpOworICAgIH0KKyAgfQorCisgIHB1YmxpYyBzdGF0aWMgTWRkTm90aWZpY2F0aW9uQ2FwdHVyZSBzbmFwc2hvdChDb250ZXh0IGNvbnRleHQpIHsKKyAgICAvLyBDYXB0dXJpbmcgYWN0aXZlIG5vdGlmaWNhdGlvbnMgaXMgb25seSBhdmFpbGFibGUgZm9yIEFQSSBsZXZlbCAyMyBhbmQgYWJvdmUuIENoZWNrIHRvIHNlZSBpZgorICAgIC8vIHRoZSBjdXJyZW50IHZlcnNpb24gc3VwcG9ydHMgaXQsIG90aGVyd2lzZSBmYWxsIGJhY2sgdG8gdXNpbmcgYWRiIHRvIGNhcHR1cmUgbm90aWZpY2F0aW9uCisgICAgLy8gY29udGVudC4KKyAgICBpZiAoVkVSU0lPTi5TREtfSU5UID49IFZFUlNJT05fQ09ERVMuTSkgeworICAgICAgTm90aWZpY2F0aW9uTWFuYWdlciBtYW5hZ2VyID0KKyAgICAgICAgICAoTm90aWZpY2F0aW9uTWFuYWdlcikgY29udGV4dC5nZXRTeXN0ZW1TZXJ2aWNlKENvbnRleHQuTk9USUZJQ0FUSU9OX1NFUlZJQ0UpOworICAgICAgU3RhdHVzQmFyTm90aWZpY2F0aW9uW10gYWN0aXZlTm90aWZpY2F0aW9ucyA9IG1hbmFnZXIuZ2V0QWN0aXZlTm90aWZpY2F0aW9ucygpOworICAgICAgTGlzdDxOb3RpZmljYXRpb24+IG5vdGlmaWNhdGlvbnMgPSBuZXcgQXJyYXlMaXN0PD4oKTsKKyAgICAgIGZvciAoU3RhdHVzQmFyTm90aWZpY2F0aW9uIG5vdGlmaWNhdGlvbiA6IGFjdGl2ZU5vdGlmaWNhdGlvbnMpIHsKKyAgICAgICAgLy8gVE9ETyhiLzE0ODQwMTAxNik6IEFkZCBzb21lIHRlc3QgdG8gZW5zdXJlIG9ubHkgTUREIG5vdGlmaWNhdGlvbnMgYXJlIGluY2x1ZGVkIGluIHRoaXMKKyAgICAgICAgLy8gbGlzdC4KKyAgICAgICAgbm90aWZpY2F0aW9ucy5hZGQobm90aWZpY2F0aW9uLmdldE5vdGlmaWNhdGlvbigpKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBuZXcgTVBsdXNOb3RpZmljYXRpb25DYXB0dXJlKGNvbnRleHQsIG5vdGlmaWNhdGlvbnMpOworICAgIH0KKyAgICB0cnkgeworICAgICAgLy8gTm90aWZpY2F0aW9uTWFuYWdlci5nZXRBY3Rpdml0Tm90aWZpY2F0aW9ucygpIGlzIHVuYXZhaWxhYmxlLCBmYWxsYmFjayB0byB1c2luZyBhZGIKKyAgICAgIFN0cmluZyByZXN1bHQgPSBBbmRyb2lkVGVzdFV0aWwuZXhlY3V0ZVNoZWxsQ29tbWFuZChEVU1QX05PVElGSUNBVElPTl9DTUQpOworICAgICAgcmV0dXJuIG5ldyBQcmVNTm90aWZpY2F0aW9uQ2FwdHVyZShjb250ZXh0LCByZXN1bHQpOworICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgIHRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIlVuYWJsZSB0byBleGVjdXRlIHNoZWxsIGNvbW1hbmQiLCBlKTsKKyAgICB9CisgIH0KKworICB2b2lkIGFzc2VydFN0YXJ0Tm90aWZpY2F0aW9uQ2FwdHVyZWQoU3RyaW5nIHRpdGxlLCBTdHJpbmcgdGV4dCk7CisKKyAgdm9pZCBhc3NlcnRTdWNjZXNzTm90aWZpY2F0aW9uQ2FwdHVyZWQoU3RyaW5nIHRpdGxlKTsKKworICB2b2lkIGFzc2VydEZhaWxlZE5vdGlmaWNhdGlvbkNhcHR1cmVkKFN0cmluZyB0aXRsZSk7CisKKyAgdm9pZCBhc3NlcnRQYXVzZWROb3RpZmljYXRpb25DYXB0dXJlZChTdHJpbmcgdGl0bGUpOworCisgIHZvaWQgYXNzZXJ0Tm9Ob3RpZmljYXRpb25zQ2FwdHVyZWQoKTsKKworICAvKioKKyAgICogSW1wbGVtZW50YXRpb24gb2YgTm90aWZpY2F0aW9uIENhcHR1cmUgZm9yIEFQSSBsZXZlbHMgYmVsb3cgMjMgKEFuZHJvaWQgTSkuCisgICAqCisgICAqIDxwPlRoaXMgaW1wbGVtZW50YXRpb24gcmVsaWVzIG9uIGNvbnRlbnQgY2FwdHVyZWQgZnJvbSBhZGIgYWJvdXQgbm90aWZpY3Rpb25zLiBUaGUgcHJpbWFyeQorICAgKiBtZXRob2Qgb2YgZmluZGluZyByZXN1bHRzIGlzIHVzaW5nIFJlZ2V4ZXMgdG8gc2VhcmNoIGZvciByZWxldmFudCBwaWVjZXMgb2YgaW5mb3JtYXRpb24gYWJvdXQKKyAgICogY2FwdHVyZWQgbm90aWZpY2F0aW9ucy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgUHJlTU5vdGlmaWNhdGlvbkNhcHR1cmUgaW1wbGVtZW50cyBNZGROb3RpZmljYXRpb25DYXB0dXJlIHsKKyAgICBwcml2YXRlIGZpbmFsIENvbnRleHQgY29udGV4dDsKKyAgICBwcml2YXRlIGZpbmFsIFN0cmluZyBub3RpZmljYXRpb25PdXRwdXQ7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIENPTlRFTlRfVElUTEVfUEFUVEVSTiA9CisgICAgICAgIFBhdHRlcm4uY29tcGlsZSgiYW5kcm9pZFxcLnRpdGxlPVN0cmluZ1xcc1xcKCguKylcXCkiKTsKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQYXR0ZXJuIENPTlRFTlRfVEVYVF9QQVRURVJOID0KKyAgICAgICAgUGF0dGVybi5jb21waWxlKCJhbmRyb2lkXFwudGV4dD1TdHJpbmdcXHNcXCgoLispXFwpIik7CisgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgUGF0dGVybiBJQ09OX1BBVFRFUk4gPSBQYXR0ZXJuLmNvbXBpbGUoImljb249MHgoW2EtZkEtRjAtOV0rKSIpOworCisgICAgcHJpdmF0ZSBQcmVNTm90aWZpY2F0aW9uQ2FwdHVyZShDb250ZXh0IGNvbnRleHQsIFN0cmluZyBub3RpZmljYXRpb25PdXRwdXQpIHsKKyAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7CisgICAgICB0aGlzLm5vdGlmaWNhdGlvbk91dHB1dCA9IG5vdGlmaWNhdGlvbk91dHB1dDsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRTdGFydE5vdGlmaWNhdGlvbkNhcHR1cmVkKFN0cmluZyB0aXRsZSwgU3RyaW5nIHRleHQpIHsKKyAgICAgIGFzc2VydE5vdGlmaWNhdGlvbkNhcHR1cmVkTWF0Y2hlcyh0aXRsZSwgdGV4dCwgYW5kcm9pZC5SLmRyYXdhYmxlLnN0YXRfc3lzX2Rvd25sb2FkKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRTdWNjZXNzTm90aWZpY2F0aW9uQ2FwdHVyZWQoU3RyaW5nIHRpdGxlKSB7CisgICAgICBhc3NlcnROb3RpZmljYXRpb25DYXB0dXJlZE1hdGNoZXMoCisgICAgICAgICAgdGl0bGUsCisgICAgICAgICAgTm90aWZpY2F0aW9uVXRpbC5nZXREb3dubG9hZFN1Y2Nlc3NNZXNzYWdlKGNvbnRleHQpLAorICAgICAgICAgIGFuZHJvaWQuUi5kcmF3YWJsZS5zdGF0X3N5c19kb3dubG9hZF9kb25lKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRGYWlsZWROb3RpZmljYXRpb25DYXB0dXJlZChTdHJpbmcgdGl0bGUpIHsKKyAgICAgIGFzc2VydE5vdGlmaWNhdGlvbkNhcHR1cmVkTWF0Y2hlcygKKyAgICAgICAgICB0aXRsZSwKKyAgICAgICAgICBOb3RpZmljYXRpb25VdGlsLmdldERvd25sb2FkRmFpbGVkTWVzc2FnZShjb250ZXh0KSwKKyAgICAgICAgICBhbmRyb2lkLlIuZHJhd2FibGUuc3RhdF9zeXNfd2FybmluZyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYXNzZXJ0UGF1c2VkTm90aWZpY2F0aW9uQ2FwdHVyZWQoU3RyaW5nIHRpdGxlKSB7CisgICAgICBhc3NlcnROb3RpZmljYXRpb25DYXB0dXJlZE1hdGNoZXMoCisgICAgICAgICAgdGl0bGUsCisgICAgICAgICAgTm90aWZpY2F0aW9uVXRpbC5nZXREb3dubG9hZFBhdXNlZE1lc3NhZ2UoY29udGV4dCksCisgICAgICAgICAgYW5kcm9pZC5SLmRyYXdhYmxlLnN0YXRfc3lzX2Rvd25sb2FkKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnROb05vdGlmaWNhdGlvbnNDYXB0dXJlZCgpIHsKKyAgICAgIExpc3Q8U3RyaW5nPiB0aXRsZU1hdGNoZXMgPSBnZXRNYXRjaGluZyhDT05URU5UX1RJVExFX1BBVFRFUk4pOworICAgICAgTGlzdDxTdHJpbmc+IHRleHRNYXRjaGVzID0gZ2V0TWF0Y2hpbmcoQ09OVEVOVF9URVhUX1BBVFRFUk4pOworICAgICAgTGlzdDxTdHJpbmc+IGljb25NYXRjaGVzID0gZ2V0TWF0Y2hpbmcoSUNPTl9QQVRURVJOKTsKKworICAgICAgYXNzZXJ0VGhhdCh0aXRsZU1hdGNoZXMpLmlzRW1wdHkoKTsKKyAgICAgIGFzc2VydFRoYXQodGV4dE1hdGNoZXMpLmlzRW1wdHkoKTsKKworICAgICAgLy8gQ2FwdHVyaW5nIHRocm91Z2ggYWRiIGluY2x1ZGVzIGluYWN0aXZlIG5vdGlmaWNhdGlvbnMgdG9vLCBzbyBqdXN0IG1ha2Ugc3VyZSBub25lIG9mIHRoZQorICAgICAgLy8gTUREIG5vdGlmaWNhdGlvbnMgd2VyZSBjYXB0dXJlc2QuCisgICAgICBhc3NlcnRUaGF0KGljb25NYXRjaGVzKQorICAgICAgICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKAorICAgICAgICAgICAgICBDb3JyZXNwb25kZW5jZS48U3RyaW5nLCBJbnRlZ2VyPnRyYW5zZm9ybWluZygKKyAgICAgICAgICAgICAgICAgIG1hdGNoIC0+IHsKKyAgICAgICAgICAgICAgICAgICAgLy8gT3VyIHJlZ2V4IHNob3VsZCBjYXB0dXJlIG9ubHkgdmFsaWQgaGV4YWRlY2ltYWwgdmFsdWVzCisgICAgICAgICAgICAgICAgICAgIGludCBpY29uUmVzSWQgPSBJbnRlZ2VyLnBhcnNlSW50KG1hdGNoLCAxNik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpY29uUmVzSWQ7CisgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgImNvbnZlcnQgdG8gcmVzb3VyY2UgaWQiKSkKKyAgICAgICAgICAuY29udGFpbnNOb25lSW4oTUREX0lDT05fSURTKTsKKyAgICB9CisKKyAgICAvLyBUT0RPKGIvMTQ4NDAxMDE2KTogUmVtb3ZlICJ1bnVzZWQiIHdoZW4gdGl0bGUvdGV4dCBjYW4gYmUgbWF0Y2hlZC4KKyAgICBwcml2YXRlIHZvaWQgYXNzZXJ0Tm90aWZpY2F0aW9uQ2FwdHVyZWRNYXRjaGVzKAorICAgICAgICBTdHJpbmcgdW51c2VkVGl0bGUsIFN0cmluZyB1bnVzZWRUZXh0LCBpbnQgaWNvbikgeworICAgICAgLyogTGlzdDxTdHJpbmc+IHRpdGxlTWF0Y2hlcyA9IGdldE1hdGNoaW5nKENPTlRFTlRfVElUTEVfUEFUVEVSTik7CisgICAgICAgKiBMaXN0PFN0cmluZz4gdGV4dE1hdGNoZXMgPSBnZXRNYXRjaGluZyhDT05URU5UX1RFWFRfUEFUVEVSTik7ICovCisgICAgICBMaXN0PFN0cmluZz4gaWNvbk1hdGNoZXMgPSBnZXRNYXRjaGluZyhJQ09OX1BBVFRFUk4pOworCisgICAgICAvLyBUT0RPKGIvMTQ4NDAxMDE2KTogRmlndXJlIG91dCBob3cgdG8gYWNjZXNzIHVucmVkYWN0ZWQgdGl0bGUgYW5kIHRleHQgY29udGVudCB0byBtYXRjaC4KKyAgICAgIC8qIGFzc2VydFRoYXQodGl0bGVNYXRjaGVzKQorICAgICAgICogICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKAorICAgICAgICogICAgICAgICBDb3JyZXNwb25kZW5jZS48U3RyaW5nLCBCb29sZWFuPnRyYW5zZm9ybWluZygKKyAgICAgICAqICAgICAgICAgICAgIG1hdGNoIC0+IG1hdGNoLmNvbnRhaW5zKHRpdGxlKSwgImlzIGEgdGl0bGUgbWF0Y2giKSkKKyAgICAgICAqICAgICAuY29udGFpbnModHJ1ZSk7CisgICAgICAgKiBhc3NlcnRUaGF0KHRleHRNYXRjaGVzKQorICAgICAgICogICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKAorICAgICAgICogICAgICAgICBDb3JyZXNwb25kZW5jZS48U3RyaW5nLCBCb29sZWFuPnRyYW5zZm9ybWluZygKKyAgICAgICAqICAgICAgICAgICAgIG1hdGNoIC0+IG1hdGNoLmNvbnRhaW5zKHRleHQpLCAiaXMgYSB0ZXh0IG1hdGNoIikpCisgICAgICAgKiAgICAgLmNvbnRhaW5zKHRydWUpOyAqLworICAgICAgYXNzZXJ0VGhhdChpY29uTWF0Y2hlcykKKyAgICAgICAgICAuY29tcGFyaW5nRWxlbWVudHNVc2luZygKKyAgICAgICAgICAgICAgQ29ycmVzcG9uZGVuY2UuPFN0cmluZywgQm9vbGVhbj50cmFuc2Zvcm1pbmcoCisgICAgICAgICAgICAgICAgICBtYXRjaCAtPiB7CisgICAgICAgICAgICAgICAgICAgIC8vIE91ciByZWdleCBzaG91bGQgY2FwdHVyZSBvbmx5IHZhbGlkIGhleGFkZWNpbWFsIHZhbHVlcworICAgICAgICAgICAgICAgICAgICBpbnQgaWNvblJlc0lkID0gSW50ZWdlci5wYXJzZUludChtYXRjaCwgMTYpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWNvblJlc0lkID09IGljb247CisgICAgICAgICAgICAgICAgICB9LAorICAgICAgICAgICAgICAgICAgImlzIGFuIGljb24gbWF0Y2giKSkKKyAgICAgICAgICAuY29udGFpbnModHJ1ZSk7CisgICAgfQorCisgICAgcHJpdmF0ZSBMaXN0PFN0cmluZz4gZ2V0TWF0Y2hpbmcoUGF0dGVybiBwYXR0ZXJuKSB7CisgICAgICBMaXN0PFN0cmluZz4gbWF0Y2hlcyA9IG5ldyBBcnJheUxpc3Q8PigpOworICAgICAgTWF0Y2hlciBtYXRjaGVyID0gcGF0dGVybi5tYXRjaGVyKG5vdGlmaWNhdGlvbk91dHB1dCk7CisgICAgICB3aGlsZSAobWF0Y2hlci5maW5kKCkpIHsKKyAgICAgICAgbWF0Y2hlcy5hZGQobWF0Y2hlci5ncm91cCgxKS50cmltKCkpOworICAgICAgfQorICAgICAgcmV0dXJuIG1hdGNoZXM7CisgICAgfQorICB9CisKKyAgLyoqCisgICAqIEltcGxlbWVudGF0aW9uIG9mIE5vdGlmaWNhdGlvbiBDYXB0dXJlIGZvciBBUEkgbGV2ZWwgMjMgKEFuZHJvaWQgTSkgYW5kIGFib3ZlLgorICAgKgorICAgKiA8cD5UaGlzIGltcGxlbWVudGF0aW9uIHJlbGllcyBvbiBjYXB0dXJpbmcgTm90aWZpY2F0aW9ucyB1c2luZyB7QGxpbmsKKyAgICogTm90aWZpY2F0aW9uTWFuYWdlciNnZXRBY3RpdmVOb3RpZmljYXRpb25zfS4gQXZhaWxhYmxlIHBhcnRzIG9mIHRoZSB7QGxpbmsgTm90aWZpY2F0aW9ufSBhcmUKKyAgICogdXNlZCB0byBjaGVjayBmb3IgbWF0Y2hpbmcgbm90aWZpY2F0aW9ucy4KKyAgICovCisgIHB1YmxpYyBzdGF0aWMgY2xhc3MgTVBsdXNOb3RpZmljYXRpb25DYXB0dXJlIGltcGxlbWVudHMgTWRkTm90aWZpY2F0aW9uQ2FwdHVyZSB7CisgICAgcHJpdmF0ZSBmaW5hbCBDb250ZXh0IGNvbnRleHQ7CisgICAgcHJpdmF0ZSBmaW5hbCBMaXN0PE5vdGlmaWNhdGlvbj4gbm90aWZpY2F0aW9uczsKKworICAgIHByaXZhdGUgTVBsdXNOb3RpZmljYXRpb25DYXB0dXJlKENvbnRleHQgY29udGV4dCwgTGlzdDxOb3RpZmljYXRpb24+IG5vdGlmaWNhdGlvbnMpIHsKKyAgICAgIFByZWNvbmRpdGlvbnMuY2hlY2tTdGF0ZSgKKyAgICAgICAgICBWRVJTSU9OLlNES19JTlQgPj0gVkVSU0lPTl9DT0RFUy5NLCAiVGhpcyBpbXBsZW1lbnRhdGlvbiBvbmx5IHdvcmtzIGZvciBNKyBkZXZpY2VzIik7CisgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OworICAgICAgdGhpcy5ub3RpZmljYXRpb25zID0gbm90aWZpY2F0aW9uczsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRTdGFydE5vdGlmaWNhdGlvbkNhcHR1cmVkKFN0cmluZyB0aXRsZSwgU3RyaW5nIHRleHQpIHsKKyAgICAgIGFzc2VydFRoYXQobm90aWZpY2F0aW9ucykKKyAgICAgICAgICAuY29tcGFyaW5nRWxlbWVudHNVc2luZygKKyAgICAgICAgICAgICAgY3JlYXRlTWF0Y2hlckZvck5vdGlmaWNhdGlvbigKKyAgICAgICAgICAgICAgICAgIHRpdGxlLCB0ZXh0LCBhbmRyb2lkLlIuZHJhd2FibGUuc3RhdF9zeXNfZG93bmxvYWQsICJpcyBhIHN0YXJ0IG5vdGlmaWNhdGlvbiIpKQorICAgICAgICAgIC5jb250YWlucyh0cnVlKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMgdm9pZCBhc3NlcnRTdWNjZXNzTm90aWZpY2F0aW9uQ2FwdHVyZWQoU3RyaW5nIHRpdGxlKSB7CisgICAgICBhc3NlcnRUaGF0KG5vdGlmaWNhdGlvbnMpCisgICAgICAgICAgLmNvbXBhcmluZ0VsZW1lbnRzVXNpbmcoCisgICAgICAgICAgICAgIGNyZWF0ZU1hdGNoZXJGb3JOb3RpZmljYXRpb24oCisgICAgICAgICAgICAgICAgICB0aXRsZSwKKyAgICAgICAgICAgICAgICAgIE5vdGlmaWNhdGlvblV0aWwuZ2V0RG93bmxvYWRTdWNjZXNzTWVzc2FnZShjb250ZXh0KSwKKyAgICAgICAgICAgICAgICAgIGFuZHJvaWQuUi5kcmF3YWJsZS5zdGF0X3N5c19kb3dubG9hZF9kb25lLAorICAgICAgICAgICAgICAgICAgImlzIGEgc3VjY2VzcyBub3RpZmljYXRpb24iKSkKKyAgICAgICAgICAuY29udGFpbnModHJ1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYXNzZXJ0RmFpbGVkTm90aWZpY2F0aW9uQ2FwdHVyZWQoU3RyaW5nIHRpdGxlKSB7CisgICAgICBhc3NlcnRUaGF0KG5vdGlmaWNhdGlvbnMpCisgICAgICAgICAgLmNvbXBhcmluZ0VsZW1lbnRzVXNpbmcoCisgICAgICAgICAgICAgIGNyZWF0ZU1hdGNoZXJGb3JOb3RpZmljYXRpb24oCisgICAgICAgICAgICAgICAgICB0aXRsZSwKKyAgICAgICAgICAgICAgICAgIE5vdGlmaWNhdGlvblV0aWwuZ2V0RG93bmxvYWRGYWlsZWRNZXNzYWdlKGNvbnRleHQpLAorICAgICAgICAgICAgICAgICAgYW5kcm9pZC5SLmRyYXdhYmxlLnN0YXRfc3lzX3dhcm5pbmcsCisgICAgICAgICAgICAgICAgICAiaXMgYSBmYWlsZWQgbm90aWZpY2F0aW9uIikpCisgICAgICAgICAgLmNvbnRhaW5zKHRydWUpOworICAgIH0KKworICAgIEBPdmVycmlkZQorICAgIHB1YmxpYyB2b2lkIGFzc2VydFBhdXNlZE5vdGlmaWNhdGlvbkNhcHR1cmVkKFN0cmluZyB0aXRsZSkgeworICAgICAgYXNzZXJ0VGhhdChub3RpZmljYXRpb25zKQorICAgICAgICAgIC5jb21wYXJpbmdFbGVtZW50c1VzaW5nKAorICAgICAgICAgICAgICBjcmVhdGVNYXRjaGVyRm9yTm90aWZpY2F0aW9uKAorICAgICAgICAgICAgICAgICAgdGl0bGUsCisgICAgICAgICAgICAgICAgICBOb3RpZmljYXRpb25VdGlsLmdldERvd25sb2FkUGF1c2VkTWVzc2FnZShjb250ZXh0KSwKKyAgICAgICAgICAgICAgICAgIGFuZHJvaWQuUi5kcmF3YWJsZS5zdGF0X3N5c19kb3dubG9hZCwKKyAgICAgICAgICAgICAgICAgICJpcyBhIHBhdXNlZCBub3RpZmljYXRpb24iKSkKKyAgICAgICAgICAuY29udGFpbnModHJ1ZSk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHVibGljIHZvaWQgYXNzZXJ0Tm9Ob3RpZmljYXRpb25zQ2FwdHVyZWQoKSB7CisgICAgICBhc3NlcnRUaGF0KG5vdGlmaWNhdGlvbnMpLmlzRW1wdHkoKTsKKyAgICB9CisKKyAgICBwcml2YXRlIHN0YXRpYyBDb3JyZXNwb25kZW5jZTxOb3RpZmljYXRpb24sIEJvb2xlYW4+IGNyZWF0ZU1hdGNoZXJGb3JOb3RpZmljYXRpb24oCisgICAgICAgIFN0cmluZyB0aXRsZSwgU3RyaW5nIHRleHQsIGludCBpY29uLCBTdHJpbmcgdGFnKSB7CisgICAgICByZXR1cm4gQ29ycmVzcG9uZGVuY2UudHJhbnNmb3JtaW5nKAorICAgICAgICAgIChATnVsbGFibGUgTm90aWZpY2F0aW9uIGFjdHVhbCkgLT4geworICAgICAgICAgICAgaWYgKGFjdHVhbCA9PSBudWxsKSB7CisgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgYm9vbGVhbiBtYXRjaGVzID0KKyAgICAgICAgICAgICAgICBTdHJpbmcudmFsdWVPZihhY3R1YWwuZXh0cmFzLmdldENoYXJTZXF1ZW5jZSgiYW5kcm9pZC50aXRsZSIpKS5lcXVhbHModGl0bGUpCisgICAgICAgICAgICAgICAgICAgICYmIFN0cmluZy52YWx1ZU9mKGFjdHVhbC5leHRyYXMuZ2V0Q2hhclNlcXVlbmNlKCJhbmRyb2lkLnRleHQiKSkuZXF1YWxzKHRleHQpCisgICAgICAgICAgICAgICAgICAgICYmIChhY3R1YWwuZ2V0U21hbGxJY29uKCkuZ2V0UmVzSWQoKSA9PSBpY29uKTsKKyAgICAgICAgICAgIHJldHVybiBtYXRjaGVzOworICAgICAgICAgIH0sCisgICAgICAgICAgdGFnKTsKKyAgICB9CisgIH0KK30KZGlmZiAtLWdpdCBhL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL1JvYm9sZWN0cmljRmlsZURvd25sb2FkZXIuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL1JvYm9sZWN0cmljRmlsZURvd25sb2FkZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MDRjMTUxCi0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RpbmcvUm9ib2xlY3RyaWNGaWxlRG93bmxvYWRlci5qYXZhCkBAIC0wLDAgKzEsODAgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRlc3Rpbmc7CisKK2ltcG9ydCBzdGF0aWMgY29tLmdvb2dsZS5jb21tb24udXRpbC5jb25jdXJyZW50LkZ1dHVyZXMuaW1tZWRpYXRlVm9pZEZ1dHVyZTsKKworaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5GaWxlVXJpOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5hYmxlRnV0dXJlOworaW1wb3J0IGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5MaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2U7CitpbXBvcnQgY29tLmdvb2dsZS5kZXZ0b29scy5idWlsZC5ydW50aW1lLlJ1bmZpbGVzUGF0aHM7CitpbXBvcnQgamF2YS5uaW8uZmlsZS5QYXRoOworCisvKioKKyAqIEEge0BsaW5rIEZpbGVEb3dubG9hZGVyfSBzdWl0YWJsZSBmb3IgdXNlIGluIFJvYm9sZWN0cmljIHRlc3RzIHRoYXQgImRvd25sb2FkcyIgYnkgY29weWluZyB0aGUKKyAqIGZpbGUgZnJvbSB0aGUgdGVzdGRhdGEgZm9sZGVyLgorICoKKyAqIDxwPlRoZSBmaWxlbmFtZSBpcyB0aGUgTGFzdCBQYXRoIFNlZ21lbnQgb2YgdGhlIHVybFRvRG93bmxvYWQuIEZvciBleGFtcGxlLCB0aGUgVVJMCisgKiBodHRwczovL3d3dy5nc3RhdGljLmNvbS9pY2luZy9pZGQvc2FtcGxlX2dyb3VwL3N0ZXAxLnR4dCB3aWxsIGJlIG1hcHBlZCB0byB0aGUgZmlsZQorICogdGVzdFNyY0RpcmVjdG9yeS90ZXN0RGF0YVJlbGF0aXZlUGF0aC9zdGVwMS50eHQuIFNlZSA8aW50ZXJuYWw+IGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9uCisgKiBwcm92aWRpbmcgZGF0YSBmaWxlcyBmb3IgdGVzdHMuCisgKgorICogPHA+Tm90ZSB0aGF0IFRlc3RGaWxlRG93bmxvYWRlciBpZ25vcmVzIHRoZSBEb3dubG9hZENvbmRpdGlvbnMuCisgKi8KK3B1YmxpYyBmaW5hbCBjbGFzcyBSb2JvbGVjdHJpY0ZpbGVEb3dubG9hZGVyIGltcGxlbWVudHMgRmlsZURvd25sb2FkZXIgeworCisgIHByaXZhdGUgZmluYWwgU3RyaW5nIHRlc3REYXRhUmVsYXRpdmVQYXRoOworICBwcml2YXRlIGZpbmFsIEZpbGVEb3dubG9hZGVyIGRlbGVnYXRlRG93bmxvYWRlcjsKKworICBwdWJsaWMgUm9ib2xlY3RyaWNGaWxlRG93bmxvYWRlcigKKyAgICAgIFN0cmluZyB0ZXN0RGF0YVJlbGF0aXZlUGF0aCwKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsCisgICAgICBMaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3IpIHsKKyAgICB0aGlzLnRlc3REYXRhUmVsYXRpdmVQYXRoID0gdGVzdERhdGFSZWxhdGl2ZVBhdGg7CisgICAgdGhpcy5kZWxlZ2F0ZURvd25sb2FkZXIgPSBuZXcgTG9jYWxGaWxlRG93bmxvYWRlcihmaWxlU3RvcmFnZSwgZXhlY3V0b3IpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHN0YXJ0RG93bmxvYWRpbmcoRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCkgeworICAgIFVyaSBmaWxlVXJpID0gZG93bmxvYWRSZXF1ZXN0LmZpbGVVcmkoKTsKKyAgICBTdHJpbmcgdXJsVG9Eb3dubG9hZCA9IGRvd25sb2FkUmVxdWVzdC51cmxUb0Rvd25sb2FkKCk7CisgICAgRG93bmxvYWRDb25zdHJhaW50cyBkb3dubG9hZENvbnN0cmFpbnRzID0gZG93bmxvYWRSZXF1ZXN0LmRvd25sb2FkQ29uc3RyYWludHMoKTsKKworICAgIC8vIFdlIG5lZWQgdG8gdHJhbnNsYXRlIHRoZSByZWFsIHVybFRvRG93bmxvYWQgdG8gdGhlIG9uZSByZXByZXNlbnRpbmcgdGhlIGxvY2FsIGZpbGUgaW4KKyAgICAvLyB0ZXN0ZGF0YSBmb2xkZXIuCisgICAgVXJpIHVyaVRvRG93bmxvYWQgPSBVcmkucGFyc2UodXJsVG9Eb3dubG9hZC50cmltKCkpOworICAgIGlmICh1cmlUb0Rvd25sb2FkID09IG51bGwpIHsKKyAgICAgIHJldHVybiBpbW1lZGlhdGVWb2lkRnV0dXJlKCk7CisgICAgfQorCisgICAgUGF0aCB0ZXN0RGF0YVBhdGggPSBSdW5maWxlc1BhdGhzLnJlc29sdmUodGVzdERhdGFSZWxhdGl2ZVBhdGgpOworICAgIFBhdGggdXJpVG9Eb3dubG9hZFBhdGggPSB0ZXN0RGF0YVBhdGgucmVzb2x2ZSh1cmlUb0Rvd25sb2FkLmdldExhc3RQYXRoU2VnbWVudCgpKTsKKworICAgIFN0cmluZyB0ZXN0RGF0YVVybCA9IEZpbGVVcmkuYnVpbGRlcigpLnNldFBhdGgodXJpVG9Eb3dubG9hZFBhdGgudG9TdHJpbmcoKSkuYnVpbGQoKS50b1N0cmluZygpOworCisgICAgcmV0dXJuIGRlbGVnYXRlRG93bmxvYWRlci5zdGFydERvd25sb2FkaW5nKAorICAgICAgICBEb3dubG9hZFJlcXVlc3QubmV3QnVpbGRlcigpCisgICAgICAgICAgICAuc2V0RmlsZVVyaShmaWxlVXJpKQorICAgICAgICAgICAgLnNldFVybFRvRG93bmxvYWQodGVzdERhdGFVcmwpCisgICAgICAgICAgICAuc2V0RG93bmxvYWRDb25zdHJhaW50cyhkb3dubG9hZENvbnN0cmFpbnRzKQorICAgICAgICAgICAgLmJ1aWxkKCkpOworICB9Cit9CmRpZmYgLS1naXQgYS9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZy9UZXN0RmlsZURvd25sb2FkZXIuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL1Rlc3RGaWxlRG93bmxvYWRlci5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiNDJjMWEKLS0tIC9kZXYvbnVsbAorKysgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZy9UZXN0RmlsZURvd25sb2FkZXIuamF2YQpAQCAtMCwwICsxLDkwIEBACisvKgorICogQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworICoKKyAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisgKgorICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKyAqCisgKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisgKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisgKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisgKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKyAqLworcGFja2FnZSBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC50ZXN0aW5nOworCitpbXBvcnQgc3RhdGljIGNvbS5nb29nbGUuY29tbW9uLnV0aWwuY29uY3VycmVudC5GdXR1cmVzLmltbWVkaWF0ZVZvaWRGdXR1cmU7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC5vcy5FbnZpcm9ubWVudDsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5kb3dubG9hZGVyLkRvd25sb2FkQ29uc3RyYWludHM7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5Eb3dubG9hZFJlcXVlc3Q7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZG93bmxvYWRlci5GaWxlRG93bmxvYWRlcjsKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5maWxlLlN5bmNocm9ub3VzRmlsZVN0b3JhZ2U7CitpbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tb2JpbGVkYXRhZG93bmxvYWQuZmlsZS5iYWNrZW5kcy5GaWxlVXJpOworaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLmludGVybmFsLmxvZ2dpbmcuTG9nVXRpbDsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuYWJsZUZ1dHVyZTsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi51dGlsLmNvbmN1cnJlbnQuTGlzdGVuaW5nRXhlY3V0b3JTZXJ2aWNlOworCisvKioKKyAqIEEge0BsaW5rIEZpbGVEb3dubG9hZGVyfSB0aGF0ICJkb3dubG9hZHMiIGJ5IGNvcHlpbmcgdGhlIGZpbGUgZnJvbSB0aGUgdGVzdGRhdGEgZm9sZGVyLgorICoKKyAqIDxwPlRoZSBmaWxlbmFtZSBpcyB0aGUgTGFzdCBQYXRoIFNlZ21lbnQgb2YgdGhlIHVybFRvRG93bmxvYWQuIEZvciBleGFtcGxlLCB0aGUgVVJMCisgKiBodHRwczovL3d3dy5nc3RhdGljLmNvbS9pY2luZy9pZGQvc2FtcGxlX2dyb3VwL3N0ZXAxLnR4dCB3aWxsIGJlIG1hcHBlZCB0byB0aGUgZmlsZQorICogdGVzdERhdGFBYnNvbHV0ZVBhdGgvc3RlcDEudHh0LgorICoKKyAqIDxwPk5vdGUgdGhhdCBUZXN0RmlsZURvd25sb2FkZXIgaWdub3JlcyB0aGUgRG93bmxvYWRDb25kaXRpb25zLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgVGVzdEZpbGVEb3dubG9hZGVyIGltcGxlbWVudHMgRmlsZURvd25sb2FkZXIgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiVGVzdERhdGFGaWxlRG93bmxvYWRlciI7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEdPT0dMRTNfQUJTT0xVVEVfUEFUSCA9CisgICAgICBFbnZpcm9ubWVudC5nZXRFeHRlcm5hbFN0b3JhZ2VEaXJlY3RvcnkoKSArICIvZ29vZ2xldGVzdC90ZXN0X3J1bmZpbGVzL2dvb2dsZTMvIjsKKworICBwcml2YXRlIGZpbmFsIFN0cmluZyB0ZXN0RGF0YUFic29sdXRlUGF0aDsKKyAgcHJpdmF0ZSBmaW5hbCBGaWxlRG93bmxvYWRlciBkZWxlZ2F0ZURvd25sb2FkZXI7CisKKyAgcHVibGljIFRlc3RGaWxlRG93bmxvYWRlcigKKyAgICAgIFN0cmluZyB0ZXN0RGF0YVJlbGF0aXZlUGF0aCwKKyAgICAgIFN5bmNocm9ub3VzRmlsZVN0b3JhZ2UgZmlsZVN0b3JhZ2UsCisgICAgICBMaXN0ZW5pbmdFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3IpIHsKKyAgICB0aGlzLnRlc3REYXRhQWJzb2x1dGVQYXRoID0gR09PR0xFM19BQlNPTFVURV9QQVRIICsgdGVzdERhdGFSZWxhdGl2ZVBhdGg7CisgICAgdGhpcy5kZWxlZ2F0ZURvd25sb2FkZXIgPSBuZXcgTG9jYWxGaWxlRG93bmxvYWRlcihmaWxlU3RvcmFnZSwgZXhlY3V0b3IpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBMaXN0ZW5hYmxlRnV0dXJlPFZvaWQ+IHN0YXJ0RG93bmxvYWRpbmcoRG93bmxvYWRSZXF1ZXN0IGRvd25sb2FkUmVxdWVzdCkgeworICAgIFVyaSBmaWxlVXJpID0gZG93bmxvYWRSZXF1ZXN0LmZpbGVVcmkoKTsKKyAgICBTdHJpbmcgdXJsVG9Eb3dubG9hZCA9IGRvd25sb2FkUmVxdWVzdC51cmxUb0Rvd25sb2FkKCk7CisgICAgRG93bmxvYWRDb25zdHJhaW50cyBkb3dubG9hZENvbnN0cmFpbnRzID0gZG93bmxvYWRSZXF1ZXN0LmRvd25sb2FkQ29uc3RyYWludHMoKTsKKworICAgIC8vIFdlIG5lZWQgdG8gdHJhbnNsYXRlIHRoZSByZWFsIHVybFRvRG93bmxvYWQgdG8gdGhlIG9uZSByZXByZXNlbnRpbmcgdGhlIGxvY2FsIGZpbGUgaW4KKyAgICAvLyB0ZXN0ZGF0YSBmb2xkZXIuCisgICAgVXJpIHVyaVRvRG93bmxvYWQgPSBVcmkucGFyc2UodXJsVG9Eb3dubG9hZC50cmltKCkpOworICAgIGlmICh1cmlUb0Rvd25sb2FkID09IG51bGwpIHsKKyAgICAgIExvZ1V0aWwuZSgiJXM6IEludmFsaWQgdXJsVG9Eb3dubG9hZCAlcyIsIFRBRywgdXJsVG9Eb3dubG9hZCk7CisgICAgICByZXR1cm4gaW1tZWRpYXRlVm9pZEZ1dHVyZSgpOworICAgIH0KKyAgICBpZiAodXJpVG9Eb3dubG9hZC5nZXRQYXRoKCkuZW5kc1dpdGgoIm9kd3MxX2VtcHR5LmphciIpKSB7CisgICAgICAvLyBUT0RPKGIvMjIyNTE5MDc3KTogdGhpcyBpcyBuZWNlc3NhcnkgdG8gYWRhcHQgdGhlIHJlYWwgZmlsZSBVUkwgdG8gbG9jYWwgdGVzdGRhdGEKKyAgICAgIHVyaVRvRG93bmxvYWQgPQorICAgICAgICAgIFVyaS5wYXJzZSh1cmlUb0Rvd25sb2FkLmdldFBhdGgoKS5zdWJzdHJpbmcoMCwgdXJpVG9Eb3dubG9hZC5nZXRQYXRoKCkubGVuZ3RoKCkgLSA0KSk7CisgICAgfQorCisgICAgU3RyaW5nIHRlc3REYXRhVXJsID0KKyAgICAgICAgRmlsZVVyaS5idWlsZGVyKCkKKyAgICAgICAgICAgIC5zZXRQYXRoKHRlc3REYXRhQWJzb2x1dGVQYXRoICsgdXJpVG9Eb3dubG9hZC5nZXRMYXN0UGF0aFNlZ21lbnQoKSkKKyAgICAgICAgICAgIC5idWlsZCgpCisgICAgICAgICAgICAudG9TdHJpbmcoKTsKKworICAgIHJldHVybiBkZWxlZ2F0ZURvd25sb2FkZXIuc3RhcnREb3dubG9hZGluZygKKyAgICAgICAgRG93bmxvYWRSZXF1ZXN0Lm5ld0J1aWxkZXIoKQorICAgICAgICAgICAgLnNldEZpbGVVcmkoZmlsZVVyaSkKKyAgICAgICAgICAgIC5zZXRVcmxUb0Rvd25sb2FkKHRlc3REYXRhVXJsKQorICAgICAgICAgICAgLnNldERvd25sb2FkQ29uc3RyYWludHMoZG93bmxvYWRDb25zdHJhaW50cykKKyAgICAgICAgICAgIC5idWlsZCgpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RpbmcvVGVzdEZsYWdzLmphdmEgYi9qYXZhdGVzdHMvY29tL2dvb2dsZS9hbmRyb2lkL2xpYnJhcmllcy9tb2JpbGVkYXRhZG93bmxvYWQvdGVzdGluZy9UZXN0RmxhZ3MuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NWM5NjQ4Ci0tLSAvZGV2L251bGwKKysrIGIvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RpbmcvVGVzdEZsYWdzLmphdmEKQEAgLTAsMCArMSw0MTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRlc3Rpbmc7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1vYmlsZWRhdGFkb3dubG9hZC5GbGFnczsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworCisvKiogRGVmYXVsdCB7QGxpbmsgRmxhZ3N9IHdpdGggc2ltcGxlIG92ZXJyaWRlcyBmb3IgZWFzZSBvZiB0ZXN0aW5nLiAqLworcHVibGljIGZpbmFsIGNsYXNzIFRlc3RGbGFncyBpbXBsZW1lbnRzIEZsYWdzIHsKKworICBwdWJsaWMgT3B0aW9uYWw8Qm9vbGVhbj4gY2xlYXJTdGF0ZU9uTWRkRGlzYWJsZWQgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IG1kZERlbGV0ZUdyb3Vwc1JlbW92ZWRBY2NvdW50cyA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8Qm9vbGVhbj4gYnJvYWRjYXN0TmV3bHlEb3dubG9hZGVkR3JvdXBzID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBsb2dGaWxlR3JvdXBzV2l0aEZpbGVzTWlzc2luZyA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8Qm9vbGVhbj4gZGVsZXRlRmlsZUdyb3Vwc1dpdGhGaWxlc01pc3NpbmcgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IGR1bXBNZGRJbmZvID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBlbmFibGVEZWJ1Z1VpID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBlbmFibGVDbGllbnRFcnJvckxvZ2dpbmcgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEludGVnZXI+IGZpbGVLZXlWZXJzaW9uID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiB0ZXN0T25seUZpbGVLZXlWZXJzaW9uID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBlbmFibGVDb21wcmVzc2VkRmlsZSA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8Qm9vbGVhbj4gZW5hYmxlWmlwRm9sZGVyID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBlbmFibGVEZWx0YURvd25sb2FkID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBlbmFibGVNZGRHY21TZXJ2aWNlID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBlbmFibGVTaWxlbnRGZWVkYmFjayA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8Qm9vbGVhbj4gbWlncmF0ZVRvTmV3RmlsZUtleSA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8Qm9vbGVhbj4gbWlncmF0ZUZpbGVFeHBpcmF0aW9uUG9saWN5ID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBkb3dubG9hZEZpcnN0T25XaWZpVGhlbk9uQW55TmV0d29yayA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8Qm9vbGVhbj4gbG9nU3RvcmFnZVN0YXRzID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBsb2dOZXR3b3JrU3RhdHMgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IHJlbW92ZUdyb3Vwa2V5c1dpdGhEb3dubG9hZGVkRmllbGROb3RTZXQgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IGNhY2hlTGFzdExvY2F0aW9uID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxJbnRlZ2VyPiBsb2NhdGlvbkN1c3RvbVBhcmFtUzJMZXZlbCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8SW50ZWdlcj4gbG9jYXRpb25UYXNrVGltZW91dFNlYyA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8Qm9vbGVhbj4gYWRkQ29uZmlnc0Zyb21QaGVub3R5cGUgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IGVuYWJsZU1vYmlsZURhdGFEb3dubG9hZCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8SW50ZWdlcj4gbWRkUmVzZXRUcmlnZ2VyID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBtZGRFbmFibGVEb3dubG9hZFBlbmRpbmdHcm91cHMgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IG1kZEVuYWJsZVZlcmlmeVBlbmRpbmdHcm91cHMgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IG1kZEVuYWJsZUdhcmJhZ2VDb2xsZWN0aW9uID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBtZGREZWxldGVVbmluc3RhbGxlZEFwcHMgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IGVuYWJsZU1vYnN0b3JlRmlsZVNlcnZpY2UgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IGVuYWJsZURlbGF5ZWREb3dubG9hZCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8Qm9vbGVhbj4gZ2NtUmVzY2hlZHVsZU9ubHlPbmNlUGVyUHJvY2Vzc1N0YXJ0ID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBnbXNNZGRTd2l0Y2hUb0Nyb25ldCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8Qm9vbGVhbj4gZW5hYmxlRGF5c1NpbmNlTGFzdE1haW50ZW5hbmNlVHJhY2tpbmcgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IGVuYWJsZVNpZGVsb2FkaW5nID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBlbmFibGVEb3dubG9hZFN0YWdlRXhwZXJpbWVudElkUHJvcGFnYXRpb24gPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IGVuYWJsZUlzb2xhdGVkU3RydWN0dXJlVmVyaWZpY2F0aW9uID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxCb29sZWFuPiBlbmFibGVSbmdCYXNlZERldmljZVN0YWJsZVNhbXBsaW5nID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxMb25nPiBtYWludGVuYW5jZUdjbVRhc2tQZXJpb2QgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPExvbmc+IGNoYXJnaW5nR2NtVGFza1BlcmlvZCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8TG9uZz4gY2VsbHVsYXJDaGFyZ2luZ0djbVRhc2tQZXJpb2QgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPExvbmc+IHdpZmlDaGFyZ2luZ0djbVRhc2tQZXJpb2QgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEludGVnZXI+IG1kZERlZmF1bHRTYW1wbGVJbnRlcnZhbCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8SW50ZWdlcj4gbWRkRG93bmxvYWRFdmVudHNTYW1wbGVJbnRlcnZhbCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8SW50ZWdlcj4gZ3JvdXBTdGF0c0xvZ2dpbmdTYW1wbGVJbnRlcnZhbCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8SW50ZWdlcj4gYXBpTG9nZ2luZ1NhbXBsZUludGVydmFsID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxJbnRlZ2VyPiBjbGVhbnVwTG9nTG9nZ2luZ1NhbXBsZUludGVydmFsID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxJbnRlZ2VyPiBzaWxlbnRGZWVkYmFja1NhbXBsZUludGVydmFsID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxJbnRlZ2VyPiBzdG9yYWdlU3RhdHNMb2dnaW5nU2FtcGxlSW50ZXJ2YWwgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEludGVnZXI+IG5ldHdvcmtTdGF0c0xvZ2dpbmdTYW1wbGVJbnRlcnZhbCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8SW50ZWdlcj4gbW9ic3RvcmVGaWxlU2VydmljZVN0YXRzU2FtcGxlSW50ZXJ2YWwgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEludGVnZXI+IG1kZEFuZHJvaWRTaGFyaW5nU2FtcGxlSW50ZXJ2YWwgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IGRvd25sb2FkZXJFbmZvcmNlSHR0cHMgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEJvb2xlYW4+IGVuZm9yY2VMb3dTdG9yYWdlQmVoYXZpb3IgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEludGVnZXI+IGFic0ZyZWVTcGFjZUFmdGVyRG93bmxvYWQgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEludGVnZXI+IGFic0ZyZWVTcGFjZUFmdGVyRG93bmxvYWRMb3dTdG9yYWdlQWxsb3dlZCA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8SW50ZWdlcj4gYWJzRnJlZVNwYWNlQWZ0ZXJEb3dubG9hZEV4dHJlbWVseUxvd1N0b3JhZ2VBbGxvd2VkID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxGbG9hdD4gZnJhY3Rpb25GcmVlU3BhY2VBZnRlckRvd25sb2FkID0gT3B0aW9uYWwuYWJzZW50KCk7CisgIHB1YmxpYyBPcHRpb25hbDxJbnRlZ2VyPiB0aW1lVG9XYWl0Rm9yRG93bmxvYWRlciA9IE9wdGlvbmFsLmFic2VudCgpOworICBwdWJsaWMgT3B0aW9uYWw8SW50ZWdlcj4gZG93bmxvYWRlck1heFRocmVhZHMgPSBPcHRpb25hbC5hYnNlbnQoKTsKKyAgcHVibGljIE9wdGlvbmFsPEludGVnZXI+IGRvd25sb2FkZXJNYXhSZXRyeU9uQ2hlY2tzdW1NaXNtYXRjaENvdW50ID0gT3B0aW9uYWwuYWJzZW50KCk7CisKKyAgcHJpdmF0ZSBmaW5hbCBGbGFncyBkZWxlZ2F0ZSA9IG5ldyBGbGFncygpIHt9OworCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBjbGVhclN0YXRlT25NZGREaXNhYmxlZCgpIHsKKyAgICByZXR1cm4gY2xlYXJTdGF0ZU9uTWRkRGlzYWJsZWQub3IoZGVsZWdhdGUuY2xlYXJTdGF0ZU9uTWRkRGlzYWJsZWQoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gbWRkRGVsZXRlR3JvdXBzUmVtb3ZlZEFjY291bnRzKCkgeworICAgIHJldHVybiBtZGREZWxldGVHcm91cHNSZW1vdmVkQWNjb3VudHMub3IoZGVsZWdhdGUubWRkRGVsZXRlR3JvdXBzUmVtb3ZlZEFjY291bnRzKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGJyb2FkY2FzdE5ld2x5RG93bmxvYWRlZEdyb3VwcygpIHsKKyAgICByZXR1cm4gYnJvYWRjYXN0TmV3bHlEb3dubG9hZGVkR3JvdXBzLm9yKGRlbGVnYXRlLmJyb2FkY2FzdE5ld2x5RG93bmxvYWRlZEdyb3VwcygpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBsb2dGaWxlR3JvdXBzV2l0aEZpbGVzTWlzc2luZygpIHsKKyAgICByZXR1cm4gbG9nRmlsZUdyb3Vwc1dpdGhGaWxlc01pc3Npbmcub3IoZGVsZWdhdGUubG9nRmlsZUdyb3Vwc1dpdGhGaWxlc01pc3NpbmcoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZGVsZXRlRmlsZUdyb3Vwc1dpdGhGaWxlc01pc3NpbmcoKSB7CisgICAgcmV0dXJuIGRlbGV0ZUZpbGVHcm91cHNXaXRoRmlsZXNNaXNzaW5nLm9yKGRlbGVnYXRlLmRlbGV0ZUZpbGVHcm91cHNXaXRoRmlsZXNNaXNzaW5nKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGR1bXBNZGRJbmZvKCkgeworICAgIHJldHVybiBkdW1wTWRkSW5mby5vcihkZWxlZ2F0ZS5kdW1wTWRkSW5mbygpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlbmFibGVEZWJ1Z1VpKCkgeworICAgIHJldHVybiBlbmFibGVEZWJ1Z1VpLm9yKGRlbGVnYXRlLmVuYWJsZURlYnVnVWkoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZW5hYmxlQ2xpZW50RXJyb3JMb2dnaW5nKCkgeworICAgIHJldHVybiBlbmFibGVDbGllbnRFcnJvckxvZ2dpbmcub3IoZGVsZWdhdGUuZW5hYmxlQ2xpZW50RXJyb3JMb2dnaW5nKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgZmlsZUtleVZlcnNpb24oKSB7CisgICAgcmV0dXJuIGZpbGVLZXlWZXJzaW9uLm9yKGRlbGVnYXRlLmZpbGVLZXlWZXJzaW9uKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIHRlc3RPbmx5RmlsZUtleVZlcnNpb24oKSB7CisgICAgcmV0dXJuIHRlc3RPbmx5RmlsZUtleVZlcnNpb24ub3IoZGVsZWdhdGUudGVzdE9ubHlGaWxlS2V5VmVyc2lvbigpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlbmFibGVDb21wcmVzc2VkRmlsZSgpIHsKKyAgICByZXR1cm4gZW5hYmxlQ29tcHJlc3NlZEZpbGUub3IoZGVsZWdhdGUuZW5hYmxlQ29tcHJlc3NlZEZpbGUoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZW5hYmxlWmlwRm9sZGVyKCkgeworICAgIHJldHVybiBlbmFibGVaaXBGb2xkZXIub3IoZGVsZWdhdGUuZW5hYmxlWmlwRm9sZGVyKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVuYWJsZURlbHRhRG93bmxvYWQoKSB7CisgICAgcmV0dXJuIGVuYWJsZURlbHRhRG93bmxvYWQub3IoZGVsZWdhdGUuZW5hYmxlRGVsdGFEb3dubG9hZCgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlbmFibGVNZGRHY21TZXJ2aWNlKCkgeworICAgIHJldHVybiBlbmFibGVNZGRHY21TZXJ2aWNlLm9yKGRlbGVnYXRlLmVuYWJsZU1kZEdjbVNlcnZpY2UoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZW5hYmxlU2lsZW50RmVlZGJhY2soKSB7CisgICAgcmV0dXJuIGVuYWJsZVNpbGVudEZlZWRiYWNrLm9yKGRlbGVnYXRlLmVuYWJsZVNpbGVudEZlZWRiYWNrKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIG1pZ3JhdGVUb05ld0ZpbGVLZXkoKSB7CisgICAgcmV0dXJuIG1pZ3JhdGVUb05ld0ZpbGVLZXkub3IoZGVsZWdhdGUubWlncmF0ZVRvTmV3RmlsZUtleSgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBtaWdyYXRlRmlsZUV4cGlyYXRpb25Qb2xpY3koKSB7CisgICAgcmV0dXJuIG1pZ3JhdGVGaWxlRXhwaXJhdGlvblBvbGljeS5vcihkZWxlZ2F0ZS5taWdyYXRlRmlsZUV4cGlyYXRpb25Qb2xpY3koKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZG93bmxvYWRGaXJzdE9uV2lmaVRoZW5PbkFueU5ldHdvcmsoKSB7CisgICAgcmV0dXJuIGRvd25sb2FkRmlyc3RPbldpZmlUaGVuT25BbnlOZXR3b3JrLm9yKGRlbGVnYXRlLmRvd25sb2FkRmlyc3RPbldpZmlUaGVuT25BbnlOZXR3b3JrKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGxvZ1N0b3JhZ2VTdGF0cygpIHsKKyAgICByZXR1cm4gbG9nU3RvcmFnZVN0YXRzLm9yKGRlbGVnYXRlLmxvZ1N0b3JhZ2VTdGF0cygpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBsb2dOZXR3b3JrU3RhdHMoKSB7CisgICAgcmV0dXJuIGxvZ05ldHdvcmtTdGF0cy5vcihkZWxlZ2F0ZS5sb2dOZXR3b3JrU3RhdHMoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gcmVtb3ZlR3JvdXBrZXlzV2l0aERvd25sb2FkZWRGaWVsZE5vdFNldCgpIHsKKyAgICByZXR1cm4gcmVtb3ZlR3JvdXBrZXlzV2l0aERvd25sb2FkZWRGaWVsZE5vdFNldC5vcigKKyAgICAgICAgZGVsZWdhdGUucmVtb3ZlR3JvdXBrZXlzV2l0aERvd25sb2FkZWRGaWVsZE5vdFNldCgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBjYWNoZUxhc3RMb2NhdGlvbigpIHsKKyAgICByZXR1cm4gY2FjaGVMYXN0TG9jYXRpb24ub3IoZGVsZWdhdGUuY2FjaGVMYXN0TG9jYXRpb24oKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBsb2NhdGlvbkN1c3RvbVBhcmFtUzJMZXZlbCgpIHsKKyAgICByZXR1cm4gbG9jYXRpb25DdXN0b21QYXJhbVMyTGV2ZWwub3IoZGVsZWdhdGUubG9jYXRpb25DdXN0b21QYXJhbVMyTGV2ZWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBsb2NhdGlvblRhc2tUaW1lb3V0U2VjKCkgeworICAgIHJldHVybiBsb2NhdGlvblRhc2tUaW1lb3V0U2VjLm9yKGRlbGVnYXRlLmxvY2F0aW9uVGFza1RpbWVvdXRTZWMoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gYWRkQ29uZmlnc0Zyb21QaGVub3R5cGUoKSB7CisgICAgcmV0dXJuIGFkZENvbmZpZ3NGcm9tUGhlbm90eXBlLm9yKGRlbGVnYXRlLmFkZENvbmZpZ3NGcm9tUGhlbm90eXBlKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVuYWJsZU1vYmlsZURhdGFEb3dubG9hZCgpIHsKKyAgICByZXR1cm4gZW5hYmxlTW9iaWxlRGF0YURvd25sb2FkLm9yKGRlbGVnYXRlLmVuYWJsZU1vYmlsZURhdGFEb3dubG9hZCgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgaW50IG1kZFJlc2V0VHJpZ2dlcigpIHsKKyAgICByZXR1cm4gbWRkUmVzZXRUcmlnZ2VyLm9yKGRlbGVnYXRlLm1kZFJlc2V0VHJpZ2dlcigpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBtZGRFbmFibGVEb3dubG9hZFBlbmRpbmdHcm91cHMoKSB7CisgICAgcmV0dXJuIG1kZEVuYWJsZURvd25sb2FkUGVuZGluZ0dyb3Vwcy5vcihkZWxlZ2F0ZS5tZGRFbmFibGVEb3dubG9hZFBlbmRpbmdHcm91cHMoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gbWRkRW5hYmxlVmVyaWZ5UGVuZGluZ0dyb3VwcygpIHsKKyAgICByZXR1cm4gbWRkRW5hYmxlVmVyaWZ5UGVuZGluZ0dyb3Vwcy5vcihkZWxlZ2F0ZS5tZGRFbmFibGVWZXJpZnlQZW5kaW5nR3JvdXBzKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIG1kZEVuYWJsZUdhcmJhZ2VDb2xsZWN0aW9uKCkgeworICAgIHJldHVybiBtZGRFbmFibGVHYXJiYWdlQ29sbGVjdGlvbi5vcihkZWxlZ2F0ZS5tZGRFbmFibGVHYXJiYWdlQ29sbGVjdGlvbigpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBtZGREZWxldGVVbmluc3RhbGxlZEFwcHMoKSB7CisgICAgcmV0dXJuIG1kZERlbGV0ZVVuaW5zdGFsbGVkQXBwcy5vcihkZWxlZ2F0ZS5tZGREZWxldGVVbmluc3RhbGxlZEFwcHMoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZW5hYmxlTW9ic3RvcmVGaWxlU2VydmljZSgpIHsKKyAgICByZXR1cm4gZW5hYmxlTW9ic3RvcmVGaWxlU2VydmljZS5vcihkZWxlZ2F0ZS5lbmFibGVNb2JzdG9yZUZpbGVTZXJ2aWNlKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVuYWJsZURlbGF5ZWREb3dubG9hZCgpIHsKKyAgICByZXR1cm4gZW5hYmxlRGVsYXllZERvd25sb2FkLm9yKGRlbGVnYXRlLmVuYWJsZURlbGF5ZWREb3dubG9hZCgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBnY21SZXNjaGVkdWxlT25seU9uY2VQZXJQcm9jZXNzU3RhcnQoKSB7CisgICAgcmV0dXJuIGdjbVJlc2NoZWR1bGVPbmx5T25jZVBlclByb2Nlc3NTdGFydC5vcihkZWxlZ2F0ZS5nY21SZXNjaGVkdWxlT25seU9uY2VQZXJQcm9jZXNzU3RhcnQoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZ21zTWRkU3dpdGNoVG9Dcm9uZXQoKSB7CisgICAgcmV0dXJuIGdtc01kZFN3aXRjaFRvQ3JvbmV0Lm9yKGRlbGVnYXRlLmdtc01kZFN3aXRjaFRvQ3JvbmV0KCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVuYWJsZURheXNTaW5jZUxhc3RNYWludGVuYW5jZVRyYWNraW5nKCkgeworICAgIHJldHVybiBlbmFibGVEYXlzU2luY2VMYXN0TWFpbnRlbmFuY2VUcmFja2luZy5vcigKKyAgICAgICAgZGVsZWdhdGUuZW5hYmxlRGF5c1NpbmNlTGFzdE1haW50ZW5hbmNlVHJhY2tpbmcoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZW5hYmxlU2lkZWxvYWRpbmcoKSB7CisgICAgcmV0dXJuIGVuYWJsZVNpZGVsb2FkaW5nLm9yKGRlbGVnYXRlLmVuYWJsZVNpZGVsb2FkaW5nKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVuYWJsZURvd25sb2FkU3RhZ2VFeHBlcmltZW50SWRQcm9wYWdhdGlvbigpIHsKKyAgICByZXR1cm4gZW5hYmxlRG93bmxvYWRTdGFnZUV4cGVyaW1lbnRJZFByb3BhZ2F0aW9uLm9yKAorICAgICAgICBkZWxlZ2F0ZS5lbmFibGVEb3dubG9hZFN0YWdlRXhwZXJpbWVudElkUHJvcGFnYXRpb24oKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGJvb2xlYW4gZW5hYmxlSXNvbGF0ZWRTdHJ1Y3R1cmVWZXJpZmljYXRpb24oKSB7CisgICAgcmV0dXJuIGVuYWJsZUlzb2xhdGVkU3RydWN0dXJlVmVyaWZpY2F0aW9uLm9yKGRlbGVnYXRlLmVuYWJsZUlzb2xhdGVkU3RydWN0dXJlVmVyaWZpY2F0aW9uKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGVuYWJsZVJuZ0Jhc2VkRGV2aWNlU3RhYmxlU2FtcGxpbmcoKSB7CisgICAgcmV0dXJuIGVuYWJsZVJuZ0Jhc2VkRGV2aWNlU3RhYmxlU2FtcGxpbmcub3IoZGVsZWdhdGUuZW5hYmxlUm5nQmFzZWREZXZpY2VTdGFibGVTYW1wbGluZygpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgbG9uZyBtYWludGVuYW5jZUdjbVRhc2tQZXJpb2QoKSB7CisgICAgcmV0dXJuIG1haW50ZW5hbmNlR2NtVGFza1BlcmlvZC5vcihkZWxlZ2F0ZS5tYWludGVuYW5jZUdjbVRhc2tQZXJpb2QoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGxvbmcgY2hhcmdpbmdHY21UYXNrUGVyaW9kKCkgeworICAgIHJldHVybiBjaGFyZ2luZ0djbVRhc2tQZXJpb2Qub3IoZGVsZWdhdGUuY2hhcmdpbmdHY21UYXNrUGVyaW9kKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBsb25nIGNlbGx1bGFyQ2hhcmdpbmdHY21UYXNrUGVyaW9kKCkgeworICAgIHJldHVybiBjZWxsdWxhckNoYXJnaW5nR2NtVGFza1BlcmlvZC5vcihkZWxlZ2F0ZS5jZWxsdWxhckNoYXJnaW5nR2NtVGFza1BlcmlvZCgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgbG9uZyB3aWZpQ2hhcmdpbmdHY21UYXNrUGVyaW9kKCkgeworICAgIHJldHVybiB3aWZpQ2hhcmdpbmdHY21UYXNrUGVyaW9kLm9yKGRlbGVnYXRlLndpZmlDaGFyZ2luZ0djbVRhc2tQZXJpb2QoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBtZGREZWZhdWx0U2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIG1kZERlZmF1bHRTYW1wbGVJbnRlcnZhbC5vcihkZWxlZ2F0ZS5tZGREZWZhdWx0U2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBtZGREb3dubG9hZEV2ZW50c1NhbXBsZUludGVydmFsKCkgeworICAgIHJldHVybiBtZGREb3dubG9hZEV2ZW50c1NhbXBsZUludGVydmFsLm9yKGRlbGVnYXRlLm1kZERvd25sb2FkRXZlbnRzU2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBncm91cFN0YXRzTG9nZ2luZ1NhbXBsZUludGVydmFsKCkgeworICAgIHJldHVybiBncm91cFN0YXRzTG9nZ2luZ1NhbXBsZUludGVydmFsLm9yKGRlbGVnYXRlLmdyb3VwU3RhdHNMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBhcGlMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIGFwaUxvZ2dpbmdTYW1wbGVJbnRlcnZhbC5vcihkZWxlZ2F0ZS5hcGlMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBjbGVhbnVwTG9nTG9nZ2luZ1NhbXBsZUludGVydmFsKCkgeworICAgIHJldHVybiBjbGVhbnVwTG9nTG9nZ2luZ1NhbXBsZUludGVydmFsLm9yKGRlbGVnYXRlLmNsZWFudXBMb2dMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBzaWxlbnRGZWVkYmFja1NhbXBsZUludGVydmFsKCkgeworICAgIHJldHVybiBzaWxlbnRGZWVkYmFja1NhbXBsZUludGVydmFsLm9yKGRlbGVnYXRlLnNpbGVudEZlZWRiYWNrU2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBzdG9yYWdlU3RhdHNMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIHN0b3JhZ2VTdGF0c0xvZ2dpbmdTYW1wbGVJbnRlcnZhbC5vcihkZWxlZ2F0ZS5zdG9yYWdlU3RhdHNMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBuZXR3b3JrU3RhdHNMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSB7CisgICAgcmV0dXJuIG5ldHdvcmtTdGF0c0xvZ2dpbmdTYW1wbGVJbnRlcnZhbC5vcihkZWxlZ2F0ZS5uZXR3b3JrU3RhdHNMb2dnaW5nU2FtcGxlSW50ZXJ2YWwoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBtb2JzdG9yZUZpbGVTZXJ2aWNlU3RhdHNTYW1wbGVJbnRlcnZhbCgpIHsKKyAgICByZXR1cm4gbW9ic3RvcmVGaWxlU2VydmljZVN0YXRzU2FtcGxlSW50ZXJ2YWwub3IoCisgICAgICAgIGRlbGVnYXRlLm1vYnN0b3JlRmlsZVNlcnZpY2VTdGF0c1NhbXBsZUludGVydmFsKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgbWRkQW5kcm9pZFNoYXJpbmdTYW1wbGVJbnRlcnZhbCgpIHsKKyAgICByZXR1cm4gbWRkQW5kcm9pZFNoYXJpbmdTYW1wbGVJbnRlcnZhbC5vcihkZWxlZ2F0ZS5tZGRBbmRyb2lkU2hhcmluZ1NhbXBsZUludGVydmFsKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBib29sZWFuIGRvd25sb2FkZXJFbmZvcmNlSHR0cHMoKSB7CisgICAgcmV0dXJuIGRvd25sb2FkZXJFbmZvcmNlSHR0cHMub3IoZGVsZWdhdGUuZG93bmxvYWRlckVuZm9yY2VIdHRwcygpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgYm9vbGVhbiBlbmZvcmNlTG93U3RvcmFnZUJlaGF2aW9yKCkgeworICAgIHJldHVybiBlbmZvcmNlTG93U3RvcmFnZUJlaGF2aW9yLm9yKGRlbGVnYXRlLmVuZm9yY2VMb3dTdG9yYWdlQmVoYXZpb3IoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBhYnNGcmVlU3BhY2VBZnRlckRvd25sb2FkKCkgeworICAgIHJldHVybiBhYnNGcmVlU3BhY2VBZnRlckRvd25sb2FkLm9yKGRlbGVnYXRlLmFic0ZyZWVTcGFjZUFmdGVyRG93bmxvYWQoKSk7CisgIH0KKworICBAT3ZlcnJpZGUKKyAgcHVibGljIGludCBhYnNGcmVlU3BhY2VBZnRlckRvd25sb2FkTG93U3RvcmFnZUFsbG93ZWQoKSB7CisgICAgcmV0dXJuIGFic0ZyZWVTcGFjZUFmdGVyRG93bmxvYWRMb3dTdG9yYWdlQWxsb3dlZC5vcigKKyAgICAgICAgZGVsZWdhdGUuYWJzRnJlZVNwYWNlQWZ0ZXJEb3dubG9hZExvd1N0b3JhZ2VBbGxvd2VkKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgYWJzRnJlZVNwYWNlQWZ0ZXJEb3dubG9hZEV4dHJlbWVseUxvd1N0b3JhZ2VBbGxvd2VkKCkgeworICAgIHJldHVybiBhYnNGcmVlU3BhY2VBZnRlckRvd25sb2FkRXh0cmVtZWx5TG93U3RvcmFnZUFsbG93ZWQub3IoCisgICAgICAgIGRlbGVnYXRlLmFic0ZyZWVTcGFjZUFmdGVyRG93bmxvYWRFeHRyZW1lbHlMb3dTdG9yYWdlQWxsb3dlZCgpKTsKKyAgfQorCisgIEBPdmVycmlkZQorICBwdWJsaWMgZmxvYXQgZnJhY3Rpb25GcmVlU3BhY2VBZnRlckRvd25sb2FkKCkgeworICAgIHJldHVybiBmcmFjdGlvbkZyZWVTcGFjZUFmdGVyRG93bmxvYWQub3IoZGVsZWdhdGUuZnJhY3Rpb25GcmVlU3BhY2VBZnRlckRvd25sb2FkKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgdGltZVRvV2FpdEZvckRvd25sb2FkZXIoKSB7CisgICAgcmV0dXJuIHRpbWVUb1dhaXRGb3JEb3dubG9hZGVyLm9yKGRlbGVnYXRlLnRpbWVUb1dhaXRGb3JEb3dubG9hZGVyKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgZG93bmxvYWRlck1heFRocmVhZHMoKSB7CisgICAgcmV0dXJuIGRvd25sb2FkZXJNYXhUaHJlYWRzLm9yKGRlbGVnYXRlLmRvd25sb2FkZXJNYXhUaHJlYWRzKCkpOworICB9CisKKyAgQE92ZXJyaWRlCisgIHB1YmxpYyBpbnQgZG93bmxvYWRlck1heFJldHJ5T25DaGVja3N1bU1pc21hdGNoQ291bnQoKSB7CisgICAgcmV0dXJuIGRvd25sb2FkZXJNYXhSZXRyeU9uQ2hlY2tzdW1NaXNtYXRjaENvdW50Lm9yKAorICAgICAgICBkZWxlZ2F0ZS5kb3dubG9hZGVyTWF4UmV0cnlPbkNoZWNrc3VtTWlzbWF0Y2hDb3VudCgpKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvamF2YXRlc3RzL2NvbS9nb29nbGUvYW5kcm9pZC9saWJyYXJpZXMvbW9iaWxlZGF0YWRvd25sb2FkL3Rlc3RpbmcvVGVzdEh0dHBTZXJ2ZXIuamF2YSBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL1Rlc3RIdHRwU2VydmVyLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDY2ZDZkMgotLS0gL2Rldi9udWxsCisrKyBiL2phdmF0ZXN0cy9jb20vZ29vZ2xlL2FuZHJvaWQvbGlicmFyaWVzL21vYmlsZWRhdGFkb3dubG9hZC90ZXN0aW5nL1Rlc3RIdHRwU2VydmVyLmphdmEKQEAgLTAsMCArMSwyMDEgQEAKKy8qCisgKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisgKgorICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisgKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisgKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKyAqCisgKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorICoKKyAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKyAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisgKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKyAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKyAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorICovCitwYWNrYWdlIGNvbS5nb29nbGUuYW5kcm9pZC5saWJyYXJpZXMubW9iaWxlZGF0YWRvd25sb2FkLnRlc3Rpbmc7CisKK2ltcG9ydCBhbmRyb2lkLm5ldC5Vcmk7CitpbXBvcnQgYW5kcm9pZC51dGlsLkxvZzsKK2ltcG9ydCBjb20uZ29vZ2xlLmNvbW1vbi5iYXNlLk9wdGlvbmFsOworaW1wb3J0IGphdmEuaW8uRmlsZTsKK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOworaW1wb3J0IGphdmEubmV0LkluZXRBZGRyZXNzOworaW1wb3J0IGphdmEubmV0LlNlcnZlclNvY2tldDsKK2ltcG9ydCBqYXZhLm5ldC5Tb2NrZXQ7CitpbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLkhlYWRlcjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuSHR0cEV4Y2VwdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuSHR0cFJlcXVlc3Q7CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLkh0dHBSZXNwb25zZTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuSHR0cFN0YXR1czsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAuZW50aXR5LkZpbGVFbnRpdHk7CitpbXBvcnQgb3JnLmFwYWNoZS5odHRwLmltcGwuRGVmYXVsdENvbm5lY3Rpb25SZXVzZVN0cmF0ZWd5OworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5pbXBsLkRlZmF1bHRIdHRwUmVzcG9uc2VGYWN0b3J5OworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5pbXBsLkRlZmF1bHRIdHRwU2VydmVyQ29ubmVjdGlvbjsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucGFyYW1zLkJhc2ljSHR0cFBhcmFtczsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucGFyYW1zLkNvcmVDb25uZWN0aW9uUE5hbWVzOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wYXJhbXMuSHR0cFBhcmFtczsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuQmFzaWNIdHRwQ29udGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuQmFzaWNIdHRwUHJvY2Vzc29yOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wcm90b2NvbC5IdHRwQ29udGV4dDsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuSHR0cFJlcXVlc3RIYW5kbGVyOworaW1wb3J0IG9yZy5hcGFjaGUuaHR0cC5wcm90b2NvbC5IdHRwUmVxdWVzdEhhbmRsZXJSZWdpc3RyeTsKK2ltcG9ydCBvcmcuYXBhY2hlLmh0dHAucHJvdG9jb2wuSHR0cFNlcnZpY2U7CisKKy8qKiBUZXN0SHR0cFNlcnZlciBpcyBhIHNpbXBsZSBodHRwIHNlcnZlciB0aGF0IGxpc3RlbnMgdG8gaHR0cCByZXF1ZXN0cyBvbiBhIHNpbmdsZSB0aHJlYWQuICovCitwdWJsaWMgZmluYWwgY2xhc3MgVGVzdEh0dHBTZXJ2ZXIgeworCisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUcgPSAiVGVzdEh0dHBTZXJ2ZXIiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVTVF9IT1NUID0gImxvY2FsaG9zdCI7CisKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEhFQURfUkVRVUVTVF9NRVRIT0QgPSAiSEVBRCI7CisgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFVEFHX0hFQURFUiA9ICJFVGFnIjsKKyAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElGX05PTkVfTUFUQ0hfSEVBREVSID0gIklmLU5vbmUtTWF0Y2giOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQklOQVJZX0NPTlRFTlRfVFlQRSA9ICJhcHBsaWNhdGlvbi9iaW5hcnkiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUFJPVE9fQ09OVEVOVF9UWVBFID0gImFwcGxpY2F0aW9uL3gtcHJvdG9idWYiOworICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVYVF9DT05URU5UX1RZUEUgPSAidGV4dC9wbGFpbiI7CisKKyAgcHJpdmF0ZSBmaW5hbCBIdHRwUGFyYW1zIGh0dHBQYXJhbXMgPSBuZXcgQmFzaWNIdHRwUGFyYW1zKCk7CisgIHByaXZhdGUgZmluYWwgSHR0cFNlcnZpY2UgaHR0cFNlcnZpY2U7CisgIHByaXZhdGUgZmluYWwgSHR0cFJlcXVlc3RIYW5kbGVyUmVnaXN0cnkgcmVnaXN0cnk7CisgIHByaXZhdGUgZmluYWwgQXRvbWljQm9vbGVhbiBmaW5pc2hlZCA9IG5ldyBBdG9taWNCb29sZWFuKCk7CisKKyAgcHJpdmF0ZSBUaHJlYWQgc2VydmVyVGhyZWFkOworICBwcml2YXRlIFNlcnZlclNvY2tldCBzZXJ2ZXJTb2NrZXQ7CisgIC8vIDAgbWVhbnMgdXNlciBkaWRuJ3Qgc3BlY2lmeSBhIHBvcnQgbnVtYmVyIGFuZCB3aWxsIHVzZSBhdXRvbWF0aWNhbGx5IGFzc2lnbmVkIHBvcnQuCisgIHByaXZhdGUgZmluYWwgaW50IHVzZXJEZXNpZ25hdGVkUG9ydDsKKworICBwdWJsaWMgVGVzdEh0dHBTZXJ2ZXIoKSB7CisgICAgdGhpcygwKTsKKyAgfQorCisgIHB1YmxpYyBUZXN0SHR0cFNlcnZlcihpbnQgcG9ydE51bWJlcikgeworICAgIHVzZXJEZXNpZ25hdGVkUG9ydCA9IHBvcnROdW1iZXI7CisgICAgaHR0cFBhcmFtcy5zZXRCb29sZWFuUGFyYW1ldGVyKENvcmVDb25uZWN0aW9uUE5hbWVzLlRDUF9OT0RFTEFZLCB0cnVlKTsKKyAgICByZWdpc3RyeSA9IG5ldyBIdHRwUmVxdWVzdEhhbmRsZXJSZWdpc3RyeSgpOworCisgICAgaHR0cFNlcnZpY2UgPQorICAgICAgICBuZXcgSHR0cFNlcnZpY2UoCisgICAgICAgICAgICBuZXcgQmFzaWNIdHRwUHJvY2Vzc29yKCksCisgICAgICAgICAgICBuZXcgRGVmYXVsdENvbm5lY3Rpb25SZXVzZVN0cmF0ZWd5KCksCisgICAgICAgICAgICBuZXcgRGVmYXVsdEh0dHBSZXNwb25zZUZhY3RvcnkoKSk7CisgICAgaHR0cFNlcnZpY2Uuc2V0SGFuZGxlclJlc29sdmVyKHJlZ2lzdHJ5KTsKKyAgICBodHRwU2VydmljZS5zZXRQYXJhbXMoaHR0cFBhcmFtcyk7CisgIH0KKyAgLyoqIFJlZ2lzdGVycyBhIGhhbmRsZXIgZm9yIGFuIGVuZHBvaW50IHBhdHRlcm4uICovCisgIHB1YmxpYyB2b2lkIHJlZ2lzdGVySGFuZGxlcihTdHJpbmcgcGF0dGVybiwgSHR0cFJlcXVlc3RIYW5kbGVyIGhhbmRsZXIpIHsKKyAgICByZWdpc3RyeS5yZWdpc3RlcihwYXR0ZXJuLCBoYW5kbGVyKTsKKyAgfQorCisgIC8qKiBSZWdpc3RlcnMgYSBoYW5kbGVyIHRoYXQgYmluZHMgb250byBhIHRleHQgZmlsZSBmb3IgYW4gZW5kcG9pbnQgcGF0dGVybi4gKi8KKyAgcHVibGljIHZvaWQgcmVnaXN0ZXJUZXh0RmlsZShTdHJpbmcgcGF0dGVybiwgU3RyaW5nIGZpbGVwYXRoKSB7CisgICAgcmVnaXN0ZXJGaWxlKHBhdHRlcm4sIGZpbGVwYXRoLCBURVhUX0NPTlRFTlRfVFlQRSwgLyogZVRhZ09wdGlvbmFsID0gKi8gT3B0aW9uYWwuYWJzZW50KCkpOworICB9CisKKyAgLyoqIFJlZ2lzdGVycyBhIGhhbmRsZXIgdGhhdCBiaW5kcyBvbnRvIGEgZmlsZSBmb3IgYW4gZW5kcG9pbnQgcGF0dGVybi4gKi8KKyAgcHVibGljIHZvaWQgcmVnaXN0ZXJCaW5hcnlGaWxlKFN0cmluZyBwYXR0ZXJuLCBTdHJpbmcgZmlsZXBhdGgpIHsKKyAgICByZWdpc3RlckZpbGUocGF0dGVybiwgZmlsZXBhdGgsIEJJTkFSWV9DT05URU5UX1RZUEUsIC8qZVRhZ09wdGlvbmFsPSovIE9wdGlvbmFsLmFic2VudCgpKTsKKyAgfQorCisgIC8qKgorICAgKiBSZWdpc3RlcnMgYSBoYW5kbGVyIHRoYXQgYmluZHMgb250byBhIHByb3RvIGZpbGUgZm9yIGFuIGVuZHBvaW50IHBhdHRlcm4gd2l0aCB0aGUgc3BlY2lmaWVkCisgICAqIEVUYWcuCisgICAqLworICBwdWJsaWMgdm9pZCByZWdpc3RlclByb3RvRmlsZVdpdGhFVGFnKFN0cmluZyBwYXR0ZXJuLCBTdHJpbmcgZmlsZXBhdGgsIFN0cmluZyBlVGFnKSB7CisgICAgcmVnaXN0ZXJGaWxlKHBhdHRlcm4sIGZpbGVwYXRoLCBQUk9UT19DT05URU5UX1RZUEUsIE9wdGlvbmFsLm9mKGVUYWcpKTsKKyAgfQorCisgIHByaXZhdGUgdm9pZCByZWdpc3RlckZpbGUoCisgICAgICBTdHJpbmcgcGF0dGVybiwgU3RyaW5nIGZpbGVwYXRoLCBTdHJpbmcgY29udGVudFR5cGUsIE9wdGlvbmFsPFN0cmluZz4gZVRhZ09wdGlvbmFsKSB7CisgICAgcmVnaXN0ZXJIYW5kbGVyKAorICAgICAgICBwYXR0ZXJuLAorICAgICAgICAoaHR0cFJlcXVlc3QsIGh0dHBSZXNwb25zZSwgaHR0cENvbnRleHQpIC0+IHsKKyAgICAgICAgICBpZiAoZVRhZ09wdGlvbmFsLmlzUHJlc2VudCgpKSB7CisgICAgICAgICAgICBTdHJpbmcgZVRhZyA9IGVUYWdPcHRpb25hbC5nZXQoKTsKKyAgICAgICAgICAgIGh0dHBSZXNwb25zZS5hZGRIZWFkZXIoRVRBR19IRUFERVIsIGVUYWcpOworICAgICAgICAgICAgc2V0SHR0cFN0YXR1c0NvZGUoaHR0cFJlcXVlc3QsIGh0dHBSZXNwb25zZSwgZVRhZyk7CisgICAgICAgICAgICBpZiAoaHR0cFJlc3BvbnNlLmdldFN0YXR1c0xpbmUoKS5nZXRTdGF0dXNDb2RlKCkgPT0gSHR0cFN0YXR1cy5TQ19OT1RfTU9ESUZJRUQKKyAgICAgICAgICAgICAgICB8fCBIRUFEX1JFUVVFU1RfTUVUSE9ELmVxdWFscyhodHRwUmVxdWVzdC5nZXRSZXF1ZXN0TGluZSgpLmdldE1ldGhvZCgpKSkgeworICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgfSBlbHNlIHsgLy8gVGhlIEVUYWcgaXMgbm90IHByZXNlbnQuCisgICAgICAgICAgICBodHRwUmVzcG9uc2Uuc2V0U3RhdHVzQ29kZShIdHRwU3RhdHVzLlNDX09LKTsKKyAgICAgICAgICB9CisgICAgICAgICAgRmlsZSBmaWxlID0gbmV3IEZpbGUoZmlsZXBhdGgpOworICAgICAgICAgIGh0dHBSZXNwb25zZS5zZXRFbnRpdHkobmV3IEZpbGVFbnRpdHkoZmlsZSwgY29udGVudFR5cGUpKTsKKyAgICAgICAgfSk7CisgIH0KKworICAvKiogU3RhcnRzIHRoZSB0ZXN0IGh0dHAgc2VydmVyIGFuZCByZXR1cm5zIHRoZSBwcmVmaXggb2YgdGhlIHRlc3QgdXJsLiAqLworICBwdWJsaWMgVXJpLkJ1aWxkZXIgc3RhcnRTZXJ2ZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgIHNlcnZlclNvY2tldCA9CisgICAgICAgIG5ldyBTZXJ2ZXJTb2NrZXQoCisgICAgICAgICAgICAvKnBvcnQ9Ki8gdXNlckRlc2lnbmF0ZWRQb3J0LCAvKmJhY2tsb2c9Ki8gMCwgSW5ldEFkZHJlc3MuZ2V0QnlOYW1lKFRFU1RfSE9TVCkpOworICAgIHNlcnZlclRocmVhZCA9CisgICAgICAgIG5ldyBUaHJlYWQoCisgICAgICAgICAgICAoKSAtPiB7CisgICAgICAgICAgICAgIHRyeSB7CisgICAgICAgICAgICAgICAgd2hpbGUgKCFmaW5pc2hlZC5nZXQoKSkgeworICAgICAgICAgICAgICAgICAgU29ja2V0IHNvY2tldCA9IHNlcnZlclNvY2tldC5hY2NlcHQoKTsKKyAgICAgICAgICAgICAgICAgIGhhbmRsZVJlcXVlc3Qoc29ja2V0KTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKKyAgICAgICAgICAgICAgICBMb2cuZShUQUcsICJFeGNlcHRpb246ICIgKyBlKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfSk7CisgICAgc2VydmVyVGhyZWFkLnN0YXJ0KCk7CisgICAgcmV0dXJuIGdldFRlc3RVcmxQcmVmaXgoKTsKKyAgfQorCisgIHB1YmxpYyB2b2lkIHN0b3BTZXJ2ZXIoKSB7CisgICAgdHJ5IHsKKyAgICAgIGZpbmlzaGVkLnNldCh0cnVlKTsKKyAgICAgIHNlcnZlclNvY2tldC5jbG9zZSgpOworICAgICAgc2VydmVyVGhyZWFkLmpvaW4oKTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiB8IEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKKyAgICAgIExvZy5lKFRBRywgIkV4Y2VwdGlvbiB3aGVuIHN0b3BwaW5nIHNlcnZlcjogIiArIGUpOworICAgIH0KKyAgfQorCisgIHByaXZhdGUgdm9pZCBoYW5kbGVSZXF1ZXN0KFNvY2tldCBzb2NrZXQpIHsKKyAgICBEZWZhdWx0SHR0cFNlcnZlckNvbm5lY3Rpb24gY29ubmVjdGlvbiA9IG5ldyBEZWZhdWx0SHR0cFNlcnZlckNvbm5lY3Rpb24oKTsKKyAgICB0cnkgeworICAgICAgY29ubmVjdGlvbi5iaW5kKHNvY2tldCwgaHR0cFBhcmFtcyk7CisgICAgICBIdHRwQ29udGV4dCBodHRwQ29udGV4dCA9IG5ldyBCYXNpY0h0dHBDb250ZXh0KCk7CisgICAgICBodHRwU2VydmljZS5oYW5kbGVSZXF1ZXN0KGNvbm5lY3Rpb24sIGh0dHBDb250ZXh0KTsKKyAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiB8IEh0dHBFeGNlcHRpb24gZSkgeworICAgICAgTG9nLmUoVEFHLCAiVW5leHBlY3RlZCBleGNlcHRpb24gd2hpbGUgcHJvY2Vzc2luZyByZXF1ZXN0ICIgKyBlKTsKKyAgICB9IGZpbmFsbHkgeworICAgICAgdHJ5IHsKKyAgICAgICAgY29ubmVjdGlvbi5zaHV0ZG93bigpOworICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgeworICAgICAgICAvLyBJZ25vcmUuCisgICAgICB9CisgICAgfQorICB9CisKKyAgcHJpdmF0ZSBVcmkuQnVpbGRlciBnZXRUZXN0VXJsUHJlZml4KCkgeworICAgIFN0cmluZyBhdXRob3JpdHkgPSBURVNUX0hPU1QgKyAiOiIgKyBzZXJ2ZXJTb2NrZXQuZ2V0TG9jYWxQb3J0KCk7CisgICAgcmV0dXJuIG5ldyBVcmkuQnVpbGRlcigpLnNjaGVtZSgiaHR0cCIpLmVuY29kZWRBdXRob3JpdHkoYXV0aG9yaXR5KTsKKyAgfQorCisgIHByaXZhdGUgc3RhdGljIHZvaWQgc2V0SHR0cFN0YXR1c0NvZGUoCisgICAgICBIdHRwUmVxdWVzdCBodHRwUmVxdWVzdCwgSHR0cFJlc3BvbnNlIGh0dHBSZXNwb25zZSwgU3RyaW5nIGVUYWcpIHsKKyAgICBIZWFkZXJbXSBoZWFkZXJzID0gaHR0cFJlcXVlc3QuZ2V0QWxsSGVhZGVycygpOworICAgIC8vIFdlIHVzZSBgSWYtTm9uZS1NYXRjaGAgaGVhZGVyIGFuZCBFVGFnIHRvIGRldGVjdCB3aGV0aGVyIHRoZSBmaWxlIGhhcyBiZWVuIGNoYW5nZWQgc2luY2UgdGhlCisgICAgLy8gbGFzdCBzeW5jLiBJZiB0aGUgRVRhZyBmcm9tIGNsaWVudCBtYXRjaGVzIHRoZSBvbmUgYXQgc2VydmVyLCB0aGUgZmlsZSBpcyBub3QgY2hhbmdlZCBhbmQKKyAgICAvLyBIdHRwU3RhdHVzLlNDX05PVF9NT0RJRklFRCBpcyByZXR1cm5lZDsgb3RoZXJ3aXNlLCB0aGUgZmlsZSBpcyBjaGFuZ2VkIGFuZCBIdHRwU3RhdHVzLlNDX09LCisgICAgLy8gaXMgcmV0dXJuZWQuCisgICAgZm9yIChIZWFkZXIgaGVhZGVyIDogaGVhZGVycykgeworICAgICAgLy8gRmluZCB0aGUgYElmLU5vbmUtTWF0Y2hgIGhlYWRlci4KKyAgICAgIGlmICghSUZfTk9ORV9NQVRDSF9IRUFERVIuZXF1YWxzKGhlYWRlci5nZXROYW1lKCkpKSB7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgfQorICAgICAgaHR0cFJlc3BvbnNlLnNldFN0YXR1c0NvZGUoCisgICAgICAgICAgZVRhZy5lcXVhbHMoaGVhZGVyLmdldFZhbHVlKCkpID8gSHR0cFN0YXR1cy5TQ19OT1RfTU9ESUZJRUQgOiBIdHRwU3RhdHVzLlNDX09LKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgaHR0cFJlc3BvbnNlLnNldFN0YXR1c0NvZGUoSHR0cFN0YXR1cy5TQ19PSyk7CisgIH0KK30KZGlmZiAtLWdpdCBhL21vYmlsZS1kYXRhLWRvd25sb2FkLmltbCBiL21vYmlsZS1kYXRhLWRvd25sb2FkLmltbApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZmE0ZDFlCi0tLSAvZGV2L251bGwKKysrIGIvbW9iaWxlLWRhdGEtZG93bmxvYWQuaW1sCkBAIC0wLDAgKzEsMTMgQEAKKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04Ij8+Cis8bW9kdWxlIHR5cGU9IkpBVkFfTU9EVUxFIiB2ZXJzaW9uPSI0Ij4KKyAgPGNvbXBvbmVudCBuYW1lPSJOZXdNb2R1bGVSb290TWFuYWdlciIgaW5oZXJpdC1jb21waWxlci1vdXRwdXQ9InRydWUiPgorICAgIDxleGNsdWRlLW91dHB1dCAvPgorICAgIDxjb250ZW50IHVybD0iZmlsZTovLyRNT0RVTEVfRElSJCI+CisgICAgICA8c291cmNlRm9sZGVyIHVybD0iZmlsZTovLyRNT0RVTEVfRElSJC9hbmRyb2lkLWFubm90YXRpb24tc3R1YnMiIGlzVGVzdFNvdXJjZT0iZmFsc2UiIHBhY2thZ2VQcmVmaXg9Il9fUEFDS0FHRV9fIiAvPgorICAgICAgPHNvdXJjZUZvbGRlciB1cmw9ImZpbGU6Ly8kTU9EVUxFX0RJUiQvamF2YSIgaXNUZXN0U291cmNlPSJmYWxzZSIgLz4KKyAgICAgIDxzb3VyY2VGb2xkZXIgdXJsPSJmaWxlOi8vJE1PRFVMRV9ESVIkL2phdmF0ZXN0cyIgaXNUZXN0U291cmNlPSJmYWxzZSIgLz4KKyAgICA8L2NvbnRlbnQ+CisgICAgPG9yZGVyRW50cnkgdHlwZT0iaW5oZXJpdGVkSmRrIiAvPgorICAgIDxvcmRlckVudHJ5IHR5cGU9InNvdXJjZUZvbGRlciIgZm9yVGVzdHM9ImZhbHNlIiAvPgorICA8L2NvbXBvbmVudD4KKzwvbW9kdWxlPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL3Byb3RvL0FuZHJvaWQuYnAgYi9wcm90by9BbmRyb2lkLmJwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVkZTQ0NzgKLS0tIC9kZXYvbnVsbAorKysgYi9wcm90by9BbmRyb2lkLmJwCkBAIC0wLDAgKzEsMzYgQEAKKy8vIENvcHlyaWdodCAoQykgMjAyMiBUaGUgQW5kcm9pZCBPcGVuIFNvdXJjZSBQcm9qZWN0CisvLworLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisvLyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisvLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKy8vCisvLyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorLy8KKy8vIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKy8vIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisvLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKy8vIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKy8vIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorCitqYXZhX2xpYnJhcnkgeworICAgIG5hbWU6ICJtb2JpbGUtZGF0YS1kb3dubG9hZC1qYXZhLXByb3RvLWxpdGUiLAorICAgIHByb3RvOiB7CisgICAgICAgIHR5cGU6ICJsaXRlIiwKKyAgICAgICAgaW5jbHVkZV9kaXJzOiBbImV4dGVybmFsL3Byb3RvYnVmL3NyYyJdLAorICAgICAgICBjYW5vbmljYWxfcGF0aF9mcm9tX3Jvb3Q6IGZhbHNlLAorICAgICAgICAvL2xvY2FsX2luY2x1ZGVfZGlyczogWyJwcm90by8qIl0sCisgICAgfSwKKyAgICBzdGF0aWNfbGliczogWworICAgICAgICAibGlicHJvdG9idWYtamF2YS1saXRlIiwKKyAgICBdLAorICAgIHNyY3M6IFsKKyAgICAgICAgIioqLyoucHJvdG8iLAorICAgICAgICAiOmxpYnByb3RvYnVmLWludGVybmFsLXByb3RvcyJdLAorICAgIHNka192ZXJzaW9uOiAiY3VycmVudCIsCisgICAgbWluX3Nka192ZXJzaW9uOiAiMzAiLAorICAgIGphcmphcl9ydWxlczogImphcmphci1ydWxlcy50eHQiLAorICAgIGFwZXhfYXZhaWxhYmxlOiBbCisgICAgICAgICIvL2FwZXhfYXZhaWxhYmxlOnBsYXRmb3JtIiwKKyAgICAgICAgImNvbS5hbmRyb2lkLmFkc2VydmljZXMiLAorICAgIF0sCit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvcHJvdG8vQlVJTEQgYi9wcm90by9CVUlMRApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MmI1ZTE4Ci0tLSAvZGV2L251bGwKKysrIGIvcHJvdG8vQlVJTEQKQEAgLTAsMCArMSw0NSBAQAorcGFja2FnZSgKKyAgICBkZWZhdWx0X3Zpc2liaWxpdHkgPSBbIi8vdmlzaWJpbGl0eTpwdWJsaWMiXSwKKyAgICBsaWNlbnNlcyA9IFsibm90aWNlIl0sCispCisKK3Byb3RvX2xpYnJhcnkoCisgICAgbmFtZSA9ICJjbGllbnRfY29uZmlnX3Byb3RvIiwKKyAgICBzcmNzID0gWyJjbGllbnRfY29uZmlnLnByb3RvIl0sCisgICAgY2NfYXBpX3ZlcnNpb24gPSAyLAorICAgIGRlcHMgPSBbCisgICAgICAgICJAY29tX2dvb2dsZV9wcm90b2J1Zi8vOmFueV9wcm90byIsCisgICAgXSwKKykKKworamF2YV9saXRlX3Byb3RvX2xpYnJhcnkoCisgICAgbmFtZSA9ICJjbGllbnRfY29uZmlnX2phdmFfcHJvdG9fbGl0ZSIsCisgICAgZGVwcyA9IFsiOmNsaWVudF9jb25maWdfcHJvdG8iXSwKKykKKworcHJvdG9fbGlicmFyeSgKKyAgICBuYW1lID0gImRvd25sb2FkX2NvbmZpZ19wcm90byIsCisgICAgc3JjcyA9IFsiZG93bmxvYWRfY29uZmlnLnByb3RvIl0sCisgICAgY2NfYXBpX3ZlcnNpb24gPSAyLAorICAgIGRlcHMgPSBbCisgICAgICAgICI6dHJhbnNmb3JtX3Byb3RvIiwKKyAgICAgICAgIkBjb21fZ29vZ2xlX3Byb3RvYnVmLy86YW55X3Byb3RvIiwKKyAgICBdLAorICAgIGFsd2F5c2xpbmsgPSAxLAorKQorCitqYXZhX2xpdGVfcHJvdG9fbGlicmFyeSgKKyAgICBuYW1lID0gImRvd25sb2FkX2NvbmZpZ19qYXZhX3Byb3RvX2xpdGUiLAorICAgIGRlcHMgPSBbIjpkb3dubG9hZF9jb25maWdfcHJvdG8iXSwKKykKKworcHJvdG9fbGlicmFyeSgKKyAgICBuYW1lID0gInRyYW5zZm9ybV9wcm90byIsCisgICAgc3JjcyA9IFsidHJhbnNmb3JtLnByb3RvIl0sCisgICAgY2NfYXBpX3ZlcnNpb24gPSAyLAorKQorCitqYXZhX2xpdGVfcHJvdG9fbGlicmFyeSgKKyAgICBuYW1lID0gInRyYW5zZm9ybV9qYXZhX3Byb3RvX2xpdGUiLAorICAgIGRlcHMgPSBbIjp0cmFuc2Zvcm1fcHJvdG8iXSwKKykKZGlmZiAtLWdpdCBhL3Byb3RvL2NsaWVudF9jb25maWcucHJvdG8gYi9wcm90by9jbGllbnRfY29uZmlnLnByb3RvCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhZTFlOTgKLS0tIC9kZXYvbnVsbAorKysgYi9wcm90by9jbGllbnRfY29uZmlnLnByb3RvCkBAIC0wLDAgKzEsMTM2IEBACisvLyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisvLworLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisvLyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisvLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKy8vCisvLyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorLy8KKy8vIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKy8vIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisvLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKy8vIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKy8vIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorc3ludGF4ID0gInByb3RvMiI7CisKK3BhY2thZ2UgY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tZGkuZG93bmxvYWQ7CisKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90byI7CisKKy8vb3B0aW9uIGpzcGJfdXNlX2NvcnJlY3RfcHJvdG8yX3NlbWFudGljcyA9IGZhbHNlOyAgLy8gPGludGVybmFsPiBUT0RPCitvcHRpb24gamF2YV9wYWNrYWdlID0gImNvbS5nb29nbGUubW9iaWxlZGF0YWRvd25sb2FkIjsKK29wdGlvbiBqYXZhX291dGVyX2NsYXNzbmFtZSA9ICJDbGllbnRDb25maWdQcm90byI7CitvcHRpb24gb2JqY19jbGFzc19wcmVmaXggPSAiSUNOIjsKKworLy8gTmV4dCBpZDogMTUKK21lc3NhZ2UgQ2xpZW50RmlsZUdyb3VwIHsKKyAgLy8gVW5pcXVlIG5hbWUgdG8gaWRlbnRpZnkgdGhlIGdyb3VwLCB0aGF0IHRoZSBjbGllbnQgd2FudHMgdG8gcmVhZC4KKyAgb3B0aW9uYWwgc3RyaW5nIGdyb3VwX25hbWUgPSAxOworCisgIG9wdGlvbmFsIHN0cmluZyBvd25lcl9wYWNrYWdlID0gMzsKKworICAvLyBUaGUgYWNjb3VudCBhc3NvY2lhdGVkIHRvIHRoZSBmaWxlIGdyb3VwLgorICBvcHRpb25hbCBzdHJpbmcgYWNjb3VudCA9IDY7CisKKyAgb3B0aW9uYWwgaW50MzIgdmVyc2lvbl9udW1iZXIgPSA0OworCisgIGVudW0gU3RhdHVzIHsKKyAgICBVTlNQRUNJRklFRCA9IDA7CisKKyAgICAvLyBUaGlzIGdyb3VwIGlzIGRvd25sb2FkZWQgYW5kIHJlYWR5IHRvIHVzZS4KKyAgICBET1dOTE9BREVEID0gMTsKKworICAgIC8vIFRoaXMgZ3JvdXAgaXMgcGVuZGluZyBkb3dubG9hZCwgYW5kIHNob3VsZCBiZSBkb3dubG9hZGVkIGJ5IGNhbGxpbmcKKyAgICAvLyB0aGUgZG93bmxvYWQgQVBJIGJlZm9yZSBpdCBjYW4gYmUgdXNlZC4KKyAgICAvLworICAgIC8vIGZpbGUuZmlsZV91cmkgd2lsbCBub3QgYmUgc2V0IGlmIHRoZSBzdGF0dXMgaXMgc2V0IHRvIHBlbmRpbmcuCisgICAgUEVORElORyA9IDI7CisKKyAgICAvLyBUaGlzIGdyb3VwIGhhcyBmaW5pc2hlZCBkb3dubG9hZGluZywgYnV0IGN1c3RvbSB2YWxpZGF0aW9uIGhhcworICAgIC8vIG5vdCB5ZXQgYmVlbiBwZXJmb3JtZWQuIFRoaXMgc3RhdGUgaXMgb25seSBleHBlY3RlZCB0byBiZSBzZWVuCisgICAgLy8gaW4gdGhlIEN1c3RvbUZpbGVHcm91cFZhbGlkYXRvci4KKyAgICBQRU5ESU5HX0NVU1RPTV9WQUxJREFUSU9OID0gMzsKKyAgfQorCisgIC8vIFN0YXR1cyBvZiB0aGUgY2xpZW50IGZpbGUgZ3JvdXAuCisgIG9wdGlvbmFsIFN0YXR1cyBzdGF0dXMgPSA1OworCisgIC8vIExpc3Qgb2YgZmlsZXMgaW4gdGhlIGdyb3VwLgorICByZXBlYXRlZCBDbGllbnRGaWxlIGZpbGUgPSAyOworCisgIC8vIFVuaXF1ZSBpZGVudGlmaWVyIG9mIGEgRGF0YUZpbGVHcm91cCBjb25maWcgKGkuZS4gYSAic25hcHNob3QiKSBjcmVhdGVkCisgIC8vIHdoZW4gdXNpbmcgTUREIEluZ3Jlc3MgQVBJLgorICAvLworICAvLyBOT1RFOiBUaGlzIGZpZWxkIG5hbWUgYW5kIGRlc2NyaXB0aW9uIGFyZSBub3QgZmluYWxpemVkIHlldCEgUmVhY2ggb3V0IHRvCisgIC8vIDxpbnRlcm5hbD5AIHRvIGRpc2N1c3MgdXNpbmcgdGhpcyBmaWVsZC4KKyAgb3B0aW9uYWwgaW50NjQgYnVpbGRfaWQgPSA4OworCisgIC8vIEEgZmluZ2VycHJpbnQgYWxsb3dpbmcgY2xpZW50cyB0byBpZGVudGlmeSBhIERhdGFGaWxlR3JvdXAKKyAgLy8gY29uZmlnIGJhc2VkIG9uIGEgZ2l2ZW4gc2V0IG9mIHByb3BlcnRpZXMgKGkuZS4gYSAicGFydGl0aW9uIiBvZgorICAvLyBhbnkgZmlsZSBncm91cCBwcm9wZXJ0aWVzKS4gVGhpcyBjYW4gYmUgdXNlZCBieSBjbGllbnRzIGFzIGFuIGV4YWN0IG1hdGNoCisgIC8vIGZvciBhIGNsYXNzIG9mIERhdGFGaWxlR3JvdXBzIGR1cmluZyB0YXJnZXRpbmcgb3IgYXMgYSBjb21wYXRpYmlsaXR5IGNoZWNrLgorICAvLworICAvLyBOT1RFOiBUaGlzIGZpZWxkIG5hbWUgYW5kIGRlc2NyaXB0aW9uIGFyZSBub3QgZmluYWxpemVkIHlldCEgUmVhY2ggb3V0IHRvCisgIC8vIDxpbnRlcm5hbD5AIHRvIGRpc2N1c3MgdXNpbmcgdGhpcyBmaWVsZC4KKyAgb3B0aW9uYWwgc3RyaW5nIHZhcmlhbnRfaWQgPSAxMjsKKworICAvLyBUaGUgbG9jYWxlcyBjb21wYXRpYmxlIHdpdGggdGhlIGZpbGUgZ3JvdXAuIFRoaXMgY2FuIGJlIGRpZmZlcmVudCBmcm9tIHRoZQorICAvLyBkZXZpY2UgbG9jYWxlLgorICAvLworICAvLyBWYWx1ZXMgaW4gdGhpcyBsaXN0IG1heSBiZSBleGFjdCBsb2NhbGVzIChlLmcuICJlbi1VUyIpIG9yIGxhbmd1YWdlLW9ubHkKKyAgLy8gKCJlbi0qIikuCisgIC8vIEV4YW1wbGUgMTogbG9jYWxlID0gWyJlbi1VUyJdOyAvLyBjb21wYXRpYmxlIHdpdGggImVuLVVTIiBvbmx5CisgIC8vIEV4YW1wbGUgMjogbG9jYWxlID0gWyJlbi1VUyIsICJlbi1DQSJdOyAvLyBjb21wYXRpYmxlIHdpdGggImVuLVVTIiBvcgorICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gImVuLUNBIgorICAvLyBFeGFtcGxlIDM6IGxvY2FsZSA9IFsiZW4tKiJdOyAvLyBjb21wYXRpYmxlIHdpdGggYWxsICJlbiIgbG9jYWxlcworICByZXBlYXRlZCBzdHJpbmcgbG9jYWxlID0gMTA7CisKKyAgcmVzZXJ2ZWQgMTE7CisKKyAgLy8gQ3VzdG9tIG1ldGFkYXRhIGF0dGFjaGVkIHRvIHRoZSBncm91cC4KKyAgLy8KKyAgLy8gVGhpcyBhbGxvd3MgY2xpZW50cyB0byBpbmNsdWRlIHNwZWNpZmljIG1ldGFkYXRhIGFib3V0IHRoZSBncm91cCBmb3IgdGhlaXIKKyAgLy8gb3duIHByb2Nlc3NpbmcgcHVycG9zZXMuIFRoZSBtZXRhZGF0YSBtdXN0IGJlIGluY2x1ZGVkIHdoZW4gdGhlIGdyb3VwIGlzCisgIC8vIGFkZGVkIHRvIE1ERCwgdGhlbiBpdCB3aWxsIGJlIGF2YWlsYWJsZSBoZXJlIHdoZW4gcmV0cmlldmluZyB0aGUgZ3JvdXAuCisgIC8vCisgIC8vIFRoaXMgcHJvcGVydHkgc2hvdWxkIG9ubHkgYmUgdXNlZCBpZiBhYnNvbHV0ZWx5IG5lY2Vzc2FyeS4gUGxlYXNlIGNvbnN1bHQKKyAgLy8gd2l0aCA8aW50ZXJuYWw+QCBpZiB5b3UgaGF2ZSBxdWVzdGlvbnMgYWJvdXQgdGhpcyBwcm9wZXJ0eSBvciBhIHBvdGVudGlhbAorICAvLyB1c2UtY2FzZS4KKyAgb3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5BbnkgY3VzdG9tX21ldGFkYXRhID0gMTM7CisKKyAgcmVzZXJ2ZWQgMTQ7CisKKyAgcmVzZXJ2ZWQgNywgOTsKK30KKworLy8gTmV4dCBpZDogNgorbWVzc2FnZSBDbGllbnRGaWxlIHsKKyAgLy8gVW5pcXVlIG5hbWUgdG8gaWRlbnRpZnkgdGhlIGZpbGUgd2l0aGluIHRoZSBncm91cC4KKyAgb3B0aW9uYWwgc3RyaW5nIGZpbGVfaWQgPSAxOworCisgIC8vIEZpbGUgVXJpIHRoYXQgY2FuIGJlIG9wZW5lZCB1c2luZyBGaWxlU3RvcmFnZSBsaWJyYXJ5ICg8aW50ZXJuYWw+KS4KKyAgb3B0aW9uYWwgc3RyaW5nIGZpbGVfdXJpID0gMjsKKworICAvLyBUaGUgZnVsbCBzaXplIG9mIHRoZSBmaWxlIGFzIHNwZWNpZmllZCBpbiBieXRlX3NpemUgZmllbGQgb2YgdGhlIGNvbmZpZworICAvLyBnaXZlbiB0byBNREQuIEZvciBmaWxlcyB1bnppcHBlZCBmcm9tIHppcCBmaWxlIHdpdGggemlwIGRvd25sb2FkCisgIC8vIHRyYW5zZm9ybXMsIGl0IHdpbGwgYmUgdGhlIGFjdHVhbCBmaWxlIHNpemUgb24gZGlzay4KKyAgb3B0aW9uYWwgaW50MzIgZnVsbF9zaXplX2luX2J5dGVzID0gMzsKKworICAvLyBUaGUgZG93bmxvYWQgc2l6ZSBvZiB0aGUgZmlsZSBhcyBzcGVjaWZpZWQgaW4gZG93bmxvYWRlZF9maWxlX2J5dGVfc2l6ZQorICAvLyBmaWVsZCAoPGludGVybmFsPikgb2YgdGhlCisgIC8vIGNvbmZpZyBnaXZlbiB0byBNREQuIEl0IGNvdWxkIGJlIHVzZWQgdG8gdHJhY2sgYW5kIGNhbGN1bGF0ZSB0aGUgZG93bmxvYWQKKyAgLy8gcHJvZ3Jlc3MuCisgIG9wdGlvbmFsIGludDMyIGRvd25sb2FkX3NpemVfaW5fYnl0ZXMgPSA0OworCisgIC8vIEN1c3RvbSBtZXRhZGF0YSBhdHRhY2hlZCB0byB0aGUgZmlsZQorICAvLworICAvLyBUaGlzIGFsbG93cyBjbGllbnRzIHRvIGluY2x1ZGUgc3BlY2lmaWMgbWV0YWRhdGEgYWJvdXQgdGhlIGZpbGUgZm9yIHRoZWlyCisgIC8vIG93biBwcm9jZXNzaW5nIHB1cnBvc2VzLiBUaGUgbWV0YWRhdGEgbXVzdCBiZSBpbmNsdWRlZCB3aGVuIHRoZSBmaWxlJ3MKKyAgLy8gZ3JvdXAgaXMgYWRkZWQgdG8gTURELCB0aGVuIGl0IHdpbGwgYmUgYXZhaWxhYmxlIGhlcmUgd2hlbiByZXRyaWV2aW5nIHRoZQorICAvLyBjb250YWluaW5nIGdyb3VwLgorICAvLworICAvLyBUaGlzIHByb3BlcnR5IHNob3VsZCBvbmx5IGJlIHVzZWQgaWYgYWJzb2x1dGVseSBuZWNlc3NhcnkuIFBsZWFzZSBjb25zdWx0CisgIC8vIHdpdGggPGludGVybmFsPkAgaWYgeW91IGhhdmUgcXVlc3Rpb25zIGFib3V0IHRoaXMgcHJvcGVydHkgb3IgYSBwb3RlbnRpYWwKKyAgLy8gdXNlLWNhc2UuCisgIG9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuQW55IGN1c3RvbV9tZXRhZGF0YSA9IDU7Cit9CmRpZmYgLS1naXQgYS9wcm90by9kb3dubG9hZF9jb25maWcucHJvdG8gYi9wcm90by9kb3dubG9hZF9jb25maWcucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzRjN2UzNAotLS0gL2Rldi9udWxsCisrKyBiL3Byb3RvL2Rvd25sb2FkX2NvbmZpZy5wcm90bwpAQCAtMCwwICsxLDU1NSBAQAorLy8gQ29weXJpZ2h0IDIwMjIgR29vZ2xlIExMQworLy8KKy8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOworLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgorLy8gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CisvLworLy8gICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKy8vCisvLyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCisvLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAorLy8gV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCisvLyBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCisvLyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIG1kaS5kb3dubG9hZDsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvYW55LnByb3RvIjsKK2ltcG9ydCAidHJhbnNmb3JtLnByb3RvIjsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZCI7CitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiRG93bmxvYWRDb25maWdQcm90byI7CitvcHRpb24gb2JqY19jbGFzc19wcmVmaXggPSAiSWNpbmciOworLy9vcHRpb24gZ29fYXBpX2ZsYWcgPSAiT1BFTl9UT19PUEFRVUVfSFlCUklEIjsgIC8vIFNlZSA8aW50ZXJuYWw+LiBUT0RPCisKKy8vIFRoZSB0b3AtbGV2ZWwgcHJvdG8gZm9yIE1vYmlsZSBEYXRhIERvd25sb2FkICg8aW50ZXJuYWw+KS4KK21lc3NhZ2UgRG93bmxvYWRDb25maWcgeworICByZXBlYXRlZCBEYXRhRmlsZUdyb3VwIGRhdGFfZmlsZV9ncm91cCA9IDE7CisKKyAgcmVzZXJ2ZWQgMjsKK30KKworLy8gSFRUUCBoZWFkZXJzIGFyZSBkZXNjcmliZWQgaW4gaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL3JmYzcyMzAjc2VjdGlvbi0zLjIKKy8vIGFzIGtleTp2YWx1ZSwgd2hlcmUgdGhlIHZhbHVlIG1heSBoYXZlIGEgd2hpdGVzcGFjZSBvbiBlYWNoIGVuZC4KK21lc3NhZ2UgRXh0cmFIdHRwSGVhZGVyIHsKKyAgb3B0aW9uYWwgc3RyaW5nIGtleSA9IDE7CisgIG9wdGlvbmFsIHN0cmluZyB2YWx1ZSA9IDI7Cit9CisKKy8vIEEgRmlsZUdyb3VwIGlzIGEgc2V0IG9mIGZpbGVzIHRoYXQgc2hvdWxkIGJlIGF0b21pY2FsbHkgdXBkYXRlZC4KKy8vIE5leHQgaWQ6IDI5CittZXNzYWdlIERhdGFGaWxlR3JvdXAgeworICAvLyBVbmlxdWUgbmFtZSB0byBpZGVudGlmeSB0aGUgZ3JvdXAuIEl0IHNob3VsZCBiZSB1bmlxdWUgcGVyIG93bmVyIHBhY2thZ2UuCisgIC8vIEluIEdNU0NvcmUsIHVzZSB0aGUgbW9kdWxlIG5hbWUgYXMgdGhlIHByZWZpeCBvZiB0aGUgZ3JvdXAgbmFtZS4KKyAgLy8KKyAgLy8gRXg6IEEgZ3JvdXAgbmFtZSBpbiBtZGlzeW5jIG1vZHVsZSBjb3VsZCBiZSBuYW1lZDogbWRpc3luYy1wcm9maWxlLXBob3Rvcy4KKyAgLy8KKyAgLy8gVGhpcyBzaG91bGRuJ3QgaWRlYWxseSBiZSBzb21ldGhpbmcgbGlrZSAiY29uZmlnIiwgYW5kCisgIC8vIGluc3RlYWQgc2hvdWxkIGJldHRlciBkZWZpbmUgdGhlIGZlYXR1cmUgaXQgd2lsbCBiZSB1c2VkIGZvci4KKyAgLy8KKyAgLy8gRXg6ICJpY2luZy1sYW5ndWFnZS1kZXRlY3Rpb24tbW9kZWwiLCAic21hcnQtYWN0aW9uLWRldGVjdGlvbi1tb2RlbCIKKyAgLy8KKyAgLy8gSU1QT1JUQU5UOiB0aGlzIGdyb3VwIG5hbWUgd2lsbCBiZSBsb2dnZWQgdG8gY2xlYXJjdXQsIGFuZCBtdXN0IG5ldmVyCisgIC8vIGNvbnRhaW4gUElJLgorICBvcHRpb25hbCBzdHJpbmcgZ3JvdXBfbmFtZSA9IDE7CisKKyAgLy8gVGhlIG5hbWUgb2YgdGhlIHBhY2thZ2UgdGhhdCBvd25zIHRoaXMgZ3JvdXAuIElmIHRoaXMgZmllbGQgaXMgbGVmdCBlbXB0eSwKKyAgLy8gdGhlIG93bmVyIGlzIGFzc3VtZWQgdG8gYmUgdGhlIHBhY2thZ2UgbmFtZSBvZiB0aGUgaG9zdCBhcHAuCisgIC8vCisgIC8vIFRoZSBmaWxlcyB3aWxsIG9ubHkgYmUgZG93bmxvYWRlZCBvbnRvIHRoZSBkZXZpY2UgaWYgdGhlIG93bmVyIHBhY2thZ2UgaXMKKyAgLy8gcHJlc2VudCBvbiB0aGUgZGV2aWNlLgorICAvLworICAvLyBFeDogImNvbS5nb29nbGUuYW5kcm9pZC5nbXMiLCAiY29tLmdvb2dsZS5hbmRyb2lkLmFwcHMuYnVnbGUiCisgIG9wdGlvbmFsIHN0cmluZyBvd25lcl9wYWNrYWdlID0gNjsKKworICAvLyBDbGllbnQgc2V0IHZlcnNpb24gbnVtYmVyIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGZpbGUgZ3JvdXAuCisgIC8vCisgIC8vIE5vdGUgdGhhdCB0aGlzIGRvZXMgbm90IHVuaXF1ZWx5IGlkZW50aWZ5IHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZSBncm91cC4KKyAgLy8gSXQgc2ltcGx5IHJlZmxlY3RzIGEgc25hcHNob3Qgb2YgY2xpZW50IGNvbmZpZyBjaGFuZ2VzLgorICAvLyBGb3IgZXhhbXBsZTogc2F5IHRoZXJlJ3MgYSBmaWxlIGdyb3VwICdsYW5ndWFnZS1kZXRlY3Rvci1tb2RlbCcgdGhhdAorICAvLyBkb3dubG9hZHMgYSBkaWZmZXJlbnQgZmlsZSBwZXIgdXNlciBsb2NhbGUuCisgIC8vIGRhdGFfZmlsZV9ncm91cCB7CisgIC8vICAgZmlsZV9ncm91cF9uYW1lID0gJ2xhbmd1YWdlLWRldGVjdG9yLW1vZGVsJworICAvLyAgIGZpbGVfZ3JvdXBfdmVyc2lvbl9udW1iZXIgPSAxCisgIC8vICAgZmlsZSB7CisgIC8vICAgICAgdXJsID0gJ2VuLW1vZGVsJworICAvLyAgIH0KKyAgLy8gfQorICAvLyBkYXRhX2ZpbGVfZ3JvdXAgeworICAvLyAgIGZpbGVfZ3JvdXBfbmFtZSA9ICdsYW5ndWFnZS1kZXRlY3Rvci1tb2RlbCcKKyAgLy8gICBmaWxlX2dyb3VwX3ZlcnNpb25fbnVtYmVyID0gMQorICAvLyAgIGZpbGUgeworICAvLyAgICAgIHVybCA9ICdlcy1tb2RlbCcKKyAgLy8gICB9CisgIC8vIH0KKyAgLy8gTm90ZSB0aGF0IGV2ZW4gdGhvdWdoIHRoZSBhY3R1YWwgY29udGVudHMgb2YgdGhlIGZpbGUgZ3JvdXAgYXJlIGRpZmZlcmVudAorICAvLyBmb3IgZWFjaCBsb2NhbGUsIHRoZSB2ZXJzaW9uIGlzIHRoZSBzYW1lIGJlY2F1c2UgdGhpcyBjb25maWcgd2FzIHB1c2hlZAorICAvLyBhdCB0aGUgc2FtZSBzbmFwc2hvdC4KKyAgLy8KKyAgLy8gQXZhaWxhYmxlIEdNUyB2MTgrLgorICBvcHRpb25hbCBpbnQzMiBmaWxlX2dyb3VwX3ZlcnNpb25fbnVtYmVyID0gMTA7CisKKyAgcmVzZXJ2ZWQgMjA7CisKKyAgLy8gQ3VzdG9tIG1ldGFkYXRhIGF0dGFjaGVkIHRvIHRoZSBmaWxlIGdyb3VwLgorICAvLworICAvLyBUaGlzIGFsbG93cyBjbGllbnRzIHRvIGluY2x1ZGUgc3BlY2lmaWMgbWV0YWRhdGEgYWJvdXQgdGhlIGdyb3VwIGZvciB0aGVpcgorICAvLyBvd24gcHJvY2Vzc2luZyBwdXJwb3Nlcy4gVGhlIG1ldGFkYXRhIHdpbGwgYmUgc3RvcmVkIHdpdGggdGhlIGdyb3VwIGFuZAorICAvLyBhY2Nlc3NpYmxlIHdoZW4gdGhlIGZpbGUgZ3JvdXAgaXMgcmV0cmlldmVkLgorICAvLworICAvLyBUaGlzIHByb3BlcnR5IHNob3VsZCBvbmx5IGJlIHVzZWQgaWYgYWJzb2x1dGVseSBuZWNlc3NhcnkuIFBsZWFzZSBjb25zdWx0CisgIC8vIHdpdGggPGludGVybmFsPkAgaWYgeW91IGhhdmUgcXVlc3Rpb25zIGFib3V0IHRoaXMgcHJvcGVydHkgb3IgYSBwb3RlbnRpYWwKKyAgLy8gdXNlLWNhc2UuCisgIC8vCisgIC8vIEF2YWlsYWJsZSBmb3IgYU1ERCBMaWIgb25seS4KKyAgb3B0aW9uYWwgZ29vZ2xlLnByb3RvYnVmLkFueSBjdXN0b21fbWV0YWRhdGEgPSAyNzsKKworICByZXNlcnZlZCAyMjsKKworICByZXNlcnZlZCAyMTsKKworICBlbnVtIEFsbG93ZWRSZWFkZXJzIHsKKyAgICBBTExfR09PR0xFX0FQUFMgPSAwOworICAgIE9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVMgPSAxOworICAgIEFMTF9BUFBTID0gMjsKKyAgfQorCisgIC8vIERlZmluZXMgd2hvIGlzIGFsbG93ZWQgdG8gcmVhZCB0aGlzIGZpbGUgZ3JvdXAuIEN1cnJlbnRseSB0aGUgb3B0aW9ucyBhcmU6CisgIC8vCisgIC8vIEFMTF9HT09HTEVfQVBQUzogYWNjZXNzaWJsZSB0byBhbGwgR29vZ2xlIDFwIEFwcHMuCisgIC8vIE9OTFlfR09PR0xFX1BMQVlfU0VSVklDRVM6IGFjY2Vzc2libGUgdG8gb25seSBHTVMgQ29yZS4KKyAgLy8KKyAgLy8gSWYgdGhpcyBmaWVsZCBpcyBub3QgZXhwbGljaXRseSBzZXQgaXQgZGVmYXVsdHMgdG8gIkFMTF9HT09HTEVfQVBQUyIuCisgIC8vCisgIC8vIEF2YWlsYWJsZSBHTVMgdjIwKy4KKyAgb3B0aW9uYWwgQWxsb3dlZFJlYWRlcnMgYWxsb3dlZF9yZWFkZXJzX2VudW0gPSAxMjsKKworICAvLyBMZW5ndGggb2YgdGltZSAoaW4gc2Vjb25kcykgZm9yIHdoaWNoIGEgZmlsZSBncm91cCB2ZXJzaW9uIHdpbGwgbGl2ZSBhZnRlcgorICAvLyBhIG5ld2VyIHZlcnNpb24gYmVjYW1lIGZ1bGx5IGRvd25sb2FkZWQuIENsaWVudHMgc2hvdWxkIHNldCB0aGlzIHRpbWUKKyAgLy8gdG8gYmUgbW9yZSB0aGFuIHRoZSB0aW1lIGluIHdoaWNoIHRoZXkgY2FsbCBNREQgdG8gcmVmcmVzaCB0aGVpciBkYXRhLgorICAvLyBOT1RFOiBNREQgd2lsbCBkZWxldGUgdGhlIGZpbGUgZ3JvdXAgdmVyc2lvbiB3aXRoaW4gYSBkYXkgb2YgdGhpcyB0aW1lLgorICAvLyBFeDogMTcyODAwICAvLyAyIERheXMKKyAgb3B0aW9uYWwgaW50NjQgc3RhbGVfbGlmZXRpbWVfc2VjcyA9IDM7CisKKyAgLy8gVGhlIHRpbWVzdGFtcCBhdCB3aGljaCB0aGlzIGZpbGVncm91cCBzaG91bGQgYmUgZGVsZXRlZCwgZXZlbiBpZiBpdCBpcworICAvLyBzdGlsbCBhY3RpdmUsIHNwZWNpZmllZCBpbiBzZWNvbmRzIHNpbmNlIGVwb2NoLgorICAvLyBOT1RFOiBNREQgd2lsbCBkZWxldGUgdGhlIGZpbGUgZ3JvdXAgdmVyc2lvbiB3aXRoaW4gYSBkYXkgb2YgdGhpcyB0aW1lLgorICBvcHRpb25hbCBpbnQ2NCBleHBpcmF0aW9uX2RhdGUgPSAxMTsKKworICAvLyBTcGVjaWZ5IHRoZSBjb25kaXRpb25zIHVuZGVyIHdoaWNoIHRoZSBmaWxlIGdyb3VwIHNob3VsZCBiZSBkb3dubG9hZGVkLgorICBvcHRpb25hbCBEb3dubG9hZENvbmRpdGlvbnMgZG93bmxvYWRfY29uZGl0aW9ucyA9IDEzOworCisgIC8vIFNldHRpbmcgdGhpcyBmbGFnIHRvIHRydWUgd2lsbCBtZWFuIHRoYXQgdGhlIGRvd25sb2FkZWQgZmlsZXMgd2lsbCBhcHBlYXIKKyAgLy8gdG8gYmUgaW4gYSBkaXJlY3RvcnkgYnkgdGhlbXNlbHZlcy4KKyAgLy8gVGhlIGZpbGUgbmFtZS9maWxlIHBhdGggb2YgdGhlIGV4cG9zZWQgZmlsZSB3aWxsIGJlIHRoZSBmaWxlbmFtZSBzZXQgaW4gdGhlCisgIC8vIGZpbGUucmVsYXRpdmVfZmlsZV9wYXRoIGZpZWxkLCBPUiBpZiB0aGF0IGZpZWxkIGlzIGVtcHR5LCB0aGUgZmlsZSBuYW1lCisgIC8vIGZyb20gdGhlIGZpbGUudXJsX3RvX2Rvd25sb2FkIGZpZWxkLiBUaGlzIGVuYWJsZXMgZG93bmxvYWRlZCBmaWxlcyB0byByZWZlcgorICAvLyB0byBlYWNoIG90aGVyIGJ5IG5hbWUuCisgIC8vIEl0J3MgaW52YWxpZCB0byBzZXQgdGhpcyBmbGFnIHRvIHRydWUgaWYgdHdvIGZpbGVzIGVuZCB1cCB3aXRoIHRoZSBzYW1lCisgIC8vIGZpbGUgcGF0aC4KKyAgLy8gVmFsaWQgb24gaU9TLCBjTURELCBhbmQgYU1ERC4KKyAgLy8KKyAgLy8gTk9URTogRm9yIGFNREQsIHRoaXMgZmVhdHVyZSBpcyBub3QgYXZhaWxhYmxlIGlmIEFuZHJvaWQgQmxvYiBTaGFyaW5nIGlzCisgIC8vIGVuYWJsZWQgb3IgaWYgdXNpbmcgYW4gQVBJIGxldmVsIGJlbG93IDIxIChMKS4gSWYgZWl0aGVyIGNhc2UgaXMgdHJ1ZSwgdGhpcworICAvLyBvcHRpb24gd2lsbCBiZSBpZ25vcmVkLgorICBvcHRpb25hbCBib29sIHByZXNlcnZlX2ZpbGVuYW1lc19hbmRfaXNvbGF0ZV9maWxlcyA9IDE0OworCisgIC8vIExpc3Qgb2YgZmlsZXMgaW4gdGhlIGdyb3VwLgorICByZXBlYXRlZCBEYXRhRmlsZSBmaWxlID0gMjsKKworICAvLyBUYWcgZm9yIHRoZSBuZXR3b3JrIHRyYWZmaWMgdG8gZG93bmxvYWQgdGhpcyBmaWxlIGdyb3VwLgorICAvLyBUYWcgc3BhY2UgaXMgZGV0ZXJtaW5lZCBieSB0aGUgaG9zdCBhcHAuCisgIC8vIEZvciBHbXNjb3JlLCB0aGUgdGFnIHNob3VsZCBjb21lIGZyb206CisgIC8vIDxpbnRlcm5hbD4KKyAgb3B0aW9uYWwgaW50MzIgdHJhZmZpY190YWcgPSAxNjsKKworICAvLyBFeHRyYSBIVFRQIGhlYWRlcnMgdG8gYXBwbHkgd2hlbiBkb3dubG9hZGluZyBhbGwgZmlsZXMgaW4gdGhlIGdyb3VwLgorICByZXBlYXRlZCBFeHRyYUh0dHBIZWFkZXIgZ3JvdXBfZXh0cmFfaHR0cF9oZWFkZXJzID0gMTc7CisKKyAgcmVzZXJ2ZWQgMTk7CisKKyAgLy8gVW5pcXVlIGlkZW50aWZpZXIgb2YgYSBEYXRhRmlsZUdyb3VwIGNvbmZpZyAoaS5lLiBhICJzbmFwc2hvdCIpIGNyZWF0ZWQKKyAgLy8gd2hlbiB1c2luZyBNREQgSW5ncmVzcyBBUEkuCisgIG9wdGlvbmFsIGludDY0IGJ1aWxkX2lkID0gMjM7CisKKyAgLy8gQSBmaW5nZXJwcmludCBhbGxvd2luZyBjbGllbnRzIHRvIGlkZW50aWZ5IGEgRGF0YUZpbGVHcm91cAorICAvLyBjb25maWcgYmFzZWQgb24gYSBnaXZlbiBzZXQgb2YgcHJvcGVydGllcyAoaS5lLiBhICJwYXJ0aXRpb24iIG9mCisgIC8vIGFueSBmaWxlIGdyb3VwIHByb3BlcnRpZXMpLiBUaGlzIGNhbiBiZSB1c2VkIGJ5IGNsaWVudHMgYXMgYW4gZXhhY3QgbWF0Y2gKKyAgLy8gZm9yIGEgY2xhc3Mgb2YgRGF0YUZpbGVHcm91cHMgZHVyaW5nIHRhcmdldGluZyBvciBhcyBhIGNvbXBhdGliaWxpdHkgY2hlY2suCisgIG9wdGlvbmFsIHN0cmluZyB2YXJpYW50X2lkID0gMjY7CisKKyAgLy8gVGhlIGxvY2FsZXMgY29tcGF0aWJsZSB3aXRoIHRoZSBmaWxlIGdyb3VwLiBUaGlzIGNhbiBiZSBkaWZmZXJlbnQgZnJvbSB0aGUKKyAgLy8gZGV2aWNlIGxvY2FsZS4KKyAgLy8KKyAgLy8gVmFsdWVzIGluIHRoaXMgbGlzdCBtYXkgYmUgZXhhY3QgbG9jYWxlcyAoZS5nLiAiZW4tVVMiKSBvciBsYW5ndWFnZS1vbmx5CisgIC8vICgiZW4tKiIpLgorICAvLyBFeGFtcGxlIDE6IGxvY2FsZSA9IFsiZW4tVVMiXTsgLy8gY29tcGF0aWJsZSB3aXRoICJlbi1VUyIgb25seQorICAvLyBFeGFtcGxlIDI6IGxvY2FsZSA9IFsiZW4tVVMiLCAiZW4tQ0EiXTsgLy8gY29tcGF0aWJsZSB3aXRoICJlbi1VUyIgb3IKKyAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICJlbi1DQSIKKyAgLy8gRXhhbXBsZSAzOiBsb2NhbGUgPSBbImVuLSoiXTsgLy8gY29tcGF0aWJsZSB3aXRoIGFsbCAiZW4iIGxvY2FsZXMKKyAgcmVwZWF0ZWQgc3RyaW5nIGxvY2FsZSA9IDI1OworCisgIHJlc2VydmVkIDI4OworCisgIHJlc2VydmVkIDQsIDUsIDcsIDgsIDksIDE1LCAxOCwgMjQsIDI0ODgxMzk2NiAvKmFNREQgZXh0ZW5zaW9uKi8sCisgICAgICAyNDg2MDY1NTIgLypjTUREIGV4dGVuc2lvbiovOworfQorCisvLyBBIGRhdGEgZmlsZSByZXByZXNlbnRzIGFsbCB0aGUgbWV0YWRhdGEgdG8gZG93bmxvYWQgdGhlIGZpbGUgYW5kIHRoZW4KKy8vIG1hbmFnZSBpdCBvbiB0aGUgZGV2aWNlLgorLy8gTmV4dCB0YWc6IDIyCisvLworLy8gVGhpcyBzaG91bGQgbm90IGNvbnRhaW4gYW55IGZpZWxkcyB0aGF0IGFyZSBtYXJrZWQgaW50ZXJuYWwsIGFzIHdlIGNvbXBhcmUKKy8vIHRoZSBwcm90b3MgZGlyZWN0bHkgdG8gZGVjaWRlIGlmIGl0IGlzIGEgbmV3IHZlcnNpb24gb2YgdGhlIGZpbGUuCisvLyBMSU5ULklmQ2hhbmdlKGRhdGFfZmlsZSkKK21lc3NhZ2UgRGF0YUZpbGUgeworICAvLyBBIHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBmaWxlIHdpdGhpbiB0aGUgZ3JvdXAsIHRoYXQgY2FuIGJlIHVzZWQgdG8KKyAgLy8gZ2V0IHRoaXMgZmlsZSBmcm9tIHRoZSBncm91cC4KKyAgLy8gRXg6ICJsYW5ndWFnZS1kZXRlY3Rpb24tbW9kZWwiCisgIG9wdGlvbmFsIHN0cmluZyBmaWxlX2lkID0gNzsKKworICAvLyBVcmwgZnJvbSB3aGVyZSB0aGUgZmlsZSBpcyB0byBiZSBkb3dubG9hZGVkLgorICAvLyBFeDogaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20vZ3JvdXAtbmFtZS9tb2RlbF8xMjM0LnppcAorICBvcHRpb25hbCBzdHJpbmcgdXJsX3RvX2Rvd25sb2FkID0gMjsKKworICAvLyBFeGFjdCBzaXplIG9mIHRoZSBmaWxlLiBUaGlzIGlzIHVzZWQgdG8gY2hlY2sgaWYgdGhlcmUgaXMgc3BhY2UgYXZhaWxhYmxlCisgIC8vIGZvciB0aGUgZmlsZSBiZWZvcmUgc2NoZWR1bGluZyB0aGUgZG93bmxvYWQuCisgIC8vIFRoZSBieXRlX3NpemUgaXMgb3B0aW9uYWwuIElmIG5vdCBzZXQsIE1ERCB3aWxsIG5vdCBiZSBhYmxlIGNoZWNrIHRoZSBzcGFjZQorICAvLyBhdmFpbGFibGUgYmVmb3JlIHNjaGVkdWxkaW5nIHRoZSBkb3dubG9hZC4KKyAgb3B0aW9uYWwgaW50MzIgYnl0ZV9zaXplID0gNDsKKworICAvLyBFbnVtIGZvciBjaGVja3N1bSB0eXBlcy4KKyAgLy8gTk9URTogZG8gbm90IGFkZCBhbnkgbmV3IGNoZWNrc3VtIHR5cGUgaGVyZSwgb2xkZXIgTUREIHZlcnNpb25zIHdvdWxkIGJyZWFrCisgIC8vIG90aGVyd2lzZS4KKyAgZW51bSBDaGVja3N1bVR5cGUgeworICAgIC8vIERlZmF1bHQgY2hlY2tzdW0gaXMgU0hBMS4KKyAgICBERUZBVUxUID0gMDsKKworICAgIC8vIE5vIGNoZWNrc3VtIGlzIHByb3ZpZGVkLgorICAgIC8vIFRoaXMgaXMgTk9UIGN1cnJlbnRseSBzdXBwb3J0ZWQgYnkgaU1ERC4gUGxlYXNlIGNvbnRhY3QgPGludGVybmFsPkAgaWYKKyAgICAvLyB5b3UgbmVlZCB0aGlzIGZlYXR1cmUuCisgICAgTk9ORSA9IDE7CisKKyAgICAvLyBUaGlzIGlzIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRlZCBieSBjTURELiBJZiB5b3UgbmVlZCBpdCBmb3IgQW5kcm9pZCBvcgorICAgIC8vIGlPUywgcGxlYXNlIGNvbnRhY3QgTUREIHRlYW0gPGludGVybmFsPkAuCisgICAgU0hBMjU2ID0gMjsKKyAgfQorCisgIG9wdGlvbmFsIENoZWNrc3VtVHlwZSBjaGVja3N1bV90eXBlID0gMTU7CisKKyAgLy8gU0hBMSBjaGVja3N1bSB0byB2ZXJpZnkgdGhlIGZpbGUgYmVmb3JlIGl0IGNhbiBiZSB1c2VkLiBUaGlzIGlzIGFsc28gdXNlZAorICAvLyB0byBkZS1kdXBsaWNhdGUgZmlsZXMgYmV0d2VlbiBkaWZmZXJlbnQgZ3JvdXBzLgorICAvLyBGb3IgbW9zdCBmaWxlcywgdGhpcyB3aWxsIGJlIHRoZSBjaGVja3N1bSBvZiB0aGUgZmlsZSBiZWluZyBkb3dubG9hZGVkLgorICAvLyBGb3IgZmlsZXMgd2l0aCBkb3dubG9hZF90cmFuc2Zvcm0sIHRoaXMgc2hvdWxkIGNvbnRhaW4gdGhlIHRyYW5zZm9ybSBvZgorICAvLyB0aGUgZmlsZSBhZnRlciB0aGUgdHJhbnNmb3JtcyBoYXZlIGJlZW4gYXBwbGllZC4KKyAgLy8gVGhlIGNoZWNrc3VtIGlzIG9wdGlvbmFsLiBJZiBub3Qgc2V0LCB0aGUgY2hlY2tzdW1fdHlwZSBtdXN0IGJlCisgIC8vIENoZWNrc3VtVHlwZS5OT05FLgorICBvcHRpb25hbCBzdHJpbmcgY2hlY2tzdW0gPSA1OworCisgIC8vIFRoZSBmb2xsb3dpbmcgYXJlIDxpbnRlcm5hbD4gdHJhbnNmb3JtcyB0byBhcHBseSB0byB0aGUgZG93bmxvYWRlZCBmaWxlcy4KKyAgLy8gVHJhbnNmb3JtcyBhcmUgYmktZGlyZWN0aW9uYWwgYW5kIGRlZmluZWQgaW4gdGVybXMgb2Ygd2hhdCB0aGV5IGRvIG9uCisgIC8vIHdyaXRlLiBTaW5jZSB0aGVzZSB0cmFuc2Zvcm1zIGFyZSBhcHBsaWVkIHdoaWxlIHJlYWRpbmcsIHRoZWlyCisgIC8vIGRpcmVjdGlvbmFsaXR5IGlzIHJldmVyc2VkLiBFZywgeW91J2xsIHNlZSAnY29tcHJlc3MnIHRvIGluZGljYXRlIHRoYXQgdGhlCisgIC8vIGZpbGUgc2hvdWxkIGJlIGRlY29tcHJlc3NlZC4KKworICAvLyBUaGVzZSB0cmFuc2Zvcm1zIGFyZSBhcHBsaWVkIG9uY2UgYnkgTUREIGFmdGVyIGRvd25sb2FkaW5nIHRoZSBmaWxlLgorICAvLyBDdXJyZW50bHkgb25seSBjb21wcmVzcyBpcyBhdmFpbGFibGUuCisgIC8vIFZhbGlkIG9uIEFuZHJvaWQuIGlPUyBzdXBwb3J0IGlzIHRyYWNrZWQgYnkgYi8xMTg4MjgwNDUuCisgIG9wdGlvbmFsIG1vYnN0b3JlLnByb3RvLlRyYW5zZm9ybXMgZG93bmxvYWRfdHJhbnNmb3JtcyA9IDExOworCisgIC8vIElmIERhdGFGaWxlIGhhcyBkb3dubG9hZF90cmFuc2Zvcm1zLCB0aGlzIGZpZWxkIG11c3QgYmUgcHJvdmlkZWQgd2l0aCB0aGUKKyAgLy8gU0hBMSBjaGVja3N1bSBvZiB0aGUgZmlsZSBiZWZvcmUgYW55IHRyYW5zZm9ybSBhcmUgYXBwbGllZC4gVGhlIG9yaWdpbmFsCisgIC8vIGNoZWNrc3VtIHdvdWxkIGFsc28gYmUgY2hlY2tlZCBhZnRlciB0aGUgZG93bmxvYWRfdHJhbnNmb3JtcyBhcmUgYXBwbGllZC4KKyAgb3B0aW9uYWwgc3RyaW5nIGRvd25sb2FkZWRfZmlsZV9jaGVja3N1bSA9IDE0OworCisgIC8vIEV4YWN0IHNpemUgb2YgdGhlIGRvd25sb2FkZWQgZmlsZS4gSWYgdGhlIERhdGFGaWxlIGhhcyBkb3dubG9hZCB0cmFuc2Zvcm1zCisgIC8vIGxpa2UgY29tcHJlc3MgYW5kIHppcCwgdGhlIGRvd25sb2FkZWQgZmlsZSBzaXplIHdvdWxkIGJlIGRpZmZlcmVudCB0aGFuCisgIC8vIHRoZSBmaW5hbCBmaWxlIHNpemUgb24gZGlzay4gQ2xpZW50IGNvdWxkIHVzZQorICAvLyB0aGlzIGZpZWxkIHRvIHRyYWNrIHRoZSBkb3dubG9hZGVkIGZpbGUgc2l6ZSBhbmQgY2FsY3VsYXRlIHRoZSBkb3dubG9hZAorICAvLyBwcm9ncmVzcyBwZXJjZW50YWdlLiBUaGlzIGZpZWxkIGlzIG5vdCB1c2VkIGJ5IE1ERCBjdXJyZW50bHkuCisgIG9wdGlvbmFsIGludDMyIGRvd25sb2FkZWRfZmlsZV9ieXRlX3NpemUgPSAxNjsKKworICAvLyBUaGVzZSB0cmFuc2Zvcm1zIGFyZSBldmFsdWF0ZWQgYnkgdGhlIGNhbGxlciBvbi10aGUtZmx5IHdoZW4gcmVhZGluZyB0aGUKKyAgLy8gZGF0YSB3aXRoIE1vYlN0b3JlLiBBbnkgdHJhbnNmb3JtcyBpbnN0YWxsZWQgaW4gdGhlIGNhbGxlcidzIE1vYlN0b3JlCisgIC8vIGluc3RhbmNlIGlzIGF2YWlsYWJsZS4KKyAgLy8gVmFsaWQgb24gQW5kcm9pZCBhbmQgY01ERC4gaU9TIHN1cHBvcnQgaXMgdHJhY2tlZCBieSBiLzExODc1OTI1NC4KKyAgb3B0aW9uYWwgbW9ic3RvcmUucHJvdG8uVHJhbnNmb3JtcyByZWFkX3RyYW5zZm9ybXMgPSAxMjsKKworICAvLyBMaXN0IG9mIGRlbHRhIGZpbGVzIHRoYXQgY2FuIGJlIGVuY29kZWQgYW5kIGRlY29kZWQgd2l0aCBiYXNlIGZpbGVzLgorICAvLyBJZiB0aGUgZGV2aWNlIGhhcyBhbnkgYmFzZSBmaWxlLCB0aGUgZGVsdGEgZmlsZSB3aGljaCBpcyBtdWNoCisgIC8vIHNtYWxsZXIgd2lsbCBiZSBkb3dubG9hZGVkIGluc3RlYWQgb2YgdGhlIGZ1bGwgZmlsZS4KKyAgLy8gRm9yIG1vc3QgY2xpZW50cywgb25seSBvbmUgZGVsdGEgZmlsZSBzaG91bGQgYmUgZW5vdWdoLiBJZiBzcGVjaWZ5aW5nCisgIC8vIG11bHRpcGxlIGRlbHRhIGZpbGVzLCB0aGV5IHNob3VsZCBiZSBpbiBhIHNlcXVlbmNlIGZyb20gdGhlIG1vc3QgcmVjZW50CisgIC8vIGJhc2UgZmlsZSB0byB0aGUgb2xkZXN0LgorICAvLyBUaGlzIGlzIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRlZCBvbiBBbmRyb2lkLgorICByZXBlYXRlZCBEZWx0YUZpbGUgZGVsdGFfZmlsZSA9IDEzOworCisgIGVudW0gQW5kcm9pZFNoYXJpbmdUeXBlIHsKKyAgICAvLyBUaGUgZGF0YUZpbGUgaXNuJ3QgYXZhaWxhYmxlIGZvciBzaGFyaW5nLgorICAgIFVOU1VQUE9SVEVEID0gMDsKKworICAgIC8vIElmIHNoYXJpbmcgd2l0aCB0aGUgQW5kcm9pZCBCbG9iIFNoYXJpbmcgU2VydmljZSBpc24ndCBhdmFpbGFibGUsIGZhbGwKKyAgICAvLyBiYWNrIHRvIG5vcm1hbCBiZWhhdmlvciwgaS5lLiBkb3dubG9hZCBsb2NhbGx5LgorICAgIEFORFJPSURfQkxPQl9XSEVOX0FWQUlMQUJMRSA9IDE7CisgIH0KKworICAvLyBEZWZpbmVzIHdoZXRoZXIgdGhlIGZpbGUgc2hvdWxkIGJlIHNoYXJlZCBhbmQgaG93LgorICAvLyBOT1RFOiBjdXJyZW50bHkgdGhpcyBmaWVsZCBpcyBvbmx5IHVzZWQgYnkgYU1ERCBhbmQgaGFzIG5vIGVmZmVjdCBvbiBpTURELgorICBvcHRpb25hbCBBbmRyb2lkU2hhcmluZ1R5cGUgYW5kcm9pZF9zaGFyaW5nX3R5cGUgPSAxNzsKKworICAvLyBFbnVtIGZvciBhbmRyb2lkIHNoYXJpbmcgY2hlY2tzdW0gdHlwZXMuCisgIGVudW0gQW5kcm9pZFNoYXJpbmdDaGVja3N1bVR5cGUgeworICAgIE5PVF9TRVQgPSAwOworCisgICAgLy8gSWYgdGhlIGZpbGUgZ3JvdXAgc2hvdWxkIGJlIHNoYXJlZCB0aHJvdWdoIHRoZSBBbmRyb2lkIEJsb2IgU2hhcmluZworICAgIC8vIFNlcnZpY2UsIHRoZSBjaGVja3N1bSB0eXBlIG11c3QgYmUgc2V0IHRvIFNIQTI1Ni4KKyAgICBTSEEyXzI1NiA9IDE7CisgIH0KKworICBvcHRpb25hbCBBbmRyb2lkU2hhcmluZ0NoZWNrc3VtVHlwZSBhbmRyb2lkX3NoYXJpbmdfY2hlY2tzdW1fdHlwZSA9IDE4OworCisgIC8vIENoZWNrc3VtIHVzZWQgdG8gYWNjZXNzIGZpbGVzIHRocm91Z2ggdGhlIEFuZHJvaWQgQmxvYiBTaGFyaW5nIFNlcnZpY2UuCisgIG9wdGlvbmFsIHN0cmluZyBhbmRyb2lkX3NoYXJpbmdfY2hlY2tzdW0gPSAxOTsKKworICAvLyBSZWxhdGl2ZSBmaWxlIHBhdGggYW5kIGZpbGUgbmFtZSB0byBiZSBwcmVzZXJ2ZWQgd2l0aGluIHRoZSBwYXJlbnQKKyAgLy8gZGlyZWN0b3J5IHdoZW4gY3JlYXRpbmcgc3ltbGlua3MgZm9yIHRoZSBmaWxlIGdyb3VwcyB0aGF0IGhhdmUKKyAgLy8gcHJlc2VydmVfZmlsZW5hbWVzX2FuZF9pc29sYXRlX2ZpbGVzIHNldCB0byB0cnVlLgorICAvLyBUaGlzIGZpbGVuYW1lIHNob3VsZCBOT1Qgc3RhcnQgb3IgZW5kIHdpdGggYSAnLycsIGFuZCBpdCBjYW4gbm90IGNvbnRhaW4KKyAgLy8gdGhlIHN1YnN0cmluZyAnLi4nLgorICAvLyBXb3JraW5nIGV4YW1wbGU6ICJzdWJEaXIvRmlsZU5hbWUudHh0Ii4KKyAgb3B0aW9uYWwgc3RyaW5nIHJlbGF0aXZlX2ZpbGVfcGF0aCA9IDIwOworCisgIC8vIEN1c3RvbSBtZXRhZGF0YSBhdHRhY2hlZCB0byB0aGUgZmlsZS4KKyAgLy8KKyAgLy8gVGhpcyBhbGxvd3MgY2xpZW50cyB0byBpbmNsdWRlIHNwZWNpZmljIG1ldGFkYXRhIGFib3V0IHRoZSBmaWxlIGZvciB0aGVpcgorICAvLyBvd24gcHJvY2Vzc2luZyBwdXJwb3Nlcy4gVGhlIG1ldGFkYXRhIHdpbGwgYmUgc3RvcmVkIHdpdGggdGhlIGZpbGUgYW5kCisgIC8vIGFjY2Vzc2libGUgd2hlbiB0aGUgZmlsZSdzIGZpbGUgZ3JvdXAgaXMgcmV0cmlldmVkLgorICAvLworICAvLyBUaGlzIHByb3BlcnR5IHNob3VsZCBvbmx5IGJlIHVzZWQgaWYgYWJzb2x1dGVseSBuZWNlc3NhcnkuIFBsZWFzZSBjb25zdWx0CisgIC8vIHdpdGggPGludGVybmFsPkAgaWYgeW91IGhhdmUgcXVlc3Rpb25zIGFib3V0IHRoaXMgcHJvcGVydHkgb3IgYSBwb3RlbnRpYWwKKyAgLy8gdXNlLWNhc2UuCisgIC8vCisgIC8vIEF2YWlsYWJsZSBmb3IgYU1ERCBMaWIgb25seS4KKyAgb3B0aW9uYWwgZ29vZ2xlLnByb3RvYnVmLkFueSBjdXN0b21fbWV0YWRhdGEgPSAyMTsKKworICByZXNlcnZlZCAxLCAzLCA2LCA4LCA5OworfQorLy8gTElOVC5UaGVuQ2hhbmdlKAorLy8gICAgIDxpbnRlcm5hbD4sCisvLyAgICAgPGludGVybmFsPikKKworLy8gQSBkZWx0YSBmaWxlIHJlcHJlc2VudHMgYWxsIHRoZSBtZXRhZGF0YSB0byBkb3dubG9hZCBmb3IgYSBkaWZmIGZpbGUgZW5jb2RlZAorLy8gYmFzZWQgb24gYSBiYXNlIGZpbGUKKy8vIExJTlQuSWZDaGFuZ2UoZGVsdGFfZmlsZSkKK21lc3NhZ2UgRGVsdGFGaWxlIHsKKyAgLy8gVGhlc2UgZmllbGRzIGFsbCBtaXJyb3IgdGhlIHNpbWlsYXJseS1uYW1lZCBmaWVsZHMgaW4gRGF0YUZpbGUuCisgIG9wdGlvbmFsIHN0cmluZyB1cmxfdG9fZG93bmxvYWQgPSAxOworICBvcHRpb25hbCBpbnQzMiBieXRlX3NpemUgPSAyOworICBvcHRpb25hbCBzdHJpbmcgY2hlY2tzdW0gPSAzOworCisgIC8vIEVudW0gb2YgYWxsIGRpZmYgZGVjb2RlcnMgc3VwcG9ydGVkCisgIGVudW0gRGlmZkRlY29kZXIgeworICAgIC8vIERlZmF1bHQgdG8gaGF2ZSBubyBkaWZmIGRlY29kZXIgc3BlY2lmaWVkLCB3aWxsIHRocm93biB1bnN1cHBvcnRlZAorICAgIC8vIGV4Y2VwdGlvbgorICAgIFVOU1BFQ0lGSUVEID0gMDsKKworICAgIC8vIFZjRElGRiBkZWNvZGVyCisgICAgLy8gR2VuZXJpYyBEaWZmZXJlbmNpbmcgYW5kIENvbXByZXNzaW9uIERhdGEgRm9ybWF0CisgICAgLy8gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSByZWZlciB0byByZmMzMjg0CisgICAgLy8gVGhlIFZjRGlmZiBkZWNvZGVyIGZvciBHTVMgc2VydmljZToKKyAgICAvLyA8aW50ZXJuYWw+CisgICAgVkNfRElGRiA9IDE7CisgIH0KKyAgLy8gVGhlIGRpZmYgZGVjb2RlciB1c2VkIHRvIGdlbmVyYXRlIGZ1bGwgZmlsZSB3aXRoIGRlbHRhIGFuZCBiYXNlIGZpbGUuCisgIC8vIEZvciBNREQgYXMgYSBHTVMgc2VydmljZSwgYSBWY0RpZmYgZGVjb2RlciB3aWxsIGJlIHJlZ2lzdGVyZWQgYW5kIGluamVjdGVkCisgIC8vIGluIGJ5IGRlZmF1bHQuIFVzaW5nIE1ERCBhcyBhIGxpYnJhcnksIGNsaWVudHMgbmVlZCB0byByZWdpc3RlciBhbmQgaW5qZWN0CisgIC8vIGluIGEgVmNEaWZmIGRlY29kZXIsIG90aGVyd2lzZSwgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgorICBvcHRpb25hbCBEaWZmRGVjb2RlciBkaWZmX2RlY29kZXIgPSA1OworCisgIC8vIFRoZSBiYXNlIGZpbGUgcmVwcmVzZW50cyB0byBhIGZ1bGwgZmlsZSBvbiBkZXZpY2UuIEl0IHNob3VsZCBjb250YWluIHRoZQorICAvLyBiYXJlIG1pbmltdW0gZmllbGRzIG9mIGEgRGF0YUZpbGUgdG8gaWRlbnRpZnkgYSBEYXRhRmlsZSBvbiBkZXZpY2UuCisgIG9wdGlvbmFsIEJhc2VGaWxlIGJhc2VfZmlsZSA9IDY7CisKKyAgcmVzZXJ2ZWQgNDsKK30KKy8vIExJTlQuVGhlbkNoYW5nZSgKKy8vICAgICA8aW50ZXJuYWw+LAorLy8gICAgIDxpbnRlcm5hbD4pCisKK21lc3NhZ2UgQmFzZUZpbGUgeworICAvLyBTSEExIGNoZWNrc3VtIG9mIHRoZSBiYXNlIGZpbGUgdG8gaWRlbnRpZnkgYSBmaWxlIG9uIGRldmljZS4gSXQgc2hvdWxkCisgIC8vIG1hdGNoIHRoZSBjaGVja3N1bSBmaWVsZCBvZiB0aGUgYmFzZSBmaWxlIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGRlbHRhIGZpbGUuCisgIG9wdGlvbmFsIHN0cmluZyBjaGVja3N1bSA9IDE7Cit9CisKKy8vIExJTlQuSWZDaGFuZ2UKKy8vIE5leHQgaWQ6IDUKK21lc3NhZ2UgRG93bmxvYWRDb25kaXRpb25zIHsKKyAgLy8gVE9ETyhiLzE0MzU0ODc1Myk6IFRoZSBmaXJzdCB2YWx1ZSBpbiBhbiBlbnVtIG11c3QgaGF2ZSBhIHNwZWNpZmljIHByZWZpeC4KKyAgZW51bSBEZXZpY2VTdG9yYWdlUG9saWN5IHsKKyAgICAvLyBNREQgd2lsbCBibG9jayBkb3dubG9hZCBvZiBmaWxlcyBpbiBhbmRyb2lkIGxvdyBzdG9yYWdlLiBDdXJyZW50bHkgTURECisgICAgLy8gZG9lc24ndCBkZWxldGUgdGhlIGZpbGVzIGluIGNhc2UgdGhlIGRldmljZSByZWFjaGVzIGxvdyBzdG9yYWdlCisgICAgLy8gYWZ0ZXIgdGhlIGZpbGUgaGFzIGJlZW4gZG93bmxvYWRlZC4KKyAgICBCTE9DS19ET1dOTE9BRF9JTl9MT1dfU1RPUkFHRSA9IDA7CisKKyAgICAvLyBCbG9jayBkb3dubG9hZCBvZiBmaWxlcyBvbmx5IHVuZGVyIGEgbG93ZXIgdGhyZXNob2xkIGRlZmluZWQgaGVyZQorICAgIC8vIDxpbnRlcm5hbD4KKyAgICBCTE9DS19ET1dOTE9BRF9MT1dFUl9USFJFU0hPTEQgPSAxOworCisgICAgLy8gU2V0IHRoZSBzdG9yYWdlIHRocmVzaG9sZCB0byBhbiBleHRyZW1lbHkgbG93IHZhbHVlIHdoZW4gZG93bmxvYWRpbmcuCisgICAgLy8gSU1QT1JUQU5UOiBpZiB0aGUgZG93bmxvYWQgbWFrZSB0aGUgZGV2aWNlIHJ1bnMgb3V0IG9mIGRpc2ssIHRoaXMgY291bGQKKyAgICAvLyByZW5kZXIgdGhlIGRldmljZSB1bnVzYWJsZS4KKyAgICAvLyBUaGlzIHNob3VsZCBvbmx5IGJlIHVzZWQgZm9yIGNyaXRpY2FsIHVzZSBjYXNlcyBzdWNoIGFzIHByaXZhY3kKKyAgICAvLyB2aW9sYXRpb25zLiBFbWVyZ2VuY3kgZml4IHNob3VsZCBub3QgYmVsb25nIHRvIHRoaXMgY2F0ZWdvcnkuIFBsZWFzZQorICAgIC8vIHRhbGtzIHRvIDxpbnRlcm5hbD5AIHdoZW4geW91IHdhbnQgdG8gdXNlIHRoaXMgb3B0aW9uLgorICAgIEVYVFJFTUVMWV9MT1dfVEhSRVNIT0xEID0gMjsKKyAgfQorCisgIC8vIFNwZWNpZnkgdGhlIGRldmljZSBzdG9yYWdlIHVuZGVyIHdoaWNoIHRoZSBmaWxlcyBzaG91bGQgYmUgZG93bmxvYWRlZC4KKyAgLy8gQnkgZGVmYXVsdCwgdGhlIGZpbGVzIHdpbGwgb25seSBiZSBkb3dubG9hZGVkIGlmIHRoZSBkZXZpY2UgaXMgbm90IGluCisgIC8vIGxvdyBzdG9yYWdlLgorICBvcHRpb25hbCBEZXZpY2VTdG9yYWdlUG9saWN5IGRldmljZV9zdG9yYWdlX3BvbGljeSA9IDE7CisKKyAgLy8gVE9ETyhiLzE0MzU0ODc1Myk6IFRoZSBmaXJzdCB2YWx1ZSBpbiBhbiBlbnVtIG11c3QgaGF2ZSBhIHNwZWNpZmljIHByZWZpeC4KKyAgZW51bSBEZXZpY2VOZXR3b3JrUG9saWN5IHsKKyAgICAvLyBPbmx5IGRvd25sb2FkIGZpbGVzIG9uIHdpZmkuCisgICAgRE9XTkxPQURfT05MWV9PTl9XSUZJID0gMDsKKworICAgIC8vIEFsbG93IGRvd25sb2FkIG9uIGFueSBuZXR3b3JrIGluY2x1ZGluZyB3aWZpIGFuZCBjZWxsdWxhci4KKyAgICBET1dOTE9BRF9PTl9BTllfTkVUV09SSyA9IDE7CisKKyAgICAvLyBBbGxvdyBkb3dubG9hZGluZyBvbmx5IG9uIHdpZmkgZmlyc3QsIHRoZW4gYWZ0ZXIgYSBjb25maWd1cmFibGUgdGltZQorICAgIC8vIHBlcmlvZCBzZXQgaW4gdGhlIGZpZWxkIGRvd25sb2FkX2ZpcnN0X29uX3dpZmlfcGVyaW9kX3NlY3MgYmVsb3csCisgICAgLy8gYWxsb3cgZG93bmxvYWRpbmcgb24gYW55IG5ldHdvcmsgaW5jbHVkaW5nIHdpZmkgYW5kIGNlbGx1bGFyLgorICAgIERPV05MT0FEX0ZJUlNUX09OX1dJRklfVEhFTl9PTl9BTllfTkVUV09SSyA9IDI7CisgIH0KKworICAvLyBTcGVjaWZ5IHRoZSBkZXZpY2UgbmV0d29yayB1bmRlciB3aGljaCB0aGUgZmlsZXMgc2hvdWxkIGJlIGRvd25sb2FkZWQuCisgIC8vIEJ5IGRlZmF1bHQsIHRoZSBmaWxlcyB3aWxsIG9ubHkgYmUgZG93bmxvYWRlZCBvbiB3aWZpLgorICAvLworICAvLyBJZiB5b3VyIGZlYXR1cmUgdGFyZ2V0cyBiZWxvdyB2MjAgYW5kIHdhbnQgdG8gZG93bmxvYWQgb24gY2VsbHVsYXIgaW4KKyAgLy8gdGhlc2UgdmVyc2lvbnMgb2YgZ21zLCBhbHNvIHNldCBhbGxvd19kb3dubG9hZF93aXRob3V0X3dpZmkgPSB0cnVlOworICBvcHRpb25hbCBEZXZpY2VOZXR3b3JrUG9saWN5IGRldmljZV9uZXR3b3JrX3BvbGljeSA9IDI7CisKKyAgLy8gVGhpcyBmaWVsZCB3aWxsIG9ubHkgYmUgdXNlZCB3aGVuIHRoZQorICAvLyBEZXZpY2VOZXR3b3JrUG9saWN5ID0gRE9XTkxPQURfRklSU1RfT05fV0lGSV9USEVOX09OX0FOWV9ORVRXT1JLCisgIC8vIE1ERCB3aWxsIGRvd25sb2FkIHRoZSBmaWxlIG9ubHkgb24gd2lmaSBmb3IgdGhpcyBwZXJpb2Qgb2YgdGltZS4gSWYgdGhlCisgIC8vIGRvd25sb2FkIHdhcyBub3QgZmluaXNoZWQsIE1ERCB3aWxsIGRvd25sb2FkIG9uIGFueSBuZXR3b3JrIGluY2x1ZGluZworICAvLyB3aWZpIGFuZCBjZWxsdWxhci4KKyAgLy8gRXg6IDYwNDgwMCAgLy8gNyBEYXlzCisgIG9wdGlvbmFsIGludDY0IGRvd25sb2FkX2ZpcnN0X29uX3dpZmlfcGVyaW9kX3NlY3MgPSA0OworCisgIC8vIFRPRE8oYi8xNDM1NDg3NTMpOiBUaGUgZmlyc3QgdmFsdWUgaW4gYW4gZW51bSBtdXN0IGhhdmUgYSBzcGVjaWZpYyBwcmVmaXguCisgIGVudW0gQWN0aXZhdGluZ0NvbmRpdGlvbiB7CisgICAgLy8gVGhlIGRvd25sb2FkIGlzIGFjdGl2YXRlZCBhcyBzb29uIHRoZSBzZXJ2ZXIgc2lkZSBjb25maWcgaXMgcmVjZWl2ZWQgYW5kCisgICAgLy8gdGhlIHNlcnZlciBjb25maWd1cmVkIGRvd25sb2FkIGNvbmRpdGlvbnMgYXJlIHNhdGlzZmllZC4KKyAgICBBTFdBWVNfQUNUSVZBVEVEID0gMDsKKworICAgIC8vIFRoZSBkb3dubG9hZCBpcyBhY3RpdmF0ZWQgd2hlbiBib3RoIHNlcnZlciBzaWRlIGFjdGl2YXRpb24gY29uZGl0aW9ucworICAgIC8vIGFyZSBzYXRpc2ZpZWQgYW5kIHRoZSBjbGllbnQgaGFzIGFjdGl2YXRlZCB0aGUgZG93bmxvYWQgb24gZGV2aWNlLgorICAgIC8vCisgICAgLy8gQ2xpZW50cyBjYW4gYWN0aXZhdGUgdGhpcyBncm91cCB1c2luZyB0aGUgYWN0aXZhdGVGaWxlR3JvdXAgQVBJLgorICAgIC8vIDxpbnRlcm5hbD4KKyAgICBERVZJQ0VfQUNUSVZBVEVEID0gMTsKKyAgfQorCisgIC8vIFNwZWNpZnkgaG93IHRoZSBkb3dubG9hZCBpcyBhY3RpdmF0ZWQuIEJ5IGRlZmF1bHQsIHRoZSBkb3dubG9hZCBpcworICAvLyBhY3RpdmF0ZWQgYXMgc29vbiBhcyBzZXJ2ZXIgY29uZmlndXJlZCBhY3RpdmF0aW5nIGNvbmRpdGlvbnMgYXJlIHNhdGlzZmllZC4KKyAgb3B0aW9uYWwgQWN0aXZhdGluZ0NvbmRpdGlvbiBhY3RpdmF0aW5nX2NvbmRpdGlvbiA9IDM7Cit9CisvLyBMSU5ULlRoZW5DaGFuZ2UoCisvLyA8aW50ZXJuYWw+LAorLy8gPGludGVybmFsPikKKworbWVzc2FnZSBQaENvbmZpZyB7CisgIHJlcGVhdGVkIFBoQ2xpZW50IHBoX2NsaWVudCA9IDE7Cit9CisKKy8vIENvbmZpZyBmb3IgYSBjbGllbnQgdGhhdCB3YW50cyB0byBkb3dubG9hZCB0aGVpciBkYXRhIGZpbGUgZ3JvdXAgdXNpbmcKKy8vIGEgcGhlbm90eXBlIGZsYWcuIEl0IGNvbnRhaW5zIHRoZSBwaGVub3R5cGUgZmxhZyBuYW1lIHdoZXJlIHRoZSBjbGllbnQKKy8vIGNvbmZpZyBpcyBwcmVzZW50LgorLy8gVGhpcyBpcyB1c2VkIGJ5IGNsaWVudHMgdGhhdCB3YW50IHRvIGRvd25sb2FkIGRhdGEgZmlsZXMgY29uZGl0aW9uYWxseS4gSXRzCisvLyBjdXJyZW50IHVzYWdlIGlzIHRvIGRvd25sb2FkIHdlYnJlZiBzbGljZXMuCittZXNzYWdlIFBoQ2xpZW50IHsKKyAgLy8gVGhlIHBoZW5vdHlwZSBmbGFnIG5hbWUgd2hlcmUgdGhlIGNvbmZpZyBpcyBwcmVzZW50LgorICBvcHRpb25hbCBzdHJpbmcgcGhfZmxhZ19uYW1lID0gMTsKK30KKworLy8gTWFuaWZlc3RDb25maWcgdG8gc3VwcG9ydCBvbiBkZXZpY2UgdGFyZ2V0aW5nLgorLy8gVGhlIE1hbmlmZXN0Q29uZmlnIGNvdWxkIGJlIGluIGEgcGF5bG9hZCBvZiBhIFBIIGZsYWcgb3IgaXQgY291bGQgYmUgaW4gdGhlCisvLyBjb250ZW50IG9mIGEgTWFuaWZlc3QgZmlsZS4gU2VlIDxpbnRlcm5hbD4gZm9yIG1vcmUKKy8vIGRldGFpbHMuCisvLyBFYWNoIE1hbmlmZXN0Q29uZmlnLkVudHJ5IHdpbGwgaGF2ZSBhIE1vZGlmaWVyIGFuZCBhIGNvcnJlc3BvbmRpbmcKKy8vIERhdGFGaWxlR3JvdXAuIFRoZSBNb2RpZmllciB3aWxsIGJlIHVzZWQgZm9yIG9uIGRldmljZSBmaWx0ZXJpbmcvdGFyZ2V0aW5nLgorbWVzc2FnZSBNYW5pZmVzdENvbmZpZyB7CisgIG1lc3NhZ2UgRW50cnkgeworICAgIC8vIEFsbCB0aGUgbW9kaWZpZXIgdmFyaWFibGVzIGFyZSB1c2VkIGZvciBmaWx0ZXJpbmcvdGFyZ2V0aW5nIG9uIHRoZSBkZXZpY2UKKyAgICAvLyBzaWRlLiBGb3IgZXhhbXBsZSwgd2UgY2FuIHNwZWNpZnkgdGhlIGxvY2FsZSAiZW5fVVMiIGFuZCBkb2VzIHRoZQorICAgIC8vIHRhcmdldGluZyBvbiB0aGUgZGV2aWNlIGJhc2VkIG9uIHRoaXMgbG9jYWxlLiBJZiB5b3UgbmVlZCB0byBhZGQgbW9yZQorICAgIC8vIGZpZWxkcyB0byBNb2RpZmllciwgcGxlYXNlIGVtYWlsIDxpbnRlcm5hbD5ALgorICAgIG1lc3NhZ2UgTW9kaWZpZXIgeworICAgICAgLy8gTG9jYWxlcyBmb3Igd2hpY2ggdGhpcyBEYXRhRmlsZUdyb3VwIGlzIHZhbGlkLgorICAgICAgLy8gTG9jYWxlcyBkZWZpbmVkIGhlcmUgYXJlIGFwcGxpY2F0aW9uJ3Mgc3BlY2lmaWMuCisgICAgICAvLyBJdCB3aWxsIGJlIGNvbnN1bWVkIGJ5IHRoZSBhcHBsaWNhdGlvbidzCisgICAgICAvLyBNYW5pZmVzdENvbmZpZ0ZsYWdQb3B1bGF0b3IuT3ZlcnJpZGVyIHRvIGRvIG9uLWRldmljZSB0YXJnZXRpbmcuIFRoZQorICAgICAgLy8gT3ZlcnJpZGVyIHdpbGwgaW50ZXJwcmV0ZSB0aGUgbG9jYWxlcyB0byBzZWxlY3QgYmVzdCBsb2NhbGUgbWF0Y2hlcy4KKyAgICAgIC8vIEZvciBleGFtcGxlLCBpdCBjYW4gaW52b2tlIHRoZSBMYW5ndWFnZU1hdGNoZXIgWzFdIHRvIHN1cHBvcnQKKyAgICAgIC8vICJMb2NhbCBJbmhlcml0YW5jZSIgWzJdLgorICAgICAgLy8gWzFdCisgICAgICAvLyA8aW50ZXJuYWw+CisgICAgICAvLyBbMl0gPGludGVybmFsPgorICAgICAgcmVwZWF0ZWQgc3RyaW5nIGxvY2FsZSA9IDE7CisKKyAgICAgIC8vIEN1c3RvbSBQcm9wZXJ0aWVzLgorICAgICAgLy8gRGVmaW5lZCBieSBlYWNoIGFwcGxpY2F0aW9uLiBUaGUgYXBwbGljYXRpb24gbmVlZHMgdG8gcHJvdmlkZSBhCisgICAgICAvLyBNYW5pZmVzdENvbmZpZ092ZXJyaWRlcgorICAgICAgLy8gKDxpbnRlcm5hbD4KKyAgICAgIC8vIHRoYXQgdW5kZXJzdGFuZHMgYW5kIGZpbHRlcnMgZW50cmllcyBiYXNlZCBvbiB0aGlzIEN1c3RvbSBQcm9wZXJ0aWVzLgorICAgICAgb3B0aW9uYWwgZ29vZ2xlLnByb3RvYnVmLkFueSBjdXN0b21fcHJvcGVydGllcyA9IDI7CisKKyAgICAgIG1lc3NhZ2UgTG9jYXRpb24geworICAgICAgICAvLyBTMkNlbGxJZCAoPGludGVybmFsPikgYXNzb2NpYXRlZCB3aXRoIHRoaXMgRGF0YUZpbGVHcm91cC4gSXQgd2lsbCBiZQorICAgICAgICAvLyB1c2VkIHRvIGRvIGxvY2F0aW9uIGJhc2VkIHRhcmdldGluZyBvbiBkZXZpY2UsIG9wdGlvbmFsbHkgZmlsdGVyaW5nCisgICAgICAgIC8vIGV4dHJhbmVvdXMgc2xpY2VzIGlmIHRoZSB1c2VyIGhhcyBsb2NhdGlvbiBwZXJtaXNzaW9ucyBlbmFibGVkLgorICAgICAgICAvLyBPdGhlcndpc2UgbG9jYXRpb24gdGFyZ2V0aW5nIHdpbGwgYmUgYmFzZWQgb24gYSByb3VnaCBlc3RpbWF0ZSBmcm9tCisgICAgICAgIC8vIElQLWJhc2VkIGdlb2xvY2F0aW9uIG9uIHRoZSBzZXJ2ZXIuIFRoZSB0eXBlIGZpeGVkNjQgaXMgYSBiaXQgbW9yZQorICAgICAgICAvLyBlZmZpY2llbnQgdGhhbiBpbnQ2NCBmb3Igb3VyIHB1cnBvc2VzLiBUaGlzIGlzIGJlY2F1c2UgaW50NjQgdXNlcworICAgICAgICAvLyBwcmVmaXggZW5jb2RpbmcsIGhvd2V2ZXIsIGZvciB0aGUgUzJDZWxsSWRzIHRoZSBoaWdoLW9yZGVyIGJpdHMKKyAgICAgICAgLy8gZW5jb2RlIHRoZSBmYWNlLUlEIGFuZCBhcyBhIHJlc3VsdCB3ZSBvZnRlbiBlbmQgdXAgd2l0aCBsYXJnZQorICAgICAgICAvLyBudW1iZXJzLgorICAgICAgICBvcHRpb25hbCBmaXhlZDY0IHMyX2NlbGxfaWQgPSAxOworICAgICAgfQorCisgICAgICBvcHRpb25hbCBMb2NhdGlvbiBsb2NhdGlvbiA9IDM7CisgICAgfQorCisgICAgb3B0aW9uYWwgTW9kaWZpZXIgbW9kaWZpZXIgPSAxOworICAgIG9wdGlvbmFsIERhdGFGaWxlR3JvdXAgZGF0YV9maWxlX2dyb3VwID0gMjsKKyAgfQorCisgIG1lc3NhZ2UgVXJsVGVtcGxhdGUgeworICAgIC8vIFRlbXBsYXRlIHRvIGNvbnN0cnVjdCBhIHtAY29kZSBEYXRhRmlsZX0ncyB1cmxfdG9fZG93bmxvYWQgb24gZGV2aWNlLgorICAgIC8vIElmIHRoZSB1cmwgdGVtcGxhdGUgc2hvdWxkIGJlIHVzZWQsIHRoZSB1cmxfdG9fZG93bmxvYWQgZmllbGQgc2hvdWxkIGJlCisgICAgLy8gbGVmdCB1bnBvcHVsYXRlZC4gSWYgdGhlIHVybCB0ZW1wbGF0ZSBhbmQgdGhlIHVybF90b19kb3dubG9hZCBhcmUgYm90aAorICAgIC8vIHBvcHVsYXRlZCwgdGhlIHRlbXBsYXRlIHdpbGwgYmUgaWdub3JlZC4KKyAgICBvcHRpb25hbCBzdHJpbmcgZmlsZV91cmxfdGVtcGxhdGUgPSAxOworICB9CisKKyAgcmVwZWF0ZWQgRW50cnkgZW50cnkgPSAxOworCisgIC8vIFRlbXBsYXRlIGRlZmluaXRpb24gZm9yIGNvbnN0cnVjdGluZyBVUkxzIG9uIGRldmljZS4gSXQgYXBwbGllcyB0byBldmVyeQorICAvLyBEYXRhRmlsZSBkZWZpbmVkIGluIHRoZSBNYW5pZmVzdENvbmZpZy4KKyAgb3B0aW9uYWwgVXJsVGVtcGxhdGUgdXJsX3RlbXBsYXRlID0gMjsKK30KKworLy8gVGhlIGZsYWcgdGhhdCBNREQgZ2V0cyBmcm9tIFAvSCwgYW5kIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtYW5pZmVzdAorLy8gZmlsZSB0byBiZSBkb3dubG9hZGVkLgorLy8gTmV4dCBpZDogMworbWVzc2FnZSBNYW5pZmVzdEZpbGVGbGFnIHsKKyAgLy8gVGhlIElEIGZvciB0aGUgbWFuaWZlc3QgZmlsZS4gVGhpcyBzaG91bGQgYmUgdW5pcXVlIGluIHRoZSBob3N0IGFwcCBzcGFjZS4KKyAgb3B0aW9uYWwgc3RyaW5nIG1hbmlmZXN0X2lkID0gMTsKKworICAvLyBUaGUgdXJsIHRvIHRoZSBtYW5pZmVzdCBmaWxlIG9uIEdvb2dsZSBob3N0aW5nIHNlcnZpY2UuCisgIG9wdGlvbmFsIHN0cmluZyBtYW5pZmVzdF9maWxlX3VybCA9IDI7Cit9CmRpZmYgLS1naXQgYS9wcm90by9qYXJqYXItcnVsZXMudHh0IGIvcHJvdG8vamFyamFyLXJ1bGVzLnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMzVmM2Y4Ci0tLSAvZGV2L251bGwKKysrIGIvcHJvdG8vamFyamFyLXJ1bGVzLnR4dApAQCAtMCwwICsxLDMgQEAKKworIyBVc2Ugb3VyIHN0YXRpY2FsbHkgbGlua2VkIHByb3RvYnVmIGxpYnJhcnkKKyMgcnVsZSBjb20uZ29vZ2xlLnByb3RvYnVmLioqIGNvbS5hbmRyb2lkLmFkc2VydmljZXMucHJvdG9idWYuQDEKZGlmZiAtLWdpdCBhL3Byb3RvL21ldGFkYXRhLnByb3RvIGIvcHJvdG8vbWV0YWRhdGEucHJvdG8KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGI4MTVkMgotLS0gL2Rldi9udWxsCisrKyBiL3Byb3RvL21ldGFkYXRhLnByb3RvCkBAIC0wLDAgKzEsNjczIEBACisvLyBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDCisvLworLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CisvLyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCisvLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKy8vCisvLyAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAorLy8KKy8vIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKy8vIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCisvLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KKy8vIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKy8vIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgorLy8gVGhlIG1haW4gcHVycG9zZSBvZiBtaXJyb3JpbmcgZXh0ZXJuYWwgcHJvdG9zIGhlcmUgaXMgdG8gc2VwYXJhdGUgQVBJIGFuZAorLy8gc3RvcmFnZSBwcm90b3MuIFRoZSBzYW1lIHRhZyBudW1iZXJzIGFyZSB1c2VkIGZvciBtYWtpbmcgbWlncmF0aW9uIHdvcmsuCisKK3N5bnRheCA9ICJwcm90bzIiOworCitwYWNrYWdlIG1kaS5kb3dubG9hZC5pbnRlcm5hbDsKKworaW1wb3J0ICJnb29nbGUvcHJvdG9idWYvYW55LnByb3RvIjsKK2ltcG9ydCAiZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wcm90byI7CitpbXBvcnQgInRyYW5zZm9ybS5wcm90byI7CisKK29wdGlvbiBqYXZhX3BhY2thZ2UgPSAiY29tLmdvb2dsZS5tb2JpbGVkYXRhZG93bmxvYWQuaW50ZXJuYWwiOworb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIk1ldGFkYXRhUHJvdG8iOworCisvLyBNaXJyb3JzIG1kaS5kb3dubG9hZC5FeHRyYUh0dHBIZWFkZXIKKy8vCisvLyBIVFRQIGhlYWRlcnMgYXJlIGRlc2NyaWJlZCBpbiBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNzIzMCNzZWN0aW9uLTMuMgorLy8gYXMga2V5OnZhbHVlLCB3aGVyZSB0aGUgdmFsdWUgbWF5IGhhdmUgYSB3aGl0ZXNwYWNlIG9uIGVhY2ggZW5kLgorbWVzc2FnZSBFeHRyYUh0dHBIZWFkZXIgeworICBvcHRpb25hbCBzdHJpbmcga2V5ID0gMTsKKyAgb3B0aW9uYWwgc3RyaW5nIHZhbHVlID0gMjsKK30KKworLy8gVGhpcyBwcm90byBpcyB1c2VkIHRvIHN0b3JlIGZpbGUgZ3JvdXAgbWV0YWRhdGEgb24gZGlzayBmb3IgaW50ZXJuYWwgdXNlLiBJdAorLy8gY29uc2lzdHMgb2YgYWxsIGZpZWxkcyBtaXJyb3JlZCBmcm9tIERhdGFGaWxlR3JvdXAgYW5kIGFuIGV4dHJhIGZpZWxkIGZvcgorLy8gYm9va2tlZXBpbmcuCisvLworLy8gVGhlIHRhZyBudW1iZXIgb2YgZXh0cmEgZmllbGRzIHNob3VsZCBzdGFydCBmcm9tIDEwMDAgdG8gcmVzZXJ2ZSByb29tIGZvcgorLy8gZ3Jvd2luZyBEYXRhRmlsZUdyb3VwLgorLy8KKy8vIE5leHQgaWQ6IDEwMDAKK21lc3NhZ2UgRGF0YUZpbGVHcm91cEludGVybmFsIHsKKyAgLy8gRXh0cmEgaW5mb3JtYXRpb24gdGhhdCBpcyBrZXB0IG9uIGRpc2suCisgIC8vCisgIC8vIFRoZSBleHRlbnNpb24gd2FzIG9yaWdpbmFsbHkgaW50cm9kdWNlZCBpbiBjbC8yNDg4MTM5NjYuIFdlIGFyZSBtaWdyYXRpbmcKKyAgLy8gYXdheSBmcm9tIHRoZSBleHRlbnNpb24uIEhvd2V2ZXIsIHdlIHN0aWxsIG5lZWQgdG8gcmVhZCBmcm9tIGZpZWxkcyBpbiB0aGUKKyAgLy8gZXh0ZW5zaW9uLiBSZXVzZSB0aGUgc2FtZSB0YWcgbnVtYmVyIGFzIHRoZSBleHRlbnNpb24gbnVtYmVyIHRvIHJlYWQgZnJvbQorICAvLyB0aGUgZXh0ZW5zaW9uLgorICBvcHRpb25hbCBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcgYm9va2tlZXBpbmcgPSAyNDg4MTM5NjY7CisKKyAgLy8gVW5pcXVlIG5hbWUgdG8gaWRlbnRpZnkgdGhlIGdyb3VwLiBJdCBzaG91bGQgYmUgdW5pcXVlIHBlciBvd25lciBwYWNrYWdlLgorICAvLyBJbiBHTVNDb3JlLCB1c2UgdGhlIG1vZHVsZSBuYW1lIGFzIHRoZSBwcmVmaXggb2YgdGhlIGdyb3VwIG5hbWUuCisgIC8vCisgIC8vIEV4OiBBIGdyb3VwIG5hbWUgaW4gbWRpc3luYyBtb2R1bGUgY291bGQgYmUgbmFtZWQ6IG1kaXN5bmMtcHJvZmlsZS1waG90b3MuCisgIC8vCisgIC8vIFRoaXMgc2hvdWxkbid0IGlkZWFsbHkgYmUgc29tZXRoaW5nIGxpa2UgImNvbmZpZyIsIGFuZAorICAvLyBpbnN0ZWFkIHNob3VsZCBiZXR0ZXIgZGVmaW5lIHRoZSBmZWF0dXJlIGl0IHdpbGwgYmUgdXNlZCBmb3IuCisgIC8vCisgIC8vIEV4OiAiaWNpbmctbGFuZ3VhZ2UtZGV0ZWN0aW9uLW1vZGVsIiwgInNtYXJ0LWFjdGlvbi1kZXRlY3Rpb24tbW9kZWwiCisgIG9wdGlvbmFsIHN0cmluZyBncm91cF9uYW1lID0gMTsKKworICAvLyBUaGUgbmFtZSBvZiB0aGUgcGFja2FnZSB0aGF0IG93bnMgdGhpcyBncm91cC4gSWYgdGhpcyBmaWVsZCBpcyBsZWZ0IGVtcHR5LAorICAvLyB0aGUgb3duZXIgaXMgYXNzdW1lZCB0byBiZSB0aGUgcGFja2FnZSBuYW1lIG9mIHRoZSBob3N0IGFwcC4KKyAgLy8KKyAgLy8gVGhlIGZpbGVzIHdpbGwgb25seSBiZSBkb3dubG9hZGVkIG9udG8gdGhlIGRldmljZSBpZiB0aGUgb3duZXIgcGFja2FnZSBpcworICAvLyBwcmVzZW50IG9uIHRoZSBkZXZpY2UuCisgIC8vCisgIC8vIEV4OiAiY29tLmdvb2dsZS5hbmRyb2lkLmdtcyIsICJjb20uZ29vZ2xlLmFuZHJvaWQuYXBwcy5idWdsZSIKKyAgb3B0aW9uYWwgc3RyaW5nIG93bmVyX3BhY2thZ2UgPSA2OworCisgIC8vIENsaWVudCBzZXQgdmVyc2lvbiBudW1iZXIgdXNlZCB0byBpZGVudGlmeSB0aGUgZmlsZSBncm91cC4KKyAgLy8KKyAgLy8gTm90ZSB0aGF0IHRoaXMgZG9lcyBub3QgdW5pcXVlbHkgaWRlbnRpZnkgdGhlIGNvbnRlbnRzIG9mIHRoZSBmaWxlIGdyb3VwLgorICAvLyBJdCBzaW1wbHkgcmVmbGVjdHMgYSBzbmFwc2hvdCBvZiBjbGllbnQgY29uZmlnIGNoYW5nZXMuCisgIC8vIEZvciBleGFtcGxlOiBzYXkgdGhlcmUncyBhIGZpbGUgZ3JvdXAgJ2xhbmd1YWdlLWRldGVjdG9yLW1vZGVsJyB0aGF0CisgIC8vIGRvd25sb2FkcyBhIGRpZmZlcmVudCBmaWxlIHBlciB1c2VyIGxvY2FsZS4KKyAgLy8gZGF0YV9maWxlX2dyb3VwIHsKKyAgLy8gICBmaWxlX2dyb3VwX25hbWUgPSAnbGFuZ3VhZ2UtZGV0ZWN0b3ItbW9kZWwnCisgIC8vICAgZmlsZV9ncm91cF92ZXJzaW9uX251bWJlciA9IDEKKyAgLy8gICBmaWxlIHsKKyAgLy8gICAgICB1cmwgPSAnZW4tbW9kZWwnCisgIC8vICAgfQorICAvLyB9CisgIC8vIGRhdGFfZmlsZV9ncm91cCB7CisgIC8vICAgZmlsZV9ncm91cF9uYW1lID0gJ2xhbmd1YWdlLWRldGVjdG9yLW1vZGVsJworICAvLyAgIGZpbGVfZ3JvdXBfdmVyc2lvbl9udW1iZXIgPSAxCisgIC8vICAgZmlsZSB7CisgIC8vICAgICAgdXJsID0gJ2VzLW1vZGVsJworICAvLyAgIH0KKyAgLy8gfQorICAvLyBOb3RlIHRoYXQgZXZlbiB0aG91Z2ggdGhlIGFjdHVhbCBjb250ZW50cyBvZiB0aGUgZmlsZSBncm91cCBhcmUgZGlmZmVyZW50CisgIC8vIGZvciBlYWNoIGxvY2FsZSwgdGhlIHZlcnNpb24gaXMgdGhlIHNhbWUgYmVjYXVzZSB0aGlzIGNvbmZpZyB3YXMgcHVzaGVkCisgIC8vIGF0IHRoZSBzYW1lIHNuYXBzaG90LgorICAvLworICAvLyBBdmFpbGFibGUgR01TIHYxOCsuCisgIG9wdGlvbmFsIGludDMyIGZpbGVfZ3JvdXBfdmVyc2lvbl9udW1iZXIgPSAxMDsKKworICAvLyBERVBSRUNBVEVECisgIC8vIE1ERCB0ZWFtIHJlY29tbWVuZHMgdG8gdXNlIGV4cGxpY2l0IHByb3BlcnRpZXMgaW5zdGVhZC4KKyAgb3B0aW9uYWwgZ29vZ2xlLnByb3RvYnVmLkFueSBjdXN0b21fcHJvcGVydHkgPSAyMCBbZGVwcmVjYXRlZCA9IHRydWVdOworCisgIC8vIEN1c3RvbSBtZXRhZGF0YSBhdHRhY2hlZCB0byB0aGUgZmlsZSBncm91cC4KKyAgLy8KKyAgLy8gVGhpcyBhbGxvd3MgY2xpZW50cyB0byBpbmNsdWRlIHNwZWNpZmljIG1ldGFkYXRhIGFib3V0IHRoZSBncm91cCBmb3IgdGhlaXIKKyAgLy8gb3duIHByb2Nlc3NpbmcgcHVycG9zZXMuIFRoZSBtZXRhZGF0YSB3aWxsIGJlIHN0b3JlZCB3aXRoIHRoZSBncm91cCBhbmQKKyAgLy8gYWNjZXNzaWJsZSB3aGVuIHRoZSBmaWxlIGdyb3VwIGlzIHJldHJpZXZlZC4KKyAgLy8KKyAgLy8gVGhpcyBwcm9wZXJ0eSBzaG91bGQgb25seSBiZSB1c2VkIGlmIGFic29sdXRlbHkgbmVjZXNzYXJ5LiBQbGVhc2UgY29uc3VsdAorICAvLyB3aXRoIDxpbnRlcm5hbD5AIGlmIHlvdSBoYXZlIHF1ZXN0aW9ucyBhYm91dCB0aGlzIHByb3BlcnR5IG9yIGEgcG90ZW50aWFsCisgIC8vIHVzZS1jYXNlLgorICBvcHRpb25hbCBnb29nbGUucHJvdG9idWYuQW55IGN1c3RvbV9tZXRhZGF0YSA9IDI3OworCisgIHJlc2VydmVkIDIxOworCisgIC8vIE1pcnJvcnMgbWRpLmRvd25sb2FkLkRhdGFGaWxlR3JvdXAuQWxsb3dlZFJlYWRlcnMKKyAgZW51bSBBbGxvd2VkUmVhZGVycyB7CisgICAgQUxMX0dPT0dMRV9BUFBTID0gMDsKKyAgICBPTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTID0gMTsKKyAgICBBTExfQVBQUyA9IDI7CisgIH0KKworICAvLyBEZWZpbmVzIHdobyBpcyBhbGxvd2VkIHRvIHJlYWQgdGhpcyBmaWxlIGdyb3VwLiBDdXJyZW50bHkgdGhlIG9wdGlvbnMgYXJlOgorICAvLworICAvLyBBTExfR09PR0xFX0FQUFM6IGFjY2Vzc2libGUgdG8gYWxsIEdvb2dsZSAxcCBBcHBzLgorICAvLyBPTkxZX0dPT0dMRV9QTEFZX1NFUlZJQ0VTOiBhY2Nlc3NpYmxlIHRvIG9ubHkgR01TIENvcmUuCisgIC8vCisgIC8vIElmIHRoaXMgZmllbGQgaXMgbm90IGV4cGxpY2l0bHkgc2V0IGl0IGRlZmF1bHRzIHRvICJBTExfR09PR0xFX0FQUFMiLgorICAvLworICAvLyBBdmFpbGFibGUgR01TIHYyMCsuCisgIG9wdGlvbmFsIEFsbG93ZWRSZWFkZXJzIGFsbG93ZWRfcmVhZGVyc19lbnVtID0gMTI7CisKKyAgLy8gTGVuZ3RoIG9mIHRpbWUgKGluIHNlY29uZHMpIGZvciB3aGljaCBhIGZpbGUgZ3JvdXAgdmVyc2lvbiB3aWxsIGxpdmUgYWZ0ZXIKKyAgLy8gc2luY2UgYSBuZXdlciB2ZXJzaW9uIGJlY2FtZSBmdWxseSBkb3dubG9hZGVkLiBDbGllbnRzIHNob3VsZCBzZXQgdGhpcyB0aW1lCisgIC8vIHRvIGJlIG1vcmUgdGhhbiB0aGUgdGltZSBpbiB3aGljaCB0aGV5IGNhbGwgTUREIHRvIHJlZnJlc2ggdGhlaXIgZGF0YS4KKyAgLy8gTk9URTogTUREIHdpbGwgZGVsZXRlIHRoZSBmaWxlIGdyb3VwIHZlcnNpb24gd2l0aGluIGEgZGF5IG9mIHRoaXMgdGltZS4KKyAgLy8gRXg6IDE3MjgwMCAgLy8gMiBEYXlzCisgIG9wdGlvbmFsIGludDY0IHN0YWxlX2xpZmV0aW1lX3NlY3MgPSAzOworCisgIC8vIFRoZSB0aW1lc3RhbXAgYXQgd2hpY2ggdGhpcyBmaWxlZ3JvdXAgc2hvdWxkIGJlIGRlbGV0ZWQsIGV2ZW4gaWYgaXQgaXMKKyAgLy8gc3RpbGwgYWN0aXZlLCBzcGVjaWZpZWQgaW4gc2Vjb25kcyBzaW5jZSBlcG9jaC4KKyAgLy8gTk9URTogTUREIHdpbGwgZGVsZXRlIHRoZSBmaWxlIGdyb3VwIHZlcnNpb24gd2l0aGluIGEgZGF5IG9mIHRoaXMgdGltZS4KKyAgb3B0aW9uYWwgaW50NjQgZXhwaXJhdGlvbl9kYXRlX3NlY3MgPSAxMTsKKworICAvLyBTcGVjaWZ5IHRoZSBjb25kaXRpb25zIHVuZGVyIHdoaWNoIHRoZSBmaWxlIGdyb3VwIHNob3VsZCBiZSBkb3dubG9hZGVkLgorICBvcHRpb25hbCBEb3dubG9hZENvbmRpdGlvbnMgZG93bmxvYWRfY29uZGl0aW9ucyA9IDEzOworCisgIC8vIFNldHRpbmcgdGhpcyBmbGFnIHRvIHRydWUgd2lsbCBtZWFuIHRoYXQgdGhlIGRvd25sb2FkZWQgZmlsZXMgd2lsbCBhcHBlYXIKKyAgLy8gdG8gYmUgaW4gYSBkaXJlY3RvcnkgYnkgdGhlbXNlbHZlcy4KKyAgLy8gVGhlIGZpbGUgbmFtZS9maWxlIHBhdGggb2YgdGhlIGV4cG9zZWQgZmlsZSB3aWxsIGJlIHRoZSBmaWxlbmFtZSBzZXQgaW4gdGhlCisgIC8vIGZpbGUucmVsYXRpdmVfZmlsZV9wYXRoIGZpZWxkLCBPUiBpZiB0aGF0IGZpZWxkIGlzIGVtcHR5LCB0aGUgZmlsZSBuYW1lCisgIC8vIGZyb20gdGhlIGZpbGUudXJsX3RvX2Rvd25sb2FkIGZpZWxkLiBUaGlzIGVuYWJsZXMgZG93bmxvYWRlZCBmaWxlcyB0byByZWZlcgorICAvLyB0byBlYWNoIG90aGVyIGJ5IG5hbWUuCisgIC8vIEl0J3MgaW52YWxpZCB0byBzZXQgdGhpcyBmbGFnIHRvIHRydWUgaWYgdHdvIGZpbGVzIGVuZCB1cCB3aXRoIHRoZSBzYW1lCisgIC8vIGZpbGUgcGF0aC4KKyAgLy8gVmFsaWQgb24gaU9TLCBjTURELCBhbmQgYU1ERC4KKyAgLy8KKyAgLy8gTk9URTogRm9yIGFNREQsIHRoaXMgZmVhdHVyZSBpcyBub3QgYXZhaWxhYmxlIGlmIEFuZHJvaWQgQmxvYiBTaGFyaW5nIGlzCisgIC8vIGVuYWJsZWQgb3IgaWYgdXNpbmcgYW4gQVBJIGxldmVsIGJlbG93IDIxIChMKS4gSWYgZWl0aGVyIGNhc2UgaXMgdHJ1ZSwgdGhpcworICAvLyBvcHRpb24gd2lsbCBiZSBpZ25vcmVkLgorICBvcHRpb25hbCBib29sIHByZXNlcnZlX2ZpbGVuYW1lc19hbmRfaXNvbGF0ZV9maWxlcyA9IDE0OworCisgIC8vIExpc3Qgb2YgZmlsZXMgaW4gdGhlIGdyb3VwLgorICByZXBlYXRlZCBEYXRhRmlsZSBmaWxlID0gMjsKKworICAvLyBUYWcgZm9yIHRoZSBuZXR3b3JrIHRyYWZmaWMgdG8gZG93bmxvYWQgdGhpcyBmaWxlIGdyb3VwLgorICAvLyBUYWcgc3BhY2UgaXMgZGV0ZXJtaW5lZCBieSB0aGUgaG9zdCBhcHAuCisgIC8vIEZvciBHbXNjb3JlLCB0aGUgdGFnIHNob3VsZCBjb21lIGZyb206CisgIC8vIDxpbnRlcm5hbD4KKyAgb3B0aW9uYWwgaW50MzIgdHJhZmZpY190YWcgPSAxNjsKKworICAvLyBFeHRyYSBIVFRQIGhlYWRlcnMgdG8gYXBwbHkgd2hlbiBkb3dubG9hZGluZyBhbGwgZmlsZXMgaW4gdGhlIGdyb3VwLgorICByZXBlYXRlZCBFeHRyYUh0dHBIZWFkZXIgZ3JvdXBfZXh0cmFfaHR0cF9oZWFkZXJzID0gMTc7CisKKyAgcmVzZXJ2ZWQgMTk7CisKKyAgLy8gVW5pcXVlIGlkZW50aWZpZXIgb2YgYSBEYXRhRmlsZUdyb3VwIGNvbmZpZyAoaS5lLiBhICJzbmFwc2hvdCIpIGNyZWF0ZWQKKyAgLy8gd2hlbiB1c2luZyBNREQgSW5ncmVzcyBBUEkuCisgIG9wdGlvbmFsIGludDY0IGJ1aWxkX2lkID0gMjM7CisKKyAgLy8gQSBmaW5nZXJwcmludCBhbGxvd2luZyBjbGllbnRzIHRvIGlkZW50aWZ5IGEgRGF0YUZpbGVHcm91cAorICAvLyBjb25maWcgYmFzZWQgb24gYSBnaXZlbiBzZXQgb2YgcHJvcGVydGllcyAoaS5lLiBhICJwYXJ0aXRpb24iIG9mCisgIC8vIGFueSBmaWxlIGdyb3VwIHByb3BlcnRpZXMpLiBUaGlzIGNhbiBiZSB1c2VkIGJ5IGNsaWVudHMgYXMgYW4gZXhhY3QgbWF0Y2gKKyAgLy8gZm9yIGEgY2xhc3Mgb2YgRGF0YUZpbGVHcm91cHMgZHVyaW5nIHRhcmdldGluZyBvciBhcyBhIGNvbXBhdGliaWxpdHkgY2hlY2suCisgIG9wdGlvbmFsIHN0cmluZyB2YXJpYW50X2lkID0gMjY7CisKKyAgLy8gVGhlIGxvY2FsZXMgY29tcGF0aWJsZSB3aXRoIHRoZSBmaWxlIGdyb3VwLiBUaGlzIGNhbiBiZSBkaWZmZXJlbnQgZnJvbSB0aGUKKyAgLy8gZGV2aWNlIGxvY2FsZS4KKyAgLy8KKyAgLy8gVmFsdWVzIGluIHRoaXMgbGlzdCBtYXkgYmUgZXhhY3QgbG9jYWxlcyAoZS5nLiAiZW4tVVMiKSBvciBsYW5ndWFnZS1vbmx5CisgIC8vICgiZW4tKiIpLgorICAvLyBFeGFtcGxlIDE6IGxvY2FsZSA9IFsiZW4tVVMiXTsgLy8gY29tcGF0aWJsZSB3aXRoICJlbi1VUyIgb25seQorICAvLyBFeGFtcGxlIDI6IGxvY2FsZSA9IFsiZW4tVVMiLCAiZW4tQ0EiXTsgLy8gY29tcGF0aWJsZSB3aXRoICJlbi1VUyIgb3IKKyAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICJlbi1DQSIKKyAgLy8gRXhhbXBsZSAzOiBsb2NhbGUgPSBbImVuLSoiXTsgLy8gY29tcGF0aWJsZSB3aXRoIGFsbCAiZW4iIGxvY2FsZXMKKyAgcmVwZWF0ZWQgc3RyaW5nIGxvY2FsZSA9IDI1OworCisgIHJlc2VydmVkIDI4OworCisgIHJlc2VydmVkIDQsIDUsIDcsIDgsIDksIDE1LCAxOCwgMjIsIDI0OworfQorCisvLyBNaXJyb3JzIG1kaS5kb3dubG9hZC5EYXRhRmlsZQorLy8KKy8vIEEgZGF0YSBmaWxlIHJlcHJlc2VudHMgYWxsIHRoZSBtZXRhZGF0YSB0byBkb3dubG9hZCB0aGUgZmlsZSBhbmQgdGhlbgorLy8gbWFuYWdlIGl0IG9uIHRoZSBkZXZpY2UuCisvLyBOZXh0IHRhZzogMjIKKy8vCisvLyBUaGlzIHNob3VsZCBub3QgY29udGFpbiBhbnkgZmllbGRzIHRoYXQgYXJlIG1hcmtlZCBpbnRlcm5hbCwgYXMgd2UgY29tcGFyZQorLy8gdGhlIHByb3RvcyBkaXJlY3RseSB0byBkZWNpZGUgaWYgaXQgaXMgYSBuZXcgdmVyc2lvbiBvZiB0aGUgZmlsZS4KKy8vIExJTlQuSWZDaGFuZ2UoZGF0YV9maWxlKQorbWVzc2FnZSBEYXRhRmlsZSB7CisgIC8vIEEgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGZpbGUgd2l0aGluIHRoZSBncm91cCwgdGhhdCBjYW4gYmUgdXNlZCB0bworICAvLyBnZXQgdGhpcyBmaWxlIGZyb20gdGhlIGdyb3VwLgorICAvLyBFeDogImxhbmd1YWdlLWRldGVjdGlvbi1tb2RlbCIKKyAgb3B0aW9uYWwgc3RyaW5nIGZpbGVfaWQgPSA3OworCisgIC8vIFVybCBmcm9tIHdoZXJlIHRoZSBmaWxlIGlzIHRvIGJlIGRvd25sb2FkZWQuCisgIC8vIEV4OiBodHRwczovL3d3dy5nc3RhdGljLmNvbS9ncm91cC1uYW1lL21vZGVsXzEyMzQuemlwCisgIG9wdGlvbmFsIHN0cmluZyB1cmxfdG9fZG93bmxvYWQgPSAyOworCisgIC8vIEV4YWN0IHNpemUgb2YgdGhlIGZpbGUuIFRoaXMgaXMgdXNlZCB0byBjaGVjayBpZiB0aGVyZSBpcyBzcGFjZSBhdmFpbGFibGUKKyAgLy8gZm9yIHRoZSBmaWxlIGJlZm9yZSBzY2hlZHVsaW5nIHRoZSBkb3dubG9hZC4KKyAgLy8gVGhlIGJ5dGVfc2l6ZSBpcyBvcHRpb25hbC4gSWYgbm90IHNldCwgTUREIHdpbGwgdHJ5IHdpdGggYmVzdCBlZmZvcnQgdG8gZ2V0CisgIC8vIHRoZSBmaWxlIHNpemUgdXNpbmcgdGhlIEhUVFAgSEVBRCByZXF1ZXN0LgorICBvcHRpb25hbCBpbnQzMiBieXRlX3NpemUgPSA0OworCisgIC8vIEVudW0gZm9yIGNoZWNrc3VtIHR5cGVzLgorICAvLyBOT1RFOiBkbyBub3QgYWRkIGFueSBuZXcgY2hlY2tzdW0gdHlwZSBoZXJlLCBvbGRlciBNREQgdmVyc2lvbnMgd291bGQgYnJlYWsKKyAgLy8gb3RoZXJ3aXNlLgorICBlbnVtIENoZWNrc3VtVHlwZSB7CisgICAgLy8gRGVmYXVsdCBjaGVja3N1bSBpcyBTSEExLgorICAgIERFRkFVTFQgPSAwOworCisgICAgLy8gTm8gY2hlY2tzdW0gaXMgcHJvdmlkZWQuCisgICAgTk9ORSA9IDE7CisKKyAgICByZXNlcnZlZCAyIC8qIFNIQTI1NiAqLzsKKyAgfQorCisgIG9wdGlvbmFsIENoZWNrc3VtVHlwZSBjaGVja3N1bV90eXBlID0gMTU7CisKKyAgLy8gU0hBMSBjaGVja3N1bSB0byB2ZXJpZnkgdGhlIGZpbGUgYmVmb3JlIGl0IGNhbiBiZSB1c2VkLiBUaGlzIGlzIGFsc28gdXNlZAorICAvLyB0byBkZS1kdXBsaWNhdGUgZmlsZXMgYmV0d2VlbiBkaWZmZXJlbnQgZ3JvdXBzLgorICAvLyBGb3IgbW9zdCBmaWxlcywgdGhpcyB3aWxsIGJlIHRoZSBjaGVja3N1bSBvZiB0aGUgZmlsZSBiZWluZyBkb3dubG9hZGVkLgorICAvLyBGb3IgZmlsZXMgd2l0aCBkb3dubG9hZF90cmFuc2Zvcm0sIHRoaXMgc2hvdWxkIGNvbnRhaW4gdGhlIHRyYW5zZm9ybSBvZgorICAvLyB0aGUgZmlsZSBhZnRlciB0aGUgdHJhbnNmb3JtcyBoYXZlIGJlZW4gYXBwbGllZC4KKyAgLy8gVGhlIGNoZWNrc3VtIGlzIG9wdGlvbmFsLiBJZiBub3Qgc2V0LCB0aGUgY2hlY2tzdW1fdHlwZSBtdXN0IGJlCisgIC8vIENoZWNrc3VtVHlwZS5OT05FLgorICBvcHRpb25hbCBzdHJpbmcgY2hlY2tzdW0gPSA1OworCisgIC8vIFRoZSBmb2xsb3dpbmcgYXJlIDxpbnRlcm5hbD4gdHJhbnNmb3JtcyB0byBhcHBseSB0byB0aGUgZG93bmxvYWRlZCBmaWxlcy4KKyAgLy8gVHJhbnNmb3JtcyBhcmUgYmktZGlyZWN0aW9uYWwgYW5kIGRlZmluZWQgaW4gdGVybXMgb2Ygd2hhdCB0aGV5IGRvIG9uCisgIC8vIHdyaXRlLiBTaW5jZSB0aGVzZSB0cmFuc2Zvcm1zIGFyZSBhcHBsaWVkIHdoaWxlIHJlYWRpbmcsIHRoZWlyCisgIC8vIGRpcmVjdGlvbmFsaXR5IGlzIHJldmVyc2VkLiBFZywgeW91J2xsIHNlZSAnY29tcHJlc3MnIHRvIGluZGljYXRlIHRoYXQgdGhlCisgIC8vIGZpbGUgc2hvdWxkIGJlIGRlY29tcHJlc3NlZC4KKworICAvLyBUaGVzZSB0cmFuc2Zvcm1zIGFyZSBhcHBsaWVkIG9uY2UgYnkgTUREIGFmdGVyIGRvd25sb2FkaW5nIHRoZSBmaWxlLgorICAvLyBDdXJyZW50bHkgb25seSBjb21wcmVzcyBpcyBhdmFpbGFibGUuCisgIC8vIFZhbGlkIG9uIEFuZHJvaWQuIGlPUyBzdXBwb3J0IGlzIHRyYWNrZWQgYnkgYi8xMTg4MjgwNDUuCisgIG9wdGlvbmFsIG1vYnN0b3JlLnByb3RvLlRyYW5zZm9ybXMgZG93bmxvYWRfdHJhbnNmb3JtcyA9IDExOworCisgIC8vIElmIERhdGFGaWxlIGhhcyBkb3dubG9hZF90cmFuc2Zvcm1zLCB0aGlzIGZpZWxkIG11c3QgYmUgcHJvdmlkZWQgd2l0aCB0aGUKKyAgLy8gU0hBMSBjaGVja3N1bSBvZiB0aGUgZmlsZSBiZWZvcmUgYW55IHRyYW5zZm9ybSBhcmUgYXBwbGllZC4gVGhlIG9yaWdpbmFsCisgIC8vIGNoZWNrc3VtIHdvdWxkIGFsc28gYmUgY2hlY2tlZCBhZnRlciB0aGUgZG93bmxvYWRfdHJhbnNmb3JtcyBhcmUgYXBwbGllZC4KKyAgb3B0aW9uYWwgc3RyaW5nIGRvd25sb2FkZWRfZmlsZV9jaGVja3N1bSA9IDE0OworCisgIC8vIEV4YWN0IHNpemUgb2YgdGhlIGRvd25sb2FkZWQgZmlsZS4gSWYgdGhlIERhdGFGaWxlIGhhcyBkb3dubG9hZCB0cmFuc2Zvcm1zCisgIC8vIGxpa2UgY29tcHJlc3MgYW5kIHppcCwgdGhlIGRvd25sb2FkZWQgZmlsZSBzaXplIHdvdWxkIGJlIGRpZmZlcmVudCB0aGFuCisgIC8vIHRoZSBmaW5hbCBmaWxlIHNpemUgb24gZGlzay4gQ2xpZW50IGNvdWxkIHVzZQorICAvLyB0aGlzIGZpZWxkIHRvIHRyYWNrIHRoZSBkb3dubG9hZGVkIGZpbGUgc2l6ZSBhbmQgY2FsY3VsYXRlIHRoZSBkb3dubG9hZAorICAvLyBwcm9ncmVzcyBwZXJjZW50YWdlLiBUaGlzIGZpZWxkIGlzIG5vdCB1c2VkIGJ5IE1ERCBjdXJyZW50bHkuCisgIG9wdGlvbmFsIGludDMyIGRvd25sb2FkZWRfZmlsZV9ieXRlX3NpemUgPSAxNjsKKworICAvLyBUaGVzZSB0cmFuc2Zvcm1zIGFyZSBldmFsdWF0ZWQgYnkgdGhlIGNhbGxlciBvbi10aGUtZmx5IHdoZW4gcmVhZGluZyB0aGUKKyAgLy8gZGF0YSB3aXRoIE1vYlN0b3JlLiBBbnkgdHJhbnNmb3JtcyBpbnN0YWxsZWQgaW4gdGhlIGNhbGxlcidzIE1vYlN0b3JlCisgIC8vIGluc3RhbmNlIGlzIGF2YWlsYWJsZS4KKyAgLy8gVmFsaWQgb24gQW5kcm9pZC4gaU9TIHN1cHBvcnQgaXMgdHJhY2tlZCBieSBiLzExODc1OTI1NC4KKyAgb3B0aW9uYWwgbW9ic3RvcmUucHJvdG8uVHJhbnNmb3JtcyByZWFkX3RyYW5zZm9ybXMgPSAxMjsKKworICAvLyBMaXN0IG9mIGRlbHRhIGZpbGVzIHRoYXQgY2FuIGJlIGVuY29kZWQgYW5kIGRlY29kZWQgd2l0aCBiYXNlIGZpbGVzLgorICAvLyBJZiB0aGUgZGV2aWNlIGhhcyBhbnkgYmFzZSBmaWxlLCB0aGUgZGVsdGEgZmlsZSB3aGljaCBpcyBtdWNoCisgIC8vIHNtYWxsZXIgd2lsbCBiZSBkb3dubG9hZGVkIGluc3RlYWQgb2YgdGhlIGZ1bGwgZmlsZS4KKyAgLy8gRm9yIG1vc3QgY2xpZW50cywgb25seSBvbmUgZGVsdGEgZmlsZSBzaG91bGQgYmUgZW5vdWdoLiBJZiBzcGVjaWZ5aW5nCisgIC8vIG11bHRpcGxlIGRlbHRhIGZpbGVzLCB0aGV5IHNob3VsZCBiZSBpbiBhIHNlcXVlbmNlIGZyb20gdGhlIG1vc3QgcmVjZW50CisgIC8vIGJhc2UgZmlsZSB0byB0aGUgb2xkZXN0LgorICAvLyBUaGlzIGlzIGN1cnJlbnRseSBvbmx5IHN1cHBvcnRlZCBvbiBBbmRyb2lkLgorICByZXBlYXRlZCBEZWx0YUZpbGUgZGVsdGFfZmlsZSA9IDEzOworCisgIGVudW0gQW5kcm9pZFNoYXJpbmdUeXBlIHsKKyAgICAvLyBUaGUgZGF0YUZpbGUgaXNuJ3QgYXZhaWxhYmxlIGZvciBzaGFyaW5nLgorICAgIFVOU1VQUE9SVEVEID0gMDsKKworICAgIC8vIElmIHNoYXJpbmcgd2l0aCB0aGUgQW5kcm9pZCBCbG9iIFNoYXJpbmcgU2VydmljZSBpc24ndCBhdmFpbGFibGUsIGZhbGwKKyAgICAvLyBiYWNrIHRvIG5vcm1hbCBiZWhhdmlvciwgaS5lLiBkb3dubG9hZCBsb2NhbGx5LgorICAgIEFORFJPSURfQkxPQl9XSEVOX0FWQUlMQUJMRSA9IDE7CisgIH0KKworICAvLyBEZWZpbmVzIHdoZXRoZXIgdGhlIGZpbGUgc2hvdWxkIGJlIHNoYXJlZCBhbmQgaG93LgorICAvLyBOT1RFOiBjdXJyZW50bHkgdGhpcyBmaWVsZCBpcyBvbmx5IHVzZWQgYnkgYU1ERCBhbmQgaGFzIG5vIGVmZmVjdCBvbiBpTURELgorICBvcHRpb25hbCBBbmRyb2lkU2hhcmluZ1R5cGUgYW5kcm9pZF9zaGFyaW5nX3R5cGUgPSAxNzsKKworICAvLyBFbnVtIGZvciBhbmRyb2lkIHNoYXJpbmcgY2hlY2tzdW0gdHlwZXMuCisgIGVudW0gQW5kcm9pZFNoYXJpbmdDaGVja3N1bVR5cGUgeworICAgIE5PVF9TRVQgPSAwOworCisgICAgLy8gSWYgdGhlIGZpbGUgZ3JvdXAgc2hvdWxkIGJlIHNoYXJlZCB0aHJvdWdoIHRoZSBBbmRyb2lkIEJsb2IgU2hhcmluZworICAgIC8vIFNlcnZpY2UsIHRoZSBjaGVja3N1bSB0eXBlIG11c3QgYmUgc2V0IHRvIFNIQTI1Ni4KKyAgICBTSEEyXzI1NiA9IDE7CisgIH0KKworICBvcHRpb25hbCBBbmRyb2lkU2hhcmluZ0NoZWNrc3VtVHlwZSBhbmRyb2lkX3NoYXJpbmdfY2hlY2tzdW1fdHlwZSA9IDE4OworCisgIC8vIENoZWNrc3VtIHVzZWQgdG8gYWNjZXNzIGZpbGVzIHRocm91Z2ggdGhlIEFuZHJvaWQgQmxvYiBTaGFyaW5nIFNlcnZpY2UuCisgIG9wdGlvbmFsIHN0cmluZyBhbmRyb2lkX3NoYXJpbmdfY2hlY2tzdW0gPSAxOTsKKworICAvLyBSZWxhdGl2ZSBmaWxlIHBhdGggYW5kIGZpbGUgbmFtZSB0byBiZSBwcmVzZXJ2ZWQgd2l0aGluIHRoZSBwYXJlbnQKKyAgLy8gZGlyZWN0b3J5IHdoZW4gY3JlYXRpbmcgc3ltbGlua3MgZm9yIHRoZSBmaWxlIGdyb3VwcyB0aGF0IGhhdmUKKyAgLy8gcHJlc2VydmVfZmlsZW5hbWVzX2FuZF9pc29sYXRlX2ZpbGVzIHNldCB0byB0cnVlLgorICAvLyBUaGlzIGZpbGVuYW1lIHNob3VsZCBOT1Qgc3RhcnQgb3IgZW5kIHdpdGggYSAnLycsIGFuZCBpdCBjYW4gbm90IGNvbnRhaW4KKyAgLy8gdGhlIHN1YnN0cmluZyAnLi4nLgorICAvLyBXb3JraW5nIGV4YW1wbGU6ICJzdWJEaXIvRmlsZU5hbWUudHh0Ii4KKyAgb3B0aW9uYWwgc3RyaW5nIHJlbGF0aXZlX2ZpbGVfcGF0aCA9IDIwOworCisgIC8vIEN1c3RvbSBtZXRhZGF0YSBhdHRhY2hlZCB0byB0aGUgZmlsZS4KKyAgLy8KKyAgLy8gVGhpcyBhbGxvd3MgY2xpZW50cyB0byBpbmNsdWRlIHNwZWNpZmljIG1ldGFkYXRhIGFib3V0IHRoZSBmaWxlIGZvciB0aGVpcgorICAvLyBvd24gcHJvY2Vzc2luZyBwdXJwb3Nlcy4gVGhlIG1ldGFkYXRhIHdpbGwgYmUgc3RvcmVkIHdpdGggdGhlIGZpbGUgYW5kCisgIC8vIGFjY2Vzc2libGUgd2hlbiB0aGUgZmlsZSdzIGZpbGUgZ3JvdXAgaXMgcmV0cmlldmVkLgorICAvLworICAvLyBUaGlzIHByb3BlcnR5IHNob3VsZCBvbmx5IGJlIHVzZWQgaWYgYWJzb2x1dGVseSBuZWNlc3NhcnkuIFBsZWFzZSBjb25zdWx0CisgIC8vIHdpdGggPGludGVybmFsPkAgaWYgeW91IGhhdmUgcXVlc3Rpb25zIGFib3V0IHRoaXMgcHJvcGVydHkgb3IgYSBwb3RlbnRpYWwKKyAgLy8gdXNlLWNhc2UuCisgIG9wdGlvbmFsIGdvb2dsZS5wcm90b2J1Zi5BbnkgY3VzdG9tX21ldGFkYXRhID0gMjE7CisKKyAgcmVzZXJ2ZWQgMSwgMywgNiwgOCwgOTsKK30KKy8vIExJTlQuVGhlbkNoYW5nZSgKKy8vICAgICA8aW50ZXJuYWw+LAorLy8gICAgIDxpbnRlcm5hbD4pCisKKy8vIE1pcnJvcnMgbWRpLmRvd25sb2FkLkRlbHRhRmlsZQorLy8KKy8vIEEgZGVsdGEgZmlsZSByZXByZXNlbnRzIGFsbCB0aGUgbWV0YWRhdGEgdG8gZG93bmxvYWQgZm9yIGEgZGlmZiBmaWxlIGVuY29kZWQKKy8vIGJhc2VkIG9uIGEgYmFzZSBmaWxlCisvLyBMSU5ULklmQ2hhbmdlKGRlbHRhX2ZpbGUpCittZXNzYWdlIERlbHRhRmlsZSB7CisgIC8vIFRoZXNlIGZpZWxkcyBhbGwgbWlycm9yIHRoZSBzaW1pbGFybHktbmFtZWQgZmllbGRzIGluIERhdGFGaWxlLgorICBvcHRpb25hbCBzdHJpbmcgdXJsX3RvX2Rvd25sb2FkID0gMTsKKyAgb3B0aW9uYWwgaW50MzIgYnl0ZV9zaXplID0gMjsKKyAgb3B0aW9uYWwgc3RyaW5nIGNoZWNrc3VtID0gMzsKKworICAvLyBFbnVtIG9mIGFsbCBkaWZmIGRlY29kZXJzIHN1cHBvcnRlZAorICBlbnVtIERpZmZEZWNvZGVyIHsKKyAgICAvLyBEZWZhdWx0IHRvIGhhdmUgbm8gZGlmZiBkZWNvZGVyIHNwZWNpZmllZCwgd2lsbCB0aHJvd24gdW5zdXBwb3J0ZWQKKyAgICAvLyBleGNlcHRpb24KKyAgICBVTlNQRUNJRklFRCA9IDA7CisKKyAgICAvLyBWY0RJRkYgZGVjb2RlcgorICAgIC8vIEdlbmVyaWMgRGlmZmVyZW5jaW5nIGFuZCBDb21wcmVzc2lvbiBEYXRhIEZvcm1hdAorICAgIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uLCBwbGVhc2UgcmVmZXIgdG8gcmZjMzI4NAorICAgIC8vIFRoZSBWY0RpZmYgZGVjb2RlciBmb3IgR01TIHNlcnZpY2U6CisgICAgLy8gPGludGVybmFsPgorICAgIFZDX0RJRkYgPSAxOworICB9CisgIC8vIFRoZSBkaWZmIGRlY29kZXIgdXNlZCB0byBnZW5lcmF0ZSBmdWxsIGZpbGUgd2l0aCBkZWx0YSBhbmQgYmFzZSBmaWxlLgorICAvLyBGb3IgTUREIGFzIGEgR01TIHNlcnZpY2UsIGEgVmNEaWZmIGRlY29kZXIgd2lsbCBiZSByZWdpc3RlcmVkIGFuZCBpbmplY3RlZAorICAvLyBpbiBieSBkZWZhdWx0LiBVc2luZyBNREQgYXMgYSBsaWJyYXJ5LCBjbGllbnRzIG5lZWQgdG8gcmVnaXN0ZXIgYW5kIGluamVjdAorICAvLyBpbiBhIFZjRGlmZiBkZWNvZGVyLCBvdGhlcndpc2UsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KKyAgb3B0aW9uYWwgRGlmZkRlY29kZXIgZGlmZl9kZWNvZGVyID0gNTsKKworICAvLyBUaGUgYmFzZSBmaWxlIHJlcHJlc2VudHMgdG8gYSBmdWxsIGZpbGUgb24gZGV2aWNlLiBJdCBzaG91bGQgY29udGFpbiB0aGUKKyAgLy8gYmFyZSBtaW5pbXVtIGZpZWxkcyBvZiBhIERhdGFGaWxlIHRvIGlkZW50aWZ5IGEgRGF0YUZpbGUgb24gZGV2aWNlLgorICBvcHRpb25hbCBCYXNlRmlsZSBiYXNlX2ZpbGUgPSA2OworCisgIHJlc2VydmVkIDQ7Cit9CisvLyBMSU5ULlRoZW5DaGFuZ2UoCisvLyAgICAgPGludGVybmFsPiwKKy8vICAgICA8aW50ZXJuYWw+KQorCisvLyBNaXJyb3JzIG1kaS5kb3dubG9hZC5CYXNlRmlsZQorbWVzc2FnZSBCYXNlRmlsZSB7CisgIC8vIFNIQTEgY2hlY2tzdW0gb2YgdGhlIGJhc2UgZmlsZSB0byBpZGVudGlmeSBhIGZpbGUgb24gZGV2aWNlLiBJdCBzaG91bGQKKyAgLy8gbWF0Y2ggdGhlIGNoZWNrc3VtIGZpZWxkIG9mIHRoZSBiYXNlIGZpbGUgdXNlZCB0byBnZW5lcmF0ZSB0aGUgZGVsdGEgZmlsZS4KKyAgb3B0aW9uYWwgc3RyaW5nIGNoZWNrc3VtID0gMTsKK30KKworLy8gTWlycm9ycyBtZGkuZG93bmxvYWQuRG93bmxvYWRDb25kaXRpb25zCisvLworLy8gTmV4dCBpZDogNQorbWVzc2FnZSBEb3dubG9hZENvbmRpdGlvbnMgeworICAvLyBUT0RPKGIvMTQzNTQ4NzUzKTogVGhlIGZpcnN0IHZhbHVlIGluIGFuIGVudW0gbXVzdCBoYXZlIGEgc3BlY2lmaWMgcHJlZml4LgorICBlbnVtIERldmljZVN0b3JhZ2VQb2xpY3kgeworICAgIC8vIE1ERCB3aWxsIGJsb2NrIGRvd25sb2FkIG9mIGZpbGVzIGluIGFuZHJvaWQgbG93IHN0b3JhZ2UuIEN1cnJlbnRseSBNREQKKyAgICAvLyBkb2Vzbid0IGRlbGV0ZSB0aGUgZmlsZXMgaW4gY2FzZSB0aGUgZGV2aWNlIHJlYWNoZXMgbG93IHN0b3JhZ2UKKyAgICAvLyBhZnRlciB0aGUgZmlsZSBoYXMgYmVlbiBkb3dubG9hZGVkLgorICAgIEJMT0NLX0RPV05MT0FEX0lOX0xPV19TVE9SQUdFID0gMDsKKworICAgIC8vIEJsb2NrIGRvd25sb2FkIG9mIGZpbGVzIG9ubHkgdW5kZXIgYSBsb3dlciB0aHJlc2hvbGQgZGVmaW5lZCBoZXJlCisgICAgLy8gPGludGVybmFsPgorICAgIEJMT0NLX0RPV05MT0FEX0xPV0VSX1RIUkVTSE9MRCA9IDE7CisKKyAgICAvLyBTZXQgdGhlIHN0b3JhZ2UgdGhyZXNob2xkIHRvIGFuIGV4dHJlbWVseSBsb3cgdmFsdWUgd2hlbiBkb3dubG9hZGluZy4KKyAgICAvLyBJTVBPUlRBTlQ6IGlmIHRoZSBkb3dubG9hZCBtYWtlIHRoZSBkZXZpY2UgcnVucyBvdXQgb2YgZGlzaywgdGhpcyBjb3VsZAorICAgIC8vIHJlbmRlciB0aGUgZGV2aWNlIHVudXNhYmxlLgorICAgIC8vIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBmb3IgY3JpdGljYWwgdXNlIGNhc2VzIHN1Y2ggYXMgcHJpdmFjeQorICAgIC8vIHZpb2xhdGlvbnMuIEVtZXJnZW5jeSBmaXggc2hvdWxkIG5vdCBiZWxvbmcgdG8gdGhpcyBjYXRlZ29yeS4gUGxlYXNlCisgICAgLy8gdGFsa3MgdG8gPGludGVybmFsPkAgd2hlbiB5b3Ugd2FudCB0byB1c2UgdGhpcyBvcHRpb24uCisgICAgRVhUUkVNRUxZX0xPV19USFJFU0hPTEQgPSAyOworICB9CisKKyAgLy8gU3BlY2lmeSB0aGUgZGV2aWNlIHN0b3JhZ2UgdW5kZXIgd2hpY2ggdGhlIGZpbGVzIHNob3VsZCBiZSBkb3dubG9hZGVkLgorICAvLyBCeSBkZWZhdWx0LCB0aGUgZmlsZXMgd2lsbCBvbmx5IGJlIGRvd25sb2FkZWQgaWYgdGhlIGRldmljZSBpcyBub3QgaW4KKyAgLy8gbG93IHN0b3JhZ2UuCisgIG9wdGlvbmFsIERldmljZVN0b3JhZ2VQb2xpY3kgZGV2aWNlX3N0b3JhZ2VfcG9saWN5ID0gMTsKKworICAvLyBUT0RPKGIvMTQzNTQ4NzUzKTogVGhlIGZpcnN0IHZhbHVlIGluIGFuIGVudW0gbXVzdCBoYXZlIGEgc3BlY2lmaWMgcHJlZml4LgorICBlbnVtIERldmljZU5ldHdvcmtQb2xpY3kgeworICAgIC8vIE9ubHkgZG93bmxvYWQgZmlsZXMgb24gd2lmaS4KKyAgICBET1dOTE9BRF9PTkxZX09OX1dJRkkgPSAwOworCisgICAgLy8gQWxsb3cgZG93bmxvYWQgb24gYW55IG5ldHdvcmsgaW5jbHVkaW5nIHdpZmkgYW5kIGNlbGx1bGFyLgorICAgIERPV05MT0FEX09OX0FOWV9ORVRXT1JLID0gMTsKKworICAgIC8vIEFsbG93IGRvd25sb2FkaW5nIG9ubHkgb24gd2lmaSBmaXJzdCwgdGhlbiBhZnRlciBhIGNvbmZpZ3VyYWJsZSB0aW1lCisgICAgLy8gcGVyaW9kIHNldCBpbiB0aGUgZmllbGQgZG93bmxvYWRfZmlyc3Rfb25fd2lmaV9wZXJpb2Rfc2VjcyBiZWxvdywKKyAgICAvLyBhbGxvdyBkb3dubG9hZGluZyBvbiBhbnkgbmV0d29yayBpbmNsdWRpbmcgd2lmaSBhbmQgY2VsbHVsYXIuCisgICAgRE9XTkxPQURfRklSU1RfT05fV0lGSV9USEVOX09OX0FOWV9ORVRXT1JLID0gMjsKKyAgfQorCisgIC8vIFNwZWNpZnkgdGhlIGRldmljZSBuZXR3b3JrIHVuZGVyIHdoaWNoIHRoZSBmaWxlcyBzaG91bGQgYmUgZG93bmxvYWRlZC4KKyAgLy8gQnkgZGVmYXVsdCwgdGhlIGZpbGVzIHdpbGwgb25seSBiZSBkb3dubG9hZGVkIG9uIHdpZmkuCisgIC8vCisgIC8vIElmIHlvdXIgZmVhdHVyZSB0YXJnZXRzIGJlbG93IHYyMCBhbmQgd2FudCB0byBkb3dubG9hZCBvbiBjZWxsdWxhciBpbgorICAvLyB0aGVzZSB2ZXJzaW9ucyBvZiBnbXMsIGFsc28gc2V0IGFsbG93X2Rvd2xvYWRfd2l0aG91dF93aWZpID0gdHJ1ZTsKKyAgb3B0aW9uYWwgRGV2aWNlTmV0d29ya1BvbGljeSBkZXZpY2VfbmV0d29ya19wb2xpY3kgPSAyOworCisgIC8vIFRoaXMgZmllbGQgd2lsbCBvbmx5IGJlIHVzZWQgd2hlbiB0aGUKKyAgLy8gRGV2aWNlTmV0d29ya1BvbGljeSA9IERPV05MT0FEX0ZJUlNUX09OX1dJRklfVEhFTl9PTl9BTllfTkVUV09SSworICAvLyBNREQgd2lsbCBkb3dubG9hZCB0aGUgZmlsZSBvbmx5IG9uIHdpZmkgZm9yIHRoaXMgcGVyaW9kIG9mIHRpbWUuIElmIHRoZQorICAvLyBkb3dubG9hZCB3YXMgbm90IGZpbmlzaGVkLCBNREQgd2lsbCBkb3dubG9hZCBvbiBhbnkgbmV0d29yayBpbmNsdWRpbmcKKyAgLy8gd2lmaSBhbmQgY2VsbHVsYXIuCisgIC8vIEV4OiA2MDQ4MDAgIC8vIDcgRGF5cworICBvcHRpb25hbCBpbnQ2NCBkb3dubG9hZF9maXJzdF9vbl93aWZpX3BlcmlvZF9zZWNzID0gNDsKKworICAvLyBUT0RPKGIvMTQzNTQ4NzUzKTogVGhlIGZpcnN0IHZhbHVlIGluIGFuIGVudW0gbXVzdCBoYXZlIGEgc3BlY2lmaWMgcHJlZml4LgorICBlbnVtIEFjdGl2YXRpbmdDb25kaXRpb24geworICAgIC8vIFRoZSBkb3dubG9hZCBpcyBhY3RpdmF0ZWQgYXMgc29vbiB0aGUgc2VydmVyIHNpZGUgY29uZmlnIGlzIHJlY2VpdmVkIGFuZAorICAgIC8vIHRoZSBzZXJ2ZXIgY29uZmlndXJlZCBkb3dubG9hZCBjb25kaXRpb25zIGFyZSBzYXRpc2ZpZWQuCisgICAgQUxXQVlTX0FDVElWQVRFRCA9IDA7CisKKyAgICAvLyBUaGUgZG93bmxvYWQgaXMgYWN0aXZhdGVkIHdoZW4gYm90aCBzZXJ2ZXIgc2lkZSBhY3RpdmF0aW9uIGNvbmRpdGlvbnMKKyAgICAvLyBhcmUgc2F0aXNmaWVkIGFuZCB0aGUgY2xpZW50IGhhcyBhY3RpdmF0ZWQgdGhlIGRvd25sb2FkIG9uIGRldmljZS4KKyAgICAvLworICAgIC8vIENsaWVudHMgY2FuIGFjdGl2YXRlIHRoaXMgZ3JvdXAgdXNpbmcgdGhlIGFjdGl2YXRlRmlsZUdyb3VwIEFQSS4KKyAgICAvLyA8aW50ZXJuYWw+CisgICAgREVWSUNFX0FDVElWQVRFRCA9IDE7CisgIH0KKworICAvLyBTcGVjaWZ5IGhvdyB0aGUgZG93bmxvYWQgaXMgYWN0aXZhdGVkLiBCeSBkZWZhdWx0LCB0aGUgZG93bmxvYWQgaXMKKyAgLy8gYWN0aXZhdGVkIGFzIHNvb24gYXMgc2VydmVyIGNvbmZpZ3VyZWQgYWN0aXZhdGluZyBjb25kaXRpb25zIGFyZSBzYXRpc2ZpZWQuCisgIG9wdGlvbmFsIEFjdGl2YXRpbmdDb25kaXRpb24gYWN0aXZhdGluZ19jb25kaXRpb24gPSAzOworfQorCisvLyBUaGlzIHByb3RvIGNvbnRhaW5zIGV4dHJhIGluZm9ybWF0aW9uIGFib3V0IGEgZmlsZSBncm91cCBmb3IgYm9va2tlZXBpbmcuCisvLyBOZXh0IHRhZzogNgorbWVzc2FnZSBEYXRhRmlsZUdyb3VwQm9va2tlZXBpbmcgeworICAvLyBUaGUgZXBvY2ggdGltZSAoc2Vjb25kcyBzaW5jZSAxLzEvMTk3MCkgYXQgd2hpY2ggdGhpcyBzdGFsZSBmaWxlIGdyb3VwIHdpbGwKKyAgLy8gYmUgZGVsZXRlZC4KKyAgb3B0aW9uYWwgaW50NjQgc3RhbGVfZXhwaXJhdGlvbl9kYXRlID0gMTsKKworICAvLyBUaGUgdGltZXN0YW1wIChlcG9jaCB0aW1lLCBtaWxsaXNlY29uZHMgc2luY2UgMS8xLzE5NzApIHRoYXQgdGhlIGZpbGUgZ3JvdXAKKyAgLy8gd2FzIGZpcnN0IHJlY2VpdmVkLgorICAvLworICAvLyBJZiB0aGlzIGlzIGFuIHVwZGF0ZSBvbiBhbiBleGlzdGluZyBncm91cCwgdGhlbiB0aGUgdGltZXN0YW1wIGZyb20gdGhlIG9sZAorICAvLyBncm91cCBpcyB1c2VkIGlmIG5vIGZpbGVzIHdlcmUgdXBkYXRlZC4KKyAgb3B0aW9uYWwgaW50NjQgZ3JvdXBfbmV3X2ZpbGVzX3JlY2VpdmVkX3RpbWVzdGFtcCA9IDI7CisKKyAgLy8gVGhlIHRpbWVzdGFtcCAoZXBvY2ggdGltZSwgbWlsbGlzZWNvbmRzIHNpbmNlIDEvMS8xOTcwKSBhdCB3aGljaCB0aGUgZ3JvdXAKKyAgLy8gd2FzIGZpcnN0IG1hcmtlZCBhcyBkb3dubG9hZGVkLgorICBvcHRpb25hbCBpbnQ2NCBncm91cF9kb3dubG9hZGVkX3RpbWVzdGFtcF9pbl9taWxsaXMgPSAzOworCisgIC8vIFRoZSB0aW1lc3RhbXAgKGVwb2NoIHRpbWUsIG1pbGxpc2Vjb25kcyBzaW5jZSAxLzEvMTk3MCkgdGhhdCBNREQgc3RhcnRzCisgIC8vIGRvd25sb2FkaW5nIHRoZSBmaWxlIGdyb3VwIGZvciB0aGUgZmlyc3QgdGltZS4KKyAgb3B0aW9uYWwgaW50NjQgZ3JvdXBfZG93bmxvYWRfc3RhcnRlZF90aW1lc3RhbXBfaW5fbWlsbGlzID0gNDsKKworICAvLyBUaGUgdG90YWwgY291bnQgb2YgZG93bmxvYWQgcGVyaW9kaWMgdGFza3MgbmVlZGVkIHRvIGZ1bGx5IGRvd25sb2FkIHRoZQorICAvLyBmaWxlIGdyb3VwLgorICBvcHRpb25hbCBpbnQzMiBkb3dubG9hZF9zdGFydGVkX2NvdW50ID0gNTsKK30KKworLy8gS2V5IHVzZWQgYnkgbWRkIHRvIHVuaXF1ZWx5IGlkZW50aWZ5IGEgY2xpZW50IGdyb3VwLgorbWVzc2FnZSBHcm91cEtleSB7CisgIC8vIFRoZSBuYW1lIG9mIHRoZSBncm91cC4KKyAgb3B0aW9uYWwgc3RyaW5nIGdyb3VwX25hbWUgPSAxOworCisgIC8vIFRoZSBwYWNrYWdlIG5hbWUgb2YgdGhlIGdyb3VwIG93bmVyLiBBIG51bGwgdmFsdWUgb3IgZW1wdHkgdmFsdWUgbWVhbnMKKyAgLy8gdGhhdCB0aGUgZ3JvdXAgaXMgbm90IGFzc29jaWF0ZWQgd2l0aCBhbnkgcGFja2FnZS4KKyAgb3B0aW9uYWwgc3RyaW5nIG93bmVyX3BhY2thZ2UgPSAyOworCisgIC8vIFRoZSBhY2NvdW50IGFzc29jaWF0ZWQgdG8gdGhlIGZpbGUgZ3JvdXAuCisgIG9wdGlvbmFsIHN0cmluZyBhY2NvdW50ID0gNTsKKworICAvLyBXaGV0aGVyIG9yIG5vdCBhbGwgZmlsZXMgaW4gYSBmaWxlR3JvdXAgaGF2ZSBiZWVuIGRvd25sb2FkZWQuCisgIG9wdGlvbmFsIGJvb2wgZG93bmxvYWRlZCA9IDQ7CisKKyAgLy8gVGhlIHZhcmlhbnQgaWQgb2YgdGhlIGdyb3VwLiBBIG51bGwgb3IgZW1wdHkgdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIGdyb3VwCisgIC8vIGRvZXMgbm90IGhhdmUgYW4gYXNzb2NpYXRlZCB2YXJpYW50LgorICBvcHRpb25hbCBzdHJpbmcgdmFyaWFudF9pZCA9IDY7CisKKyAgcmVzZXJ2ZWQgMzsKK30KKworLy8gR3JvdXAgS2V5IHByb3BlcnRpZXMgdGhhdCBhcHBseSB0byBhbGwgZ3JvdXBzIHdpdGggdGhhdCBrZXkuCittZXNzYWdlIEdyb3VwS2V5UHJvcGVydGllcyB7CisgIC8vIFdoZXRoZXIgdGhpcyBncm91cCBrZXkgaGFzIGJlZW4gYWN0aXZhdGVkIG9uIHRoZSBkZXZpY2UuCisgIG9wdGlvbmFsIGJvb2wgYWN0aXZhdGVkX29uX2RldmljZSA9IDE7Cit9CisKKy8vIFNoYXJlZEZpbGUgaXMgYSBpbnRlcm5hbCBkYXRhIHN0cnVjdHVyZSBvZiB0aGUgU2hhcmVkRmlsZU1hbmFnZXIuCittZXNzYWdlIFNoYXJlZEZpbGUgeworICBvcHRpb25hbCBzdHJpbmcgZmlsZV9uYW1lID0gNDsKKyAgb3B0aW9uYWwgRmlsZVN0YXR1cyBmaWxlX3N0YXR1cyA9IDU7CisKKyAgLy8gVGhpcyBmaWVsZCB3aWxsIGJlIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIGEgZmlsZSBjYW4gYmUgcmV0cmlldmVkIGZyb20gdGhlCisgIC8vIEFuZHJvaWQgQmxvYiBTaGFyaW5nIFNlcnZpY2UuCisgIG9wdGlvbmFsIGJvb2wgYW5kcm9pZF9zaGFyZWQgPSA4OworCisgIC8vIFRoZSBtYXhpbXVtIGV4cGlyYXRpb24gZGF0ZSBmb3VuZCBmb3IgYSBkb3dubG9hZGVkIGRhdGEgZmlsZS4gSWYKKyAgLy8ge0Bjb2RlIGFuZHJvaWRfc2hhcmVkfSBpcyBzZXQgdG8gdHJ1ZSwgdGhpcyBmaWVsZCBzdG9yZXMgdGhlIGN1cnJlbnQgbGVhc2UKKyAgLy8gZXhwaXJhdGlvbiBkYXRlLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyAwLgorICAvLyBTZWUgPGludGVybmFsPiBmb3IgbW9yZSBkZXRhaWxzLgorICBvcHRpb25hbCBpbnQ2NCBtYXhfZXhwaXJhdGlvbl9kYXRlX3NlY3MgPSA5OworCisgIC8vIENoZWNrc3VtIHVzZWQgdG8gYWNjZXNzIGZpbGVzIHRocm91Z2ggdGhlIEFuZHJvaWQgQmxvYiBTaGFyaW5nIFNlcnZpY2UuCisgIG9wdGlvbmFsIHN0cmluZyBhbmRyb2lkX3NoYXJpbmdfY2hlY2tzdW0gPSAxMDsKKworICAvLyBJZiB0aGUgZmlsZSBpcyBkb3dubG9hZGVkIHN1Y2Nlc3NmdWxseSBidXQgZmFpbHMgY2hlY2tzdW0gbWF0Y2hpbmcsIHdlIHdpbGwKKyAgLy8gYXR0ZW1wdCB0byBkZWxldGUgdGhlIGZpbGUgc28gaXQgY2FuIGJlIHJlZG93bmxvYWRlZCBmcm9tIHNjcmF0Y2guIFRvCisgIC8vIHByZXZlbnQgdW5uZWNlc3NhcnkgbmV0d29yayBiYW5kd2lkdGgsIHdlIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiB0aGVzZQorICAvLyBhdHRlbXB0cyBpbiB0aGlzIGZpZWxkIGFuZCBzdG9wIGFmdGVyIGEgY2VydGFpbiBudW1iZXIuIChjb25maWd1cmFibGUgYnkgYQorICAvLyBkb3dubG9hZCBmbGFnKS4KKyAgb3B0aW9uYWwgaW50MzIgY2hlY2tzdW1fbWlzbWF0Y2hfcmV0cnlfZG93bmxvYWRfY291bnQgPSAxMTsKKworICByZXNlcnZlZCAxLCAyLCAzLCA2LCA3OworfQorCisvLyBNZXRhZGF0YSB1c2VkIGJ5CisvLyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1kaS5kb3dubG9hZC5Nb2JpbGVEYXRhRG93bmxvYWRNYW5hZ2VyCittZXNzYWdlIE1vYmlsZURhdGFEb3dubG9hZE1hbmFnZXJNZXRhZGF0YSB7CisgIG9wdGlvbmFsIGJvb2wgbWRkX21pZ3JhdGVkX3RvX29mZnJvYWQgPSAxOworICBvcHRpb25hbCBpbnQzMiByZXNldF90cmlnZ2VyID0gMjsKK30KKworLy8gTWV0YWRhdGEgdXNlZCBieQorLy8gY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tZGkuZG93bmxvYWQuU2hhcmVkRmlsZU1hbmFnZXIKK21lc3NhZ2UgU2hhcmVkRmlsZU1hbmFnZXJNZXRhZGF0YSB7CisgIG9wdGlvbmFsIGJvb2wgbWlncmF0ZWRfdG9fbmV3X2ZpbGVfa2V5ID0gMTsKKyAgb3B0aW9uYWwgaW50NjQgbmV4dF9maWxlX25hbWUgPSAyOworfQorCisvLyBDb2xsZWN0cyBhbGwgZGF0YSB1c2VkIGJ5CisvLyBjb20uZ29vZ2xlLmFuZHJvaWQubGlicmFyaWVzLm1kaS5kb3dubG9hZC5pbnRlcm5hbC5NaWdyYXRpb25zCittZXNzYWdlIE1pZ3JhdGlvbnNTdG9yZSB7CisgIGVudW0gRmlsZUtleVZlcnNpb24geworICAgIE5FV19GSUxFX0tFWSA9IDA7CisgICAgQUREX0RPV05MT0FEX1RSQU5TRk9STSA9IDE7CisgICAgVVNFX0NIRUNLU1VNX09OTFkgPSAyOworICB9CisgIG9wdGlvbmFsIGJvb2wgaXNfbWlncmF0ZWRfdG9fbmV3X2ZpbGVfa2V5ID0gMTsKKyAgb3B0aW9uYWwgRmlsZUtleVZlcnNpb24gY3VycmVudF92ZXJzaW9uID0gMjsKK30KKworLy8gQ29sbGVjdHMgYWxsIGRhdGEgdXNlZCBieQorLy8gY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tZGkuZG93bmxvYWQuaW50ZXJuYWwuRmlsZUdyb3Vwc01ldGFkYXRhCittZXNzYWdlIEZpbGVHcm91cHNNZXRhZGF0YVN0b3JlIHsKKyAgLy8gS2V5IG11c3QgYmUgYSBzZXJpYWxpemVkIEdyb3VwS2V5LgorICBtYXA8c3RyaW5nLCBEYXRhRmlsZUdyb3VwSW50ZXJuYWw+IGRhdGFfZmlsZV9ncm91cHMgPSAxOworICAvLyBLZXkgbXVzdCBiZSBhIHNlcmlhbGl6ZWQgR3JvdXBLZXkuCisgIG1hcDxzdHJpbmcsIEdyb3VwS2V5UHJvcGVydGllcz4gZ3JvdXBfa2V5X3Byb3BlcnRpZXMgPSAyOworICByZXBlYXRlZCBEYXRhRmlsZUdyb3VwSW50ZXJuYWwgc3RhbGVfZ3JvdXBzID0gMzsKK30KKworLy8gQ29sbGVjdHMgYWxsIGRhdGEgdXNlZCBieQorLy8gY29tLmdvb2dsZS5hbmRyb2lkLmxpYnJhcmllcy5tZGkuZG93bmxvYWQuaW50ZXJuYWwuU2hhcmVkRmlsZXNNZXRhZGF0YQorbWVzc2FnZSBTaGFyZWRGaWxlc01ldGFkYXRhU3RvcmUgeworICAvLyBUaGUga2V5IG11c3QgYmUgYSBzZXJpYWxpemVkIE5ld0ZpbGVLZXkuCisgIG1hcDxzdHJpbmcsIFNoYXJlZEZpbGU+IHNoYXJlZF9maWxlcyA9IDE7Cit9CisKK2VudW0gRmlsZVN0YXR1cyB7CisgIC8vIFRoZSBmaWxlIGhhcyBuZXZlciBiZWVuIHNlZW4gYmVmb3JlLgorICBOT05FID0gMDsKKyAgLy8gVGhlIGZpbGUgaGFzIGJlZW4gc3Vic2NyaWJlZCB0bywgYnV0IGRvd25sb2FkIGhhcyBub3QgYmVlbiBhdHRlbXB0ZWQuCisgIFNVQlNDUklCRUQgPSAxOworICAvLyBUaGUgZmlsZSBkb3dubG9hZCBpcyBjdXJyZW50bHkgaW4gcHJvZ3Jlc3MuCisgIERPV05MT0FEX0lOX1BST0dSRVNTID0gMjsKKyAgLy8gRG93bmxvYWRpbmcgdGhlIGZpbGUgZmFpbGVkLgorICBET1dOTE9BRF9GQUlMRUQgPSAzOworICAvLyBUaGUgZmlsZSB3YXMgZG93bmxvYWRlZCBjb21wbGV0ZWx5LCBhbmQgaXMgYXZhaWxhYmxlIGZvciB1c2UuCisgIERPV05MT0FEX0NPTVBMRVRFID0gNDsKKyAgLy8gVGhlIGZpbGUgd2FzIGNvcnJ1cHRlZCBvciBsb3N0IGFmdGVyIGJlaW5nIHN1Y2Nlc3NmdWxseSBkb3dubG9hZGVkLgorICBDT1JSVVBURUQgPSA2OworICAvLyBTdGF0dXMgcmV0dXJuZWQgd2hlbiB0aGVpciBpcyBhbiBlcnJvciB3aGlsZSBnZXR0aW5nIHRoZSBmaWxlIHN0YXR1cy4KKyAgLy8gVGhpcyBpcyBuZXZlciBzYXZlZCBvbiBkaXNrLgorICBJTlRFUk5BTF9FUlJPUiA9IDU7Cit9CisKKy8vIEtleSB1c2VkIGJ5IHRoZSBTaGFyZWRGaWxlTWFuYWdlciB0byBpZGVudGlmeSBhIHNoYXJlZCBmaWxlLgorbWVzc2FnZSBOZXdGaWxlS2V5IHsKKyAgLy8gVGhlc2UgZmllbGRzIGFsbCBtaXJyb3IgdGhlIHNpbWlsYXJseS1uYW1lZCBmaWVsZHMgaW4gRGF0YUZpbGUuCisgIG9wdGlvbmFsIHN0cmluZyB1cmxfdG9fZG93bmxvYWQgPSAxIFtkZXByZWNhdGVkID0gdHJ1ZV07CisgIG9wdGlvbmFsIGludDMyIGJ5dGVfc2l6ZSA9IDIgW2RlcHJlY2F0ZWQgPSB0cnVlXTsKKyAgb3B0aW9uYWwgc3RyaW5nIGNoZWNrc3VtID0gMzsKKyAgb3B0aW9uYWwgRGF0YUZpbGVHcm91cEludGVybmFsLkFsbG93ZWRSZWFkZXJzIGFsbG93ZWRfcmVhZGVycyA9IDQ7CisgIG9wdGlvbmFsIG1vYnN0b3JlLnByb3RvLlRyYW5zZm9ybXMgZG93bmxvYWRfdHJhbnNmb3JtcyA9IDUKKyAgICAgIFtkZXByZWNhdGVkID0gdHJ1ZV07Cit9CisKKy8vIFRoaXMgcHJvdG8gaXMgdXNlZCB0byBzdG9yZSBzdGF0ZSBmb3IgbG9nZ2luZy4gU2VlIGRldGFpbHMgYXQKKy8vIDxpbnRlcm5hbD4KK21lc3NhZ2UgTG9nZ2luZ1N0YXRlIHsKKyAgLy8gVGhlIGxhc3QgdGltZSBtYWludGVuYW5jZSB3YXMgcnVuLiBUaGlzIHNob3VsZCBiZSB1cGRhdGVkIGV2ZXJ5IHRpbWUKKyAgLy8gbWFpbnRlbmFuY2UgaXMgcnVuLgorICAvLyBOb3RlOiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBvbmx5IHVzZXMgdGhpcyB0byBkZXRlcm1pbmUgdGhlIGRhdGUgb2YKKyAgLy8gdGhlIGxhc3QgbG9nIGV2ZW50LCBidXQgaW4gdGhlIGZ1dHVyZSB3ZSBtYXkgd2FudCBtb3JlIGdyYW51bGFyCisgIC8vIG1lYXN1cmVtZW50cyBmb3IgdGhpcywgc28gd2Ugc3RvcmUgdGhlIHRpbWVzdGFtcCBhcy1pcy4KKyAgb3B0aW9uYWwgZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBsYXN0X21haW50ZW5hbmNlX3J1bl90aW1lc3RhbXAgPSAxOworCisgIC8vIEZpbGUgZ3JvdXAgc3BlY2lmaWMgbG9nZ2luZyBzdGF0ZSBrZXllZCBieSBHcm91cEtleSwgYnVpbGQgaWQgYW5kIHZlcnNpb24KKyAgLy8gbnVtYmVyLgorICByZXBlYXRlZCBGaWxlR3JvdXBMb2dnaW5nU3RhdGUgZmlsZV9ncm91cF9sb2dnaW5nX3N0YXRlID0gMjsKKworICAvLyBTZXQgdG8gdHJ1ZSBvbmNlIHRoZSBzaGFyZWQgcHJlZmVyZW5jZXMgbWlncmF0aW9uIGlzIGNvbXBsZXRlLgorICAvLyBOb3RlOiB0aGlzIGZpZWxkIGlzbid0IHN0cmljdGx5IG5lY2Vzc2FyeSBhdCB0aGUgbW9tZW50IC0gd2UgY291bGQganVzdAorICAvLyBjaGVjayB0aGF0IHRoZSBmaWxlX2dyb3VwX2xvZ2dpbmdfc3RhdGUgaXMgZW1wdHkgc2luY2Ugbm8gb25lIHNob3VsZCB3cml0ZQorICAvLyB0byB0aGUgbmV0d29yayB1c2FnZSBtb25pdG9yIHNoYXJlZCBwcmVmcyBzaW5jZSB0aGUgbWlncmF0aW9uIHdpbGwgYmUKKyAgLy8gaW5zdGFsbGVkIGF0IHRoZSBzYW1lIGNsIHdoZXJlIHRoZSBjb2RlIGlzIHJlbW92ZWQuIEhvd2V2ZXIsIGlmIHdlIHdlcmUgdG8KKyAgLy8gYWRkIG1vcmUgZmllbGRzIHRvIEZpbGVHcm91cExvZ2dpbmdTdGF0ZSwgaXQgd291bGQgYmUgbGVzcyBzdHJhaWdodGZvcndhcmQKKyAgLy8gdG8gY2hlY2sgZm9yIG1pZ3JhdGlvbiBzdGF0ZSAtIHNvIGhhdmluZyB0aGlzIGJvb2xlYW4gbWFrZXMgaXQgYSBiaXQgc2FmZXIuCisgIG9wdGlvbmFsIGJvb2wgc2hhcmVkX3ByZWZlcmVuY2VzX25ldHdvcmtfdXNhZ2VfbW9uaXRvcl9taWdyYXRpb25fY29tcGxldGUgPSAzOworCisgIC8vIEluZm8gdG8gZW5hYmxlIHN0YWJsZSBzYW1wbGluZy4gU2VlIDxpbnRlcm5hbD4gZm9yIG1vcmUKKyAgLy8gaW5mby4gVGhpcyBmaWVsZCB3aWxsIGJlIHNldCBieSBhIG1pZ3JhdGlvbiBvbiBmaXJzdCBhY2Nlc3MuCisgIG9wdGlvbmFsIFNhbXBsaW5nSW5mbyBzYW1wbGluZ19pbmZvID0gNDsKK30KKworLy8gVGhpcyBwcm90byBpcyB1c2VkIHRvIHN0b3JlIHN0YXRlIGZvciBsb2dnaW5nIHRoYXQgaXMgc3BlY2lmaWMgdG8gYSBGaWxlCisvLyBHcm91cC4gVGhpcyBpbmNsdWRlcyBuZXR3b3JrIHVzYWdlIGxvZ2dpbmcgYW5kIG1heWJlIGRvd25sb2FkIHRpZXJzIChmb3IKKy8vIDxpbnRlcm5hbD4pLgorbWVzc2FnZSBGaWxlR3JvdXBMb2dnaW5nU3RhdGUgeworICBvcHRpb25hbCBHcm91cEtleSBncm91cF9rZXkgPSAxOworICBvcHRpb25hbCBpbnQ2NCBidWlsZF9pZCA9IDI7CisgIG9wdGlvbmFsIGludDMyIGZpbGVfZ3JvdXBfdmVyc2lvbl9udW1iZXIgPSAzOworICBvcHRpb25hbCBpbnQ2NCBjZWxsdWxhcl91c2FnZSA9IDQ7CisgIG9wdGlvbmFsIGludDY0IHdpZmlfdXNhZ2UgPSA1OworfQorCisvLyBOZXh0IGlkOiAzCittZXNzYWdlIFNhbXBsaW5nSW5mbyB7CisgIC8vIFJhbmRvbSBudW1iZXIgZ2VuZXJhdGVkIGFuZCBwZXJzaXN0ZWQgb24gZGV2aWNlLiBUaGlzIG51bWJlciBzaG91bGQgbm90CisgIC8vIGNoYW5nZSAodW5sZXNzIGRldmljZSBzdG9yYWdlL21kZCBpcyBjbGVhcmVkKS4gSXQgaXMgdXNlZCBhcyBhIHN0YWJsZQorICAvLyBpZGVudGlmaWVyIHRvIGRldGVybWluZSB3aGV0aGVyIE1ERCBzaG91bGQgbG9nIGV2ZW50cy4KKyAgb3B0aW9uYWwgaW50NjQgc3RhYmxlX2xvZ19zYW1wbGluZ19zYWx0ID0gMTsKKworICAvLyBXaGVuIHRoZSBzdGFibGVfbG9nX3NhbXBsaW5nX3NhbHQgd2FzIGZpcnN0IHNldC4gVGhpcyB3aWxsIGJlIHVzZWQgZHVyaW5nCisgIC8vIHJvbGwgb3V0IHRvIGRldGVybWluZSB3aGljaCBkZXZpY2VzIGhhdmUgZW5hYmxlZCBzdGFibGUgc2FtcGxpbmcgZm9yIGEKKyAgLy8gc3VmZmljaWVudCB0aW1lIHBlcmlvZC4KKyAgb3B0aW9uYWwgZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBsb2dfc2FtcGxpbmdfc2FsdF9zZXRfdGltZXN0YW1wID0gMjsKK30KZGlmZiAtLWdpdCBhL3Byb3RvL3RyYW5zZm9ybS5wcm90byBiL3Byb3RvL3RyYW5zZm9ybS5wcm90bwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hOGIyZTg1Ci0tLSAvZGV2L251bGwKKysrIGIvcHJvdG8vdHJhbnNmb3JtLnByb3RvCkBAIC0wLDAgKzEsODggQEAKKy8vIENvcHlyaWdodCAyMDIyIEdvb2dsZSBMTEMKKy8vCisvLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKKy8vIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKy8vIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAorLy8KKy8vICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCisvLworLy8gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQorLy8gZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKKy8vIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgorLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAorLy8gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCitzeW50YXggPSAicHJvdG8yIjsKKworcGFja2FnZSBtb2JzdG9yZS5wcm90bzsKKworb3B0aW9uIGphdmFfcGFja2FnZSA9ICJjb20uZ29vZ2xlLm1vYmlsZWRhdGFkb3dubG9hZCI7CitvcHRpb24gamF2YV9vdXRlcl9jbGFzc25hbWUgPSAiVHJhbnNmb3JtUHJvdG8iOworb3B0aW9uIG9iamNfY2xhc3NfcHJlZml4ID0gIk1PQiI7CisKKy8vIERlc2NyaXB0aW9uIG9mIHRyYW5zZm9ybXMgdGhhdCBhcmUgdG8gYmUgYXBwbGllZCBieSBNb2JTdG9yZSB0byBhIHN0cmVhbS4KKy8vCisvLyBGb2xsb3dpbmcgTW9iU3RvcmUgY29udmVudGlvbiwgdGhleSBhcmUgYXBwbGllZCBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleQorLy8gYXBwZWFyIG9uIHdyaXRlLCBhbmQgcmV2ZXJzZSBvbiByZWFkLiBTZXJpYWxpemF0aW9uIGFzIGEgVVJJIGZyYWdtZW50CisvLyBwcmVzZXJ2ZXMgb3JkZXIuCisvLworLy8gZWcgInRyYW5zZm9ybT1jb21wcmVzcytlbmNyeXB0KGFlc19nY21fa2V5PTEyMzQ1KSIKK21lc3NhZ2UgVHJhbnNmb3JtcyB7CisgIHJlcGVhdGVkIFRyYW5zZm9ybSB0cmFuc2Zvcm0gPSAxOworfQorCisvLyBTcGVjaWZpY2F0aW9uIGZvciBhbiBpbmRpdmlkdWFsIHRyYW5zZm9ybS4KK21lc3NhZ2UgVHJhbnNmb3JtIHsKKyAgb25lb2YgdHJhbnNmb3JtIHsKKyAgICBDb21wcmVzc1RyYW5zZm9ybSBjb21wcmVzcyA9IDE7CisgICAgRW5jcnlwdFRyYW5zZm9ybSBlbmNyeXB0ID0gMjsKKyAgICBJbnRlZ3JpdHlUcmFuc2Zvcm0gaW50ZWdyaXR5ID0gMzsKKyAgICBaaXBUcmFuc2Zvcm0gemlwID0gNDsKKyAgICBDdXN0b21UcmFuc2Zvcm0gY3VzdG9tID0gNTsKKyAgfQorfQorCisvLyBUaGUgY29tcHJlc3Npb24gdHJhbnNmb3JtLiBJdCBoYXMgbm8gcGFyYW1ldGVycy4KKy8vCisvLyBlZyAiY29tcHJlc3MiCittZXNzYWdlIENvbXByZXNzVHJhbnNmb3JtIHt9CisKKy8vIFRoZSBlbmNyeXB0aW9uIHRyYW5zZm9ybS4gSWYgbm8gcGFyYW1zIGFyZSBnaXZlbiwgaXQgdXNlcyB0aGUga2V5c3RvcmUKKy8vIHRvIG1hbmFnZSBrZXlzLiBBbHRlcm5hdGl2ZWx5LCB0aGUga2V5IGNhbiBiZSBzdG9yZWQgaW4gdGhlIFVSSSBpdHNlbGYuCisvLworLy8gZWcgImVuY3J5cHQiLCAiZW5jcnlwdChhZXNfZ2NtX2tleT0xMjM0NSkiCittZXNzYWdlIEVuY3J5cHRUcmFuc2Zvcm0geworICBvbmVvZiBrZXkgeworICAgIHN0cmluZyBhZXNfZ2NtX2tleV9iYXNlNjQgPSAxOworICB9Cit9CisKKy8vIFRoZSBpbnRlZ3JpdHkgdHJhbnNmb3JtLiBJZiB0aGUgaGFzaCBpcyBpbmNsdWRlZCwgaXQgY2FuIGJlIHZlcmlmaWVkLgorLy8gT3RoZXJ3aXNlLCBpdCBjYW4gYmUgcmV0cmlldmVkIGFmdGVyIHJlYWRpbmcgb3Igd3JpdGluZyB3aXRoIHRoZQorLy8gQ29tcHV0ZWRVcmkgQVBJLgorLy8KKy8vIGVnICJpbnRlZ3JpdHkiLCAiaW50ZWdyaXR5KHNoYTI1Nj0xMjM0NSkiCittZXNzYWdlIEludGVncml0eVRyYW5zZm9ybSB7CisgIG9uZW9mIGhhc2ggeworICAgIHN0cmluZyBzaGEyNTYgPSAxOworICB9Cit9CisKKy8vIFRoZSBaSVAgZGVjb21wcmVzcyB0cmFuc2Zvcm0uIEl0IHJlcXVpcmVzIGEgdGFyZ2V0IGZpbGUgcGFyYW0uCittZXNzYWdlIFppcFRyYW5zZm9ybSB7CisgIC8vIHJlcXVpcmVkCisgIG9wdGlvbmFsIHN0cmluZyB0YXJnZXQgPSAxOworfQorCisvLyBBIGN1c3RvbSB0cmFuc2Zvcm0uIFRoZSB0cmFuc2Zvcm0gd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgbXVzdCBiZSByZWdpc3RlcmVkCisvLyB3aXRoIE1vYlN0b3JlIEZpbGVTdG9yYWdlLgorbWVzc2FnZSBDdXN0b21UcmFuc2Zvcm0geworICAvLyByZXF1aXJlZAorICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CisKKyAgbWVzc2FnZSBTdWJQYXJhbSB7CisgICAgLy8gcmVxdWlyZWQKKyAgICBvcHRpb25hbCBzdHJpbmcga2V5ID0gMTsKKyAgICBvcHRpb25hbCBzdHJpbmcgdmFsdWUgPSAyOworICB9CisgIHJlcGVhdGVkIFN1YlBhcmFtIHN1YnBhcmFtID0gMjsKK30K